@wcag-checkr/ci 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/ErrorBoundary-B069Styg.js +594 -0
- package/dist/assets/ai-usage-log-CYuyLsU4.js +1 -0
- package/dist/assets/{copy-ai-fixer-prompt-DKUDhBLv.js → copy-ai-fixer-prompt-2854S1dW.js} +2 -2
- package/dist/assets/{devtools-panel-BAMmfrpT.js → devtools-panel-DO-Ue7xN.js} +1 -1
- package/dist/assets/{options-D_6nRFjj.js → options-DTbm8Du2.js} +1 -1
- package/dist/assets/{parallel-tab-flow-CecEndeb.js → parallel-tab-flow-C9KmXHUE.js} +1 -1
- package/dist/assets/{rubric-config-client-DJcOQbG2.js → rubric-config-client-CtLnVY3l.js} +1 -1
- package/dist/assets/{scheduled-audit-runner-Cad1yq0z.js → scheduled-audit-runner-AQwZVFus.js} +253 -234
- package/dist/assets/{service-worker.ts-B9F-ll_q.js → service-worker.ts-DQH3-r3D.js} +2 -2
- package/dist/assets/side-panel-CJB1fZKF.js +4 -0
- package/dist/assets/{site-report-renderer-klOJEyJa.js → site-report-renderer-JtIJmmtx.js} +5 -5
- package/dist/assets/{styles-B_kTykZT.js → styles-CLV9y-Ki.js} +1 -1
- package/dist/assets/{tier-config-client-85XOCE5d.js → tier-config-client-CT-oOti3.js} +1 -1
- package/dist/devtools/panel.html +5 -5
- package/dist/manifest.json +1 -1
- package/dist/options/options.html +4 -4
- package/dist/service-worker-loader.js +1 -1
- package/dist/side-panel/side-panel.html +8 -8
- package/package.json +1 -1
- package/dist/assets/ErrorBoundary-TPkmJFZP.js +0 -594
- package/dist/assets/ai-usage-log-CYyG5MT2.js +0 -1
- package/dist/assets/side-panel-Br-bhDHn.js +0 -4
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as U}from"./crash-reporter-KD5f4utB.js";const I="autoExportSettings",f="lastAutoExportAt",fe=["deposition-packet","defense-bundle","html-print","ai-prompt"],v={enabled:!1,formats:["defense-bundle"]};function q(i){return i==="deposition-packet"||i==="defense-bundle"||i==="html-print"||i==="ai-prompt"}async function ye(){var l;if(typeof chrome>"u"||!((l=chrome.storage)!=null&&l.local))return{...v,formats:[...v.formats]};const e=(await chrome.storage.local.get(I))[I];if(!e||typeof e!="object")return{...v,formats:[...v.formats]};const n=typeof e.enabled=="boolean"?e.enabled:!1;let a=[];return Array.isArray(e.formats)?a=e.formats.filter(q):q(e.format)&&(a=[e.format]),a.length===0&&(a=[...v.formats]),{enabled:n,formats:a}}async function be(i){var e;typeof chrome>"u"||!((e=chrome.storage)!=null&&e.local)||await chrome.storage.local.set({[I]:i})}async function Ae(i){var a;return typeof chrome>"u"||!((a=chrome.storage)!=null&&a.local)?null:((await chrome.storage.local.get(f))[f]??{})[i]??null}async function we(i){var a;if(typeof chrome>"u"||!((a=chrome.storage)!=null&&a.local))return;const n=(await chrome.storage.local.get(f))[f]??{};n[i.url]=i,await chrome.storage.local.set({[f]:n})}const S="autoDownloadReports";async function Ie(){return(await chrome.storage.local.get(S))[S]===!0}const Se=S;function xe(i,e,n="text/html"){const a=new Blob([i],{type:n}),l=URL.createObjectURL(a),r=document.createElement("a");r.href=l,r.download=e,document.body.appendChild(r),r.click(),document.body.removeChild(r),setTimeout(()=>URL.revokeObjectURL(l),5e3)}function ke(i){var e;typeof chrome<"u"&&((e=chrome.tabs)!=null&&e.create)?chrome.tabs.create({url:i,active:!0}).catch(n=>{console.warn("[download-helper] chrome.tabs.create failed; falling back to window.open",n),window.open(i,"_blank","noopener,noreferrer")}):window.open(i,"_blank","noopener,noreferrer")}function De(i,e="text/html"){var l;const n=new Blob([i],{type:e}),a=URL.createObjectURL(n);return typeof chrome<"u"&&((l=chrome.tabs)!=null&&l.create)?chrome.tabs.create({url:a,active:!0}).catch(r=>{console.warn("[download-helper] chrome.tabs.create failed; falling back to window.open",r),window.open(a,"_blank","noopener,noreferrer")}):window.open(a,"_blank","noopener,noreferrer"),setTimeout(()=>URL.revokeObjectURL(a),6e4),a}function qe(i,e){const n=new Date().toISOString().slice(0,10),a=(e??"audit").replace(/[^a-z0-9]/gi,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,24).toLowerCase()||"audit";return`wcagcheckr-${i}-${n}-${a}.${i==="ai-prompt"?"md":"html"}`}function Ce(i){return i<1024?`${i} B`:i<1024*1024?`${Math.round(i/1024)} KB`:`${(i/(1024*1024)).toFixed(1)} MB`}const x="tierConfig:cache",M=60*60*1e3,P=24*60*60*1e3,N=7*24*60*60*1e3;async function Re(){return(await chrome.storage.local.get(x))[x]??null}async function Te(i){await chrome.storage.local.set({[x]:i})}function Oe(i,e=Date.now()){const n=e-i.fetchedAt;return n<M?"fresh":n<P?"stale":n<N?"grace":"expired"}function Ee(i,e){const n={...i},a=d=>{if(typeof d=="number")return d===-1?1/0:d},l=d=>typeof d=="boolean"?d:void 0,r=d=>{if(d==="all"||d==="configurable"||d==="default-only")return d},t=(d,c)=>{const u=l(c);u!==void 0&&(n[d]=u)},s=(d,c)=>{const u=a(c);u!==void 0&&(n[d]=u)};s("maxComponents",e.maxComponents),s("maxBaselines",e.maxBaselines);const o=r(e.stateMatrix);return o!==void 0&&(n.stateMatrix=o),s("siteCrawlMaxPages",e.siteCrawlMaxPages),s("scheduledAuditsMaxCount",e.scheduledAuditsMaxCount),s("aiCostCapDefaultUsd",e.aiCostCapDefaultUsd),s("aiMaxCandidatesPerCheck",e.aiMaxCandidatesPerCheck),t("storybookAutoIterate",e.storybookAutoIterate),t("parallelScan",e.parallelScan),t("allFramesAudit",e.allFramesAudit),t("siteCrawl",e.siteCrawl),t("scheduledAudits",e.scheduledAudits),t("emailAlerts",e.emailAlerts),t("webhookAlerts",e.webhookAlerts),t("autoExportAuditReports",e.autoExportAuditReports),t("aiJudgment",e.aiJudgment),t("aiWalkthroughs",e.aiWalkthroughs),t("aiCopilot",e.aiCopilot),t("aiColorFix",e.aiColorFix),t("aiComplianceSummary",e.aiComplianceSummary),t("aiIncompleteResolver",e.aiIncompleteResolver),t("aiConsistencySuppression",e.aiConsistencySuppression),t("visualizers",e.visualizers),t("flowRecorder",e.flowRecorder),t("igtWorkflows",e.igtWorkflows),t("axTreeViewer",e.axTreeViewer),t("pdfAudit",e.pdfAudit),t("exportJson",e.exportJson),t("exportSarif",e.exportSarif),t("exportJunit",e.exportJunit),t("exportHtmlPrint",e.exportHtmlPrint),t("exportVpat",e.exportVpat),t("exportDefenseBundle",e.exportDefenseBundle),t("exportEvidenceBundle",e.exportEvidenceBundle),t("exportDeveloperLetter",e.exportDeveloperLetter),t("exportOwnerReport",e.exportOwnerReport),t("exportAiPrompts",e.exportAiPrompts),t("exportDepositionPacket",e.exportDepositionPacket),t("exportMethodologyDoc",e.exportMethodologyDoc),t("exportConformanceCrosswalk",e.exportConformanceCrosswalk),t("exportEaaStatement",e.exportEaaStatement),t("exportTicketBundle",e.exportTicketBundle),t("exportExecutiveReport",e.exportExecutiveReport),t("exportPreLitigationReport",e.exportPreLitigationReport),t("forensicLog",e.forensicLog),t("forensicAnchoring",e.forensicAnchoring),t("wcagEmReport",e.wcagEmReport),t("wcagEmAnchor",e.wcagEmAnchor),t("statusBadge",e.statusBadge),t("riskDashboard",e.riskDashboard),t("lawfareRisk",e.lawfareRisk),t("wcag3Preview",e.wcag3Preview),t("cloudSync",e.cloudSync),t("issueTrackers",e.issueTrackers),t("cliRunner",e.cliRunner),t("mcpServer",e.mcpServer),t("vscodeExtension",e.vscodeExtension),t("devtoolsPanel",e.devtoolsPanel),t("designSystemAudit",e.designSystemAudit),t("customRules",e.customRules),n}function Le(i,e){const n=e.plans.find(a=>a.code===i||a.code.startsWith(i+"-"));return(n==null?void 0:n.features)??null}const w=[{id:"mobile",label:"Mobile (375×667)",width:375,height:667,deviceScaleFactor:2,mobile:!0},{id:"tablet",label:"Tablet (768×1024)",width:768,height:1024,deviceScaleFactor:2,mobile:!0},{id:"desktop",label:"Desktop (1280×800)",width:1280,height:800,deviceScaleFactor:1,mobile:!1}],T={pseudoStates:["default","hover","focus","disabled"],ariaVariations:[],themes:["light","dark"],directions:["ltr"],breakpoints:["desktop"],breakpointPresets:w},O={pseudoStates:["default","hover","focus","focus-visible","active","disabled"],ariaVariations:[],themes:["light","dark","forced-colors-active"],directions:["ltr","rtl"],breakpoints:["mobile","desktop"],breakpointPresets:w},W={pseudoStates:["default"],ariaVariations:[],themes:["light"],directions:["ltr"],breakpoints:["desktop"],breakpointPresets:w},V=[{id:"default-subset",name:"Default subset",matrix:T},{id:"full-matrix",name:"Full matrix",matrix:O}],_e=Object.freeze(Object.defineProperty({__proto__:null,BUILT_IN_PRESETS:V,DEFAULT_BREAKPOINT_PRESETS:w,DEFAULT_STATE_MATRIX_SETTINGS:T,FULL_STATE_MATRIX_SETTINGS:O,QUICK_SCAN_MATRIX_SETTINGS:W},Symbol.toStringTag,{value:"Module"})),$={id:"keyboard",name:"Keyboard navigation",blurb:"Verify everyone who relies on the keyboard can reach, operate, and escape every interactive element. WCAG 2.1.1, 2.1.2, 2.4.3, 2.4.7.",steps:[{id:"tab-reaches-all",prompt:"Tab through the component from start to finish. Compare against the Tab-order overlay.",question:"Did Tab reach every interactive element (button, link, form field, custom widget)?",wcag:"2.1.1",visualizer:"tab-order",severity:"required"},{id:"tab-order-logical",prompt:"Watch the focus indicator as you Tab. Compare visual order vs the Tab-order numbered overlay.",question:"Does focus move in a logical order matching the visual layout (left-to-right, top-to-bottom)? Red badges indicate visual mismatches.",wcag:"2.4.3",visualizer:"tab-order",severity:"required",autoDismissActivity:"tab-order"},{id:"focus-visible",prompt:"On each focused element, confirm a visible focus indicator (outline, ring, color change).",question:"Is the focus indicator clearly visible on every interactive element?",wcag:"2.4.7",relatedAxeRule:"focus-order-semantics",severity:"required"},{id:"no-trap",prompt:"Tab forward and Shift+Tab backward through any modal, dropdown, or custom widget.",question:"Can you escape the widget with Tab/Shift+Tab/Esc — no trapping?",wcag:"2.1.2",severity:"required"},{id:"enter-activates",prompt:"Focus a button or link and press Enter (and Space for buttons).",question:"Did Enter/Space activate the control as expected?",wcag:"2.1.1",severity:"required"},{id:"esc-closes",prompt:"Open any modal, dropdown, or popover and press Escape.",question:"Did Escape close the overlay and return focus to the trigger?",wcag:"2.1.2",severity:"required"},{id:"arrow-keys-grouped",prompt:"For grouped widgets (radio, tabs, listbox, menu): focus into the group, then use arrow keys.",question:"Do arrow keys move within the group as expected (and Tab moves out of it)?",wcag:"2.1.1",severity:"advisory"},{id:"character-key-shortcuts",prompt:'Identify any single-character keyboard shortcuts (e.g., "S" to open search, "/" to focus the search box, J/K for next/prev). If none exist, mark N/A.',question:"For every single-character shortcut: can it be turned off, remapped to a modifier-key combo, OR is it only active when the relevant control has focus? (Prevents accidental activation by speech-input users.)",wcag:"2.1.4",severity:"required"}]},z={id:"screen-reader",name:"Screen reader readiness",blurb:"Verify the component is operable and meaningful via a screen reader. Use NVDA (Windows), VoiceOver (macOS/iOS), or TalkBack (Android). WCAG 1.3.1, 4.1.2.",steps:[{id:"sr-announces-on-focus",prompt:"Activate your screen reader and Tab to each interactive element.",question:"Does the SR announce a meaningful name + role + state for every focused element?",wcag:"4.1.2",relatedAxeRule:"aria-required-attr",severity:"required"},{id:"sr-headings-navigate",prompt:"Use the SR's heading-navigation shortcut (NVDA: H, VoiceOver: VO+Cmd+H). Compare against the Outline overlay.",question:"Are all logical sections reachable via heading navigation, in correct hierarchy order?",wcag:"1.3.1",relatedAxeRule:"heading-order",visualizer:"outline",severity:"required"},{id:"sr-reading-order",prompt:"Read the page top-to-bottom using the SR's read-all command (NVDA: NumPad+Down, VoiceOver: VO+A). Compare against the Reading-order numbered overlay.",question:"Does the SR read content in the meaningful order implied by the visual layout (1.3.2 Meaningful Sequence)? Red badges in the Reading-order overlay show DOM-vs-visual divergences.",wcag:"1.3.2",visualizer:"reading-order",severity:"required",autoDismissActivity:"reading-order"},{id:"sr-landmarks",prompt:"Use the SR's landmark-navigation shortcut (NVDA: D, VoiceOver: VO+U → Landmarks). Compare against the Outline overlay.",question:"Can the user jump to main, nav, banner, contentinfo via landmark navigation?",wcag:"1.3.1",relatedAxeRule:"region",visualizer:"outline",severity:"required"},{id:"sr-live-region",prompt:"Trigger any dynamic update (form submission, status change, toast).",question:'Does the SR announce the change automatically (via aria-live or role="status"/role="alert")?',wcag:"4.1.3",severity:"required"},{id:"sr-form-errors",prompt:"Submit a form with an invalid field.",question:"Does the SR announce the error and which field it relates to?",wcag:"3.3.1",severity:"required"},{id:"sr-images-meaningful",prompt:"Navigate over each image (NVDA: G, VoiceOver: VO+Cmd+G).",question:"Does each meaningful image have descriptive alt text? Are decorative images silent?",wcag:"1.1.1",relatedAxeRule:"image-alt",severity:"required"}]},K={id:"focus-management",name:"Focus management",blurb:"Verify focus moves and restores correctly across overlays, navigations, and dynamic content. WCAG 2.4.3, 2.4.7, 3.2.2.",steps:[{id:"modal-initial-focus",prompt:"Open a modal/dialog.",question:"Did focus move into the modal automatically (typically to the first focusable element or a heading)?",severity:"required"},{id:"modal-restored-on-close",prompt:"Close a modal/dialog (via close button or Esc).",question:"Was focus restored to the element that opened it?",severity:"required"},{id:"modal-trap-while-open",prompt:"While a modal is open, Tab/Shift+Tab through it.",question:"Is focus trapped inside the modal until it closes?",severity:"required"},{id:"route-change-focus",prompt:"Trigger a client-side route change.",question:"Did focus move sensibly (to the new page heading, or main landmark) — not to <body>?",severity:"required"},{id:"expanded-focus",prompt:"Open an expandable section (accordion, dropdown, collapsible).",question:"Is focus moved into or near the newly-revealed content (or kept on the trigger appropriately)?",severity:"advisory"},{id:"no-unexpected-focus-move",prompt:"Type or click in form fields without explicitly tabbing.",question:"Does focus stay where you put it (no auto-jump on input)?",wcag:"3.2.2",severity:"required"},{id:"no-context-change-on-focus",prompt:"Tab into each interactive element on the page.",question:"Does merely RECEIVING focus on an element NOT trigger a context change (auto-submit, open modal, navigate elsewhere, change focus to a different field)? (Context change on focus violates 3.2.1; activating a control via click/Enter is fine.)",wcag:"3.2.1",severity:"required"}]},G={id:"forms",name:"Forms",blurb:"Verify form fields are properly labeled, errors are clear, and the experience works for assistive technology. WCAG 1.3.1, 3.3.1, 3.3.2, 4.1.2.",steps:[{id:"visible-labels",prompt:"Look at every form field.",question:"Does every field have a visible label (not just placeholder text)?",wcag:"3.3.2",relatedAxeRule:"label",severity:"required"},{id:"label-association",prompt:"Click each visible label.",question:"Did clicking the label focus the associated input?",wcag:"1.3.1",relatedAxeRule:"label",severity:"required"},{id:"required-marked",prompt:"Identify required fields.",question:"Are required fields marked both visually AND programmatically (aria-required or required attribute)?",wcag:"3.3.2",severity:"required"},{id:"autocomplete-set",prompt:"For personal-info fields (name, email, phone, address): inspect the autocomplete attribute.",question:'Is autocomplete set with a valid HTML5 token (e.g., "email", "given-name", "tel")?',wcag:"1.3.5",relatedAxeRule:"autocomplete-valid",severity:"required"},{id:"error-text",prompt:"Submit with invalid input.",question:'Are error messages specific (not just "invalid"), shown near the field, and programmatically associated (aria-describedby)?',wcag:"3.3.1",severity:"required"},{id:"no-color-only-error",prompt:"Look at how errors are signaled.",question:"Is the error indicated by more than just color (also icon, text, or border style)?",wcag:"1.4.1",severity:"required"},{id:"success-announced",prompt:"Submit a form successfully.",question:'Is the success state announced to screen readers (via aria-live or role="status")?',wcag:"4.1.3",severity:"advisory"},{id:"error-suggestion",prompt:"Submit a form with an obvious invalid input (wrong email format, password too short, missing required field).",question:'Does the error message INCLUDE a specific suggestion for fixing it (not just "invalid")?',wcag:"3.3.3",severity:"required"},{id:"redundant-entry",prompt:"Identify any multi-step or multi-form flow where the user re-enters previously provided information (shipping = billing, profile data repeated in another form).",question:"Is previously-entered information auto-populated, selectable from a list, or otherwise NOT manually re-entered?",wcag:"3.3.7",severity:"required"},{id:"accessible-authentication",prompt:"Identify the site's authentication flow (login, password reset, multi-factor).",question:'Does auth NOT require a cognitive function test (e.g., remembering / transcribing characters), OR is an accessible alternative offered (passkey, magic link, password-manager autofill, "show password" toggle)?',wcag:"3.3.8",severity:"required"}]},B={id:"page-structure",name:"Page structure",blurb:"Verify the page declares its language, has a meaningful title, and exposes a sensible heading + landmark hierarchy. WCAG 2.4.2, 3.1.1, 3.1.2, 1.3.1, 2.4.6.",steps:[{id:"page-title",prompt:"Look at the browser tab — is the page title set and meaningful?",question:'Does the title describe the page topic / purpose (not just "Untitled" or the site name)?',wcag:"2.4.2",relatedAxeRule:"document-title",severity:"required"},{id:"page-lang",prompt:"Inspect the <html> element's lang attribute.",question:'Is lang set to a valid language code (e.g., "en", "es-MX")?',wcag:"3.1.1",relatedAxeRule:"html-has-lang",severity:"required"},{id:"lang-of-parts",prompt:"For any text not in the page's primary language (foreign quote, brand name in another language), inspect the parent element.",question:"Is lang attribute set on those elements to indicate the language change?",wcag:"3.1.2",severity:"advisory"},{id:"h1-present",prompt:"Use the Outline visualizer or SR heading shortcut to find the h1.",question:"Is there exactly one h1, and does it describe the main content of the page?",wcag:"1.3.1",relatedAxeRule:"page-has-heading-one",visualizer:"outline",severity:"required"},{id:"descriptive-headings",prompt:"Read each heading. Imagine someone listening only to the heading text.",question:"Does each heading describe its section meaningfully on its own?",wcag:"2.4.6",severity:"required"},{id:"main-landmark",prompt:"Use the Outline visualizer or SR landmark shortcut.",question:"Is there exactly one <main> landmark wrapping the page's primary content?",wcag:"1.3.1",relatedAxeRule:"landmark-one-main",visualizer:"outline",severity:"required"},{id:"parsing-well-formed",prompt:"Open DevTools → Console. Reload the page and check for HTML parse errors. Or run W3C validator on the URL.",question:"Is the page's markup well-formed (no duplicate IDs in scope, no invalid nesting, no missing required attributes)? WCAG 4.1.1 was obsoleted in 2.2 but still applies to 2.1 conformance claims.",wcag:"4.1.1",severity:"required"}]},H={id:"visual-indicators",name:"Visual indicators",blurb:"Verify nothing relies on color/shape/position alone, and non-text contrast meets thresholds for UI components and focus rings. WCAG 1.3.3, 1.4.1, 1.4.11.",steps:[{id:"no-color-only-info",prompt:"Scan instructions, error messages, charts, status indicators.",question:"Is information conveyed by something OTHER than color alone (text, icon, pattern, label)?",wcag:"1.4.1",severity:"required"},{id:"no-sensory-only",prompt:'Look for instructions referencing shape ("the round button"), location ("on the left"), sound ("the chime"), or visual cues alone.',question:"Are those instructions backed up by a programmatic identifier (label, role, accessible name)?",wcag:"1.3.3",severity:"required"},{id:"non-text-contrast",prompt:"For UI components (form-field borders, focus rings, icons-as-buttons), verify contrast vs adjacent colors. Use a contrast checker if needed.",question:"Do non-text UI components meet ≥3:1 contrast against adjacent colors?",wcag:"1.4.11",severity:"required"},{id:"focus-ring-contrast",prompt:"Tab through; for each focused element, verify the focus ring is visible against both the element and the page background.",question:"Does the focus ring meet ≥3:1 contrast on every focusable surface?",wcag:"1.4.11",visualizer:"tab-order",severity:"required"},{id:"state-changes-visible",prompt:"For toggleable controls (checkboxes, switches, expanded states): change them and observe.",question:"Is the state change conveyed visibly AND programmatically (aria-pressed/expanded/checked)?",wcag:"4.1.2",severity:"required"}]},j={id:"reflow",name:"Reflow & text spacing",blurb:"Verify the layout survives narrow viewports, browser zoom, and user-overridden text spacing. WCAG 1.4.4, 1.4.10, 1.4.12.",steps:[{id:"resize-320",prompt:"Resize the browser to 320px wide (or set DevTools device toolbar to 320×256).",question:"Does content reflow without two-dimensional scrolling? (Vertical scroll OK; horizontal scroll within content blocks NOT OK.)",wcag:"1.4.10",relatedAxeRule:"wcagcheckr-reflow",severity:"required"},{id:"zoom-200",prompt:"In a desktop viewport, zoom the browser to 200%.",question:"Is all content + functionality available, with no text clipping or unusable controls?",wcag:"1.4.4",severity:"required"},{id:"text-spacing-override",prompt:"Apply text-spacing override (line-height: 1.5, paragraph spacing 2x font-size, letter-spacing 0.12em, word-spacing 0.16em) via a bookmarklet or DevTools.",question:"Does content stay readable with no overlap or clipping?",wcag:"1.4.12",severity:"required"},{id:"no-fixed-pixel-text",prompt:"Inspect text styles for fixed px-based font sizes, line-heights.",question:"Are text dimensions set in relative units (rem/em/%) so they scale with user settings?",severity:"advisory"},{id:"orientation-not-locked",prompt:"Rotate a mobile device (or use DevTools device toolbar to rotate) between portrait and landscape.",question:"Does the layout adapt to both orientations? (Content not locked to one orientation unless essential.)",wcag:"1.3.4",severity:"required"},{id:"images-of-text",prompt:"Look for marketing banners, hero images, or any image that contains substantial text content as part of the raster.",question:"Is real HTML text used in preference to images-of-text, except for logos / decorative purposes? (Images-of-text fail to scale with zoom, can't be selected, and don't respect user text settings.)",wcag:"1.4.5",severity:"required"}]},Y={id:"hover-focus-content",name:"Content on hover or focus",blurb:"Tooltips, dropdown previews, and any content revealed on hover or focus must be dismissable, hoverable, and persistent. WCAG 1.4.13.",steps:[{id:"dismissable",prompt:"Hover or focus to reveal a tooltip / popover. Press Escape.",question:"Did Escape dismiss the revealed content without moving pointer or focus?",wcag:"1.4.13",severity:"required"},{id:"hoverable",prompt:"Hover to reveal a tooltip. Move the pointer over the tooltip itself (without losing the trigger's hover).",question:"Does the revealed content stay visible when the pointer enters it?",wcag:"1.4.13",severity:"required"},{id:"persistent",prompt:"Reveal a tooltip and don't do anything else.",question:"Does the content remain visible until the user dismisses it, moves focus/pointer away, or the trigger info is no longer valid?",wcag:"1.4.13",severity:"required"}]},J={id:"pointer",name:"Pointer interactions",blurb:"Verify gestures, target sizes, and pointer cancellation respect users with motor limitations. WCAG 2.5.1, 2.5.2, 2.5.5/2.5.8.",steps:[{id:"no-multi-point-gesture",prompt:"Identify any feature that requires a multi-point gesture (pinch, two-finger swipe) or path-based gesture (drag along a line).",question:"Is there a single-tap / single-click alternative for that feature?",wcag:"2.5.1",severity:"required"},{id:"pointer-cancellation",prompt:"Mouse-down on a button, drag the pointer OFF the button, then release.",question:"Was the action canceled (the button did NOT activate)? Activation should fire on up-event over the target, not down-event.",wcag:"2.5.2",severity:"required"},{id:"target-size-aa",prompt:"Toggle the Targets visualizer. Look for any red overlays (≥24×24 fail).",question:"Are all interactive targets ≥24×24 CSS px (or have sufficient spacing per WCAG 2.5.8)?",wcag:"2.5.8",relatedAxeRule:"target-size",visualizer:"targets",severity:"required"},{id:"label-in-name",prompt:"For every visually-labeled control (button, link), inspect its accessible name (use the SR or DevTools).",question:"Does the accessible name START with — or fully contain — the visible label text?",wcag:"2.5.3",relatedAxeRule:"label-content-name-mismatch",severity:"required"},{id:"motion-actuation-alt",prompt:"Identify any feature that triggers on device motion (shake to undo, tilt to scroll, step counter).",question:"Is there a non-motion alternative (button / control) for every motion-triggered function, AND can motion be disabled?",wcag:"2.5.4",severity:"required"},{id:"dragging-alternative",prompt:"Identify any feature that requires a dragging movement (slider thumb, drag-to-rearrange, swipe-to-delete).",question:"Is there a single-tap / single-click alternative for every dragging action (e.g., +/- buttons next to a slider, up/down buttons next to draggable list items)?",wcag:"2.5.7",severity:"required"}]},X={id:"time-based",name:"Time-based behaviors",blurb:"Verify time limits, auto-updating content, and motion can be controlled by users. WCAG 2.2.1, 2.2.2, 2.3.1.",steps:[{id:"time-limits-adjustable",prompt:"Identify any time-limited interaction (session timeout, form auto-submit, OTP expiration).",question:"Can the user turn off, adjust, or extend the time limit before it expires (warning + control before the deadline)?",wcag:"2.2.1",severity:"required"},{id:"pause-moving-content",prompt:"Look for content that moves, blinks, scrolls, or auto-updates for >5 seconds (carousels, animated banners, news tickers, auto-refreshing feeds).",question:"Is there a control to pause / stop / hide the moving content?",wcag:"2.2.2",severity:"required"},{id:"no-flash",prompt:"Identify any flashing or blinking content (>3 flashes per second).",question:"Is flashing absent, OR limited below the general/red flash thresholds?",wcag:"2.3.1",severity:"required"},{id:"reduced-motion-honored",prompt:'Enable system "reduce motion" preference. Reload the page.',question:"Does the site honor prefers-reduced-motion (parallax / animations / spinners minimized or disabled)?",wcag:"2.3.3",severity:"advisory"}]},Q={id:"error-prevention",name:"Error prevention",blurb:"Verify destructive, financial, or legal actions are reversible, checked, or confirmed. WCAG 3.3.4, 3.3.6.",steps:[{id:"destructive-confirm",prompt:"Identify destructive actions (delete account, cancel subscription, destroy data, send irreversible message).",question:'Is each destructive action reversible (undo), or checked (validation), or confirmed (explicit "Are you sure?" dialog)?',wcag:"3.3.4",severity:"required"},{id:"financial-confirm",prompt:"Identify financial / legal commitments (purchase, contract sign, transfer).",question:"Before submission, does the user see a review screen and an explicit confirmation step?",wcag:"3.3.4",severity:"required"},{id:"undo-available",prompt:'Test "destructive" actions on user content (delete a note, archive an item).',question:'Is there an undo / restore mechanism, even briefly (toast with "undo" button)?',wcag:"3.3.6",severity:"advisory"}]},Z={id:"consistency",name:"Consistency",blurb:"Verify navigation, identification, and user paths are consistent across pages. WCAG 2.4.5, 3.2.3, 3.2.4.",steps:[{id:"consistent-nav",prompt:"Compare the primary navigation across 3+ pages.",question:"Does the same navigation appear in the same order on every page?",wcag:"3.2.3",severity:"required"},{id:"consistent-id",prompt:'Compare the same UI element appearing on multiple pages (e.g., a search icon, a "Help" link).',question:"Does the same component have the same accessible name everywhere it appears?",wcag:"3.2.4",severity:"required"},{id:"multiple-ways",prompt:"Beyond the primary navigation, is there a second way to find a page (search, sitemap, related links, breadcrumbs)?",question:"Are there at least 2 ways to locate any page (single-process pages exempt)?",wcag:"2.4.5",severity:"required"},{id:"skip-link",prompt:"Tab once when the page loads.",question:'Does the first focusable element offer a "Skip to main content" link (or equivalent bypass)?',wcag:"2.4.1",relatedAxeRule:"bypass",severity:"required"},{id:"consistent-help",prompt:"Identify pages that surface a help mechanism (contact info, help link, FAQ link, chatbot trigger). Compare position + order across pages.",question:"When the same help mechanism appears on multiple pages, does it appear in the same relative order (e.g., always last in the header)?",wcag:"3.2.6",severity:"required"}]},ee={id:"time-based-media",name:"Time-based media",blurb:'Verify audio + video have the alternatives required by WCAG. If the site has no time-based media, mark every step "Not applicable." WCAG 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.4.2.',steps:[{id:"prerecorded-audio-only-alt",prompt:"Identify any prerecorded audio-only content (podcast embed, audio quote, voice message).",question:"Does each prerecorded audio-only file have a text transcript readable on the page (or linked from it)?",wcag:"1.2.1",severity:"required"},{id:"prerecorded-video-only-alt",prompt:"Identify any prerecorded silent video (animated GIF with content, silent screencast, animated explainer).",question:"Does each prerecorded video-only file have an equivalent text or audio description?",wcag:"1.2.1",severity:"required"},{id:"prerecorded-captions",prompt:"Identify any prerecorded video that includes audio (interviews, tutorials, marketing videos).",question:"Does each video provide synchronized captions for ALL spoken content + meaningful non-speech sound?",wcag:"1.2.2",severity:"required"},{id:"prerecorded-alt-for-video",prompt:"For each prerecorded video with audio, check if there's a full text transcript on the page (covering both audio dialog AND visual action) OR if audio description is provided.",question:"Does each prerecorded video have either a full text alternative OR an audio-description track?",wcag:"1.2.3",severity:"required"},{id:"prerecorded-audio-description",prompt:"Watch each prerecorded video without looking at it. Listen only.",question:"Is all visually-conveyed information also conveyed in the audio (either built into the narration OR via a separate audio-description track)?",wcag:"1.2.5",severity:"required"},{id:"live-captions",prompt:"Identify any LIVE audio/video stream (live shopping, webinar, conference broadcast).",question:"Does each live broadcast provide real-time captions?",wcag:"1.2.4",severity:"required"},{id:"audio-control",prompt:"Reload the page. Listen for audio that starts automatically and plays for >3 seconds (background music, autoplay video with sound).",question:"Is there a mechanism to pause / stop the audio, OR can the volume be controlled INDEPENDENTLY from the system volume?",wcag:"1.4.2",severity:"required"}]},te=[$,z,K,G,B,H,j,Y,J,X,ee,Q,Z];function Fe(i,e){let n=0,a=0,l=0,r=0,t=0;for(const s of e.steps){const o=i.steps[s.id];if(!o){t++;continue}o.status==="pass"?n++:o.status==="fail"?a++:o.status==="not-applicable"?r++:o.status==="skip"?l++:t++}return{passed:n,failed:a,skipped:l,notApplicable:r,unanswered:t,total:e.steps.length,fullyAnswered:t===0}}const ie=[{id:"1.1.1",title:"Non-text Content",level:"A",addedIn:"2.0",understandingSlug:"non-text-content",shortDescription:"All non-text content has a text alternative."},{id:"1.2.1",title:"Audio-only and Video-only (Prerecorded)",level:"A",addedIn:"2.0",understandingSlug:"audio-only-and-video-only-prerecorded",shortDescription:"Alternatives for prerecorded audio-only or video-only."},{id:"1.2.2",title:"Captions (Prerecorded)",level:"A",addedIn:"2.0",understandingSlug:"captions-prerecorded",shortDescription:"Captions for prerecorded audio in synchronized media."},{id:"1.2.3",title:"Audio Description or Media Alternative (Prerecorded)",level:"A",addedIn:"2.0",understandingSlug:"audio-description-or-media-alternative-prerecorded",shortDescription:"Alternative for time-based media (prerecorded)."},{id:"1.2.4",title:"Captions (Live)",level:"AA",addedIn:"2.0",understandingSlug:"captions-live",shortDescription:"Captions for live synchronized media."},{id:"1.2.5",title:"Audio Description (Prerecorded)",level:"AA",addedIn:"2.0",understandingSlug:"audio-description-prerecorded",shortDescription:"Audio description for prerecorded video in synchronized media."},{id:"1.2.6",title:"Sign Language (Prerecorded)",level:"AAA",addedIn:"2.0",understandingSlug:"sign-language-prerecorded",shortDescription:"Sign-language interpretation for prerecorded audio."},{id:"1.2.7",title:"Extended Audio Description (Prerecorded)",level:"AAA",addedIn:"2.0",understandingSlug:"extended-audio-description-prerecorded",shortDescription:"Extended audio description for prerecorded video."},{id:"1.2.8",title:"Media Alternative (Prerecorded)",level:"AAA",addedIn:"2.0",understandingSlug:"media-alternative-prerecorded",shortDescription:"Alternative for time-based media (prerecorded)."},{id:"1.2.9",title:"Audio-only (Live)",level:"AAA",addedIn:"2.0",understandingSlug:"audio-only-live",shortDescription:"Alternative for live audio-only content."},{id:"1.3.1",title:"Info and Relationships",level:"A",addedIn:"2.0",understandingSlug:"info-and-relationships",shortDescription:"Information and structural relationships are programmatically determinable."},{id:"1.3.2",title:"Meaningful Sequence",level:"A",addedIn:"2.0",understandingSlug:"meaningful-sequence",shortDescription:"Reading sequence is programmatically determinable."},{id:"1.3.3",title:"Sensory Characteristics",level:"A",addedIn:"2.0",understandingSlug:"sensory-characteristics",shortDescription:"Instructions don't rely solely on shape, color, size, or sound."},{id:"1.3.4",title:"Orientation",level:"AA",addedIn:"2.1",understandingSlug:"orientation",shortDescription:"Content doesn't restrict view to portrait or landscape."},{id:"1.3.5",title:"Identify Input Purpose",level:"AA",addedIn:"2.1",understandingSlug:"identify-input-purpose",shortDescription:"Purpose of input fields is programmatically identifiable."},{id:"1.3.6",title:"Identify Purpose",level:"AAA",addedIn:"2.1",understandingSlug:"identify-purpose",shortDescription:"Purpose of UI components, icons, and regions is identifiable."},{id:"1.4.1",title:"Use of Color",level:"A",addedIn:"2.0",understandingSlug:"use-of-color",shortDescription:"Color is not the only means of conveying information."},{id:"1.4.2",title:"Audio Control",level:"A",addedIn:"2.0",understandingSlug:"audio-control",shortDescription:"Mechanism to pause/stop auto-playing audio over 3s."},{id:"1.4.3",title:"Contrast (Minimum)",level:"AA",addedIn:"2.0",understandingSlug:"contrast-minimum",shortDescription:"Text has 4.5:1 contrast (3:1 for large text)."},{id:"1.4.4",title:"Resize Text",level:"AA",addedIn:"2.0",understandingSlug:"resize-text",shortDescription:"Text resizable to 200% without loss of content/function."},{id:"1.4.5",title:"Images of Text",level:"AA",addedIn:"2.0",understandingSlug:"images-of-text",shortDescription:"Text used in preference to images of text where possible."},{id:"1.4.6",title:"Contrast (Enhanced)",level:"AAA",addedIn:"2.0",understandingSlug:"contrast-enhanced",shortDescription:"Text has 7:1 contrast (4.5:1 for large text)."},{id:"1.4.7",title:"Low or No Background Audio",level:"AAA",addedIn:"2.0",understandingSlug:"low-or-no-background-audio",shortDescription:"Background audio at least 20dB lower than speech."},{id:"1.4.8",title:"Visual Presentation",level:"AAA",addedIn:"2.0",understandingSlug:"visual-presentation",shortDescription:"Configurable visual presentation for blocks of text."},{id:"1.4.9",title:"Images of Text (No Exception)",level:"AAA",addedIn:"2.0",understandingSlug:"images-of-text-no-exception",shortDescription:"Images of text used only for decoration / essential."},{id:"1.4.10",title:"Reflow",level:"AA",addedIn:"2.1",understandingSlug:"reflow",shortDescription:"Content reflows at 320 CSS px without 2D scrolling."},{id:"1.4.11",title:"Non-text Contrast",level:"AA",addedIn:"2.1",understandingSlug:"non-text-contrast",shortDescription:"UI components and graphical objects have 3:1 contrast."},{id:"1.4.12",title:"Text Spacing",level:"AA",addedIn:"2.1",understandingSlug:"text-spacing",shortDescription:"Text spacing overrides don't cause content loss."},{id:"1.4.13",title:"Content on Hover or Focus",level:"AA",addedIn:"2.1",understandingSlug:"content-on-hover-or-focus",shortDescription:"Hover/focus tooltips are dismissible, hoverable, persistent."},{id:"2.1.1",title:"Keyboard",level:"A",addedIn:"2.0",understandingSlug:"keyboard",shortDescription:"All functionality available from the keyboard."},{id:"2.1.2",title:"No Keyboard Trap",level:"A",addedIn:"2.0",understandingSlug:"no-keyboard-trap",shortDescription:"Keyboard focus can move away from any component."},{id:"2.1.3",title:"Keyboard (No Exception)",level:"AAA",addedIn:"2.0",understandingSlug:"keyboard-no-exception",shortDescription:"All functionality is keyboard-operable without timing."},{id:"2.1.4",title:"Character Key Shortcuts",level:"A",addedIn:"2.1",understandingSlug:"character-key-shortcuts",shortDescription:"Single-key shortcuts can be turned off or remapped."},{id:"2.2.1",title:"Timing Adjustable",level:"A",addedIn:"2.0",understandingSlug:"timing-adjustable",shortDescription:"User can turn off, adjust, or extend time limits."},{id:"2.2.2",title:"Pause, Stop, Hide",level:"A",addedIn:"2.0",understandingSlug:"pause-stop-hide",shortDescription:"Moving/blinking/scrolling content can be paused."},{id:"2.2.3",title:"No Timing",level:"AAA",addedIn:"2.0",understandingSlug:"no-timing",shortDescription:"No timing essential to content/function (with exceptions)."},{id:"2.2.4",title:"Interruptions",level:"AAA",addedIn:"2.0",understandingSlug:"interruptions",shortDescription:"User can postpone/suppress non-emergency interruptions."},{id:"2.2.5",title:"Re-authenticating",level:"AAA",addedIn:"2.0",understandingSlug:"re-authenticating",shortDescription:"Authenticated session can be resumed without data loss."},{id:"2.2.6",title:"Timeouts",level:"AAA",addedIn:"2.1",understandingSlug:"timeouts",shortDescription:"Inactivity timeouts warned in advance."},{id:"2.3.1",title:"Three Flashes or Below Threshold",level:"A",addedIn:"2.0",understandingSlug:"three-flashes-or-below-threshold",shortDescription:"No content flashes more than 3 times per second."},{id:"2.3.2",title:"Three Flashes",level:"AAA",addedIn:"2.0",understandingSlug:"three-flashes",shortDescription:"No content flashes more than 3 times per second (no exceptions)."},{id:"2.3.3",title:"Animation from Interactions",level:"AAA",addedIn:"2.1",understandingSlug:"animation-from-interactions",shortDescription:"Motion animation from interactions can be disabled."},{id:"2.4.1",title:"Bypass Blocks",level:"A",addedIn:"2.0",understandingSlug:"bypass-blocks",shortDescription:"Mechanism to skip blocks of repeated content."},{id:"2.4.2",title:"Page Titled",level:"A",addedIn:"2.0",understandingSlug:"page-titled",shortDescription:"Pages have titles that describe topic/purpose."},{id:"2.4.3",title:"Focus Order",level:"A",addedIn:"2.0",understandingSlug:"focus-order",shortDescription:"Components receive focus in a meaningful order."},{id:"2.4.4",title:"Link Purpose (In Context)",level:"A",addedIn:"2.0",understandingSlug:"link-purpose-in-context",shortDescription:"Link purpose is clear from the link text + context."},{id:"2.4.5",title:"Multiple Ways",level:"AA",addedIn:"2.0",understandingSlug:"multiple-ways",shortDescription:"Two or more ways to locate a page within a set."},{id:"2.4.6",title:"Headings and Labels",level:"AA",addedIn:"2.0",understandingSlug:"headings-and-labels",shortDescription:"Headings and labels describe topic or purpose."},{id:"2.4.7",title:"Focus Visible",level:"AA",addedIn:"2.0",understandingSlug:"focus-visible",shortDescription:"Keyboard focus indicator is visible."},{id:"2.4.8",title:"Location",level:"AAA",addedIn:"2.0",understandingSlug:"location",shortDescription:"Information about user's location within a set is available."},{id:"2.4.9",title:"Link Purpose (Link Only)",level:"AAA",addedIn:"2.0",understandingSlug:"link-purpose-link-only",shortDescription:"Link purpose clear from the link text alone."},{id:"2.4.10",title:"Section Headings",level:"AAA",addedIn:"2.0",understandingSlug:"section-headings",shortDescription:"Section headings are used to organize content."},{id:"2.4.11",title:"Focus Not Obscured (Minimum)",level:"AA",addedIn:"2.2",understandingSlug:"focus-not-obscured-minimum",shortDescription:"Focused component not entirely hidden by other content."},{id:"2.4.12",title:"Focus Not Obscured (Enhanced)",level:"AAA",addedIn:"2.2",understandingSlug:"focus-not-obscured-enhanced",shortDescription:"Focused component fully visible."},{id:"2.4.13",title:"Focus Appearance",level:"AAA",addedIn:"2.2",understandingSlug:"focus-appearance",shortDescription:"Focus indicator meets specific size/contrast requirements."},{id:"2.5.1",title:"Pointer Gestures",level:"A",addedIn:"2.1",understandingSlug:"pointer-gestures",shortDescription:"Multi-point or path-based gestures have single-pointer alternatives."},{id:"2.5.2",title:"Pointer Cancellation",level:"A",addedIn:"2.1",understandingSlug:"pointer-cancellation",shortDescription:"Pointer actions can be aborted or undone."},{id:"2.5.3",title:"Label in Name",level:"A",addedIn:"2.1",understandingSlug:"label-in-name",shortDescription:"Accessible name includes the visible label text."},{id:"2.5.4",title:"Motion Actuation",level:"A",addedIn:"2.1",understandingSlug:"motion-actuation",shortDescription:"Motion-triggered functions have UI alternatives + can be disabled."},{id:"2.5.5",title:"Target Size (Enhanced)",level:"AAA",addedIn:"2.1",understandingSlug:"target-size-enhanced",shortDescription:"Pointer target size at least 44×44 CSS px."},{id:"2.5.6",title:"Concurrent Input Mechanisms",level:"AAA",addedIn:"2.1",understandingSlug:"concurrent-input-mechanisms",shortDescription:"Content doesn't restrict input modality."},{id:"2.5.7",title:"Dragging Movements",level:"AA",addedIn:"2.2",understandingSlug:"dragging-movements",shortDescription:"Dragging actions have single-pointer alternatives."},{id:"2.5.8",title:"Target Size (Minimum)",level:"AA",addedIn:"2.2",understandingSlug:"target-size-minimum",shortDescription:"Pointer target size at least 24×24 CSS px."},{id:"3.1.1",title:"Language of Page",level:"A",addedIn:"2.0",understandingSlug:"language-of-page",shortDescription:"Default human language of the page is programmatically set."},{id:"3.1.2",title:"Language of Parts",level:"AA",addedIn:"2.0",understandingSlug:"language-of-parts",shortDescription:"Language of each passage is programmatically set."},{id:"3.1.3",title:"Unusual Words",level:"AAA",addedIn:"2.0",understandingSlug:"unusual-words",shortDescription:"Definitions provided for jargon, idioms, etc."},{id:"3.1.4",title:"Abbreviations",level:"AAA",addedIn:"2.0",understandingSlug:"abbreviations",shortDescription:"Expanded form or meaning of abbreviations is available."},{id:"3.1.5",title:"Reading Level",level:"AAA",addedIn:"2.0",understandingSlug:"reading-level",shortDescription:"Supplemental content provided for advanced reading levels."},{id:"3.1.6",title:"Pronunciation",level:"AAA",addedIn:"2.0",understandingSlug:"pronunciation",shortDescription:"Mechanism for pronunciation of words where meaning is ambiguous."},{id:"3.2.1",title:"On Focus",level:"A",addedIn:"2.0",understandingSlug:"on-focus",shortDescription:"Focus does not trigger an unexpected context change."},{id:"3.2.2",title:"On Input",level:"A",addedIn:"2.0",understandingSlug:"on-input",shortDescription:"Input does not trigger an unexpected context change."},{id:"3.2.3",title:"Consistent Navigation",level:"AA",addedIn:"2.0",understandingSlug:"consistent-navigation",shortDescription:"Navigation is consistent across a set of pages."},{id:"3.2.4",title:"Consistent Identification",level:"AA",addedIn:"2.0",understandingSlug:"consistent-identification",shortDescription:"Components with the same function are identified consistently."},{id:"3.2.5",title:"Change on Request",level:"AAA",addedIn:"2.0",understandingSlug:"change-on-request",shortDescription:"Changes of context only on user request."},{id:"3.2.6",title:"Consistent Help",level:"A",addedIn:"2.2",understandingSlug:"consistent-help",shortDescription:"Help mechanisms appear in consistent order across pages."},{id:"3.3.1",title:"Error Identification",level:"A",addedIn:"2.0",understandingSlug:"error-identification",shortDescription:"Form errors are identified and described in text."},{id:"3.3.2",title:"Labels or Instructions",level:"A",addedIn:"2.0",understandingSlug:"labels-or-instructions",shortDescription:"Form fields have labels or instructions."},{id:"3.3.3",title:"Error Suggestion",level:"AA",addedIn:"2.0",understandingSlug:"error-suggestion",shortDescription:"Error suggestions provided when known."},{id:"3.3.4",title:"Error Prevention (Legal, Financial, Data)",level:"AA",addedIn:"2.0",understandingSlug:"error-prevention-legal-financial-data",shortDescription:"Submissions are reversible, checked, or confirmed."},{id:"3.3.5",title:"Help",level:"AAA",addedIn:"2.0",understandingSlug:"help",shortDescription:"Context-sensitive help is available."},{id:"3.3.6",title:"Error Prevention (All)",level:"AAA",addedIn:"2.0",understandingSlug:"error-prevention-all",shortDescription:"All submissions reversible, checked, or confirmed."},{id:"3.3.7",title:"Redundant Entry",level:"A",addedIn:"2.2",understandingSlug:"redundant-entry",shortDescription:"Previously-entered information is auto-populated or selectable."},{id:"3.3.8",title:"Accessible Authentication (Minimum)",level:"AA",addedIn:"2.2",understandingSlug:"accessible-authentication-minimum",shortDescription:"Auth doesn't require cognitive function test."},{id:"3.3.9",title:"Accessible Authentication (Enhanced)",level:"AAA",addedIn:"2.2",understandingSlug:"accessible-authentication-enhanced",shortDescription:"Auth doesn't require cognitive function test (no exceptions)."},{id:"4.1.1",title:"Parsing",level:"A",addedIn:"2.0",removedIn:"2.2",understandingSlug:"parsing",shortDescription:"Markup is well-formed (obsoleted in WCAG 2.2)."},{id:"4.1.2",title:"Name, Role, Value",level:"A",addedIn:"2.0",understandingSlug:"name-role-value",shortDescription:"UI components have programmatically determinable name + role + state."},{id:"4.1.3",title:"Status Messages",level:"AA",addedIn:"2.1",understandingSlug:"status-messages",shortDescription:"Status messages programmatically announced without focus change."}];function oe(i,e){const n={A:1,AA:2,AAA:3},a={"2.0":1,"2.1":2,"2.2":3};return ie.filter(l=>a[l.addedIn]>a[i]||l.removedIn&&a[l.removedIn]<=a[i]?!1:n[l.level]<=n[e])}function Ue(i,e){return`https://www.w3.org/WAI/WCAG${e.replace(".","")}/Understanding/${i.understandingSlug}`}let b="2.1";const ne="AA";function Me(i){b=i}async function Pe(){var i,e;try{const a=(await chrome.storage.local.get("wcagTargetVersion")).wcagTargetVersion;(a==="2.1"||a==="2.2")&&(b=a),(e=(i=chrome.storage.onChanged)==null?void 0:i.addListener)==null||e.call(i,(l,r)=>{if(r!=="local")return;const t=l.wcagTargetVersion;if(!t)return;const s=t.newValue;(s==="2.1"||s==="2.2")&&(b=s)})}catch{}}const re=["3.2.3","3.2.4","3.2.6","3.3.7"];function Ne(i){const e=oe(b,ne),n=new Map;for(const r of e)n.set(r.id,{criterionId:r.id,level:r.level,title:r.title,state:"not-evaluated",evidence:[]});const a=new Map;function l(r,t){let s=a.get(r);return s||(s=new Set,a.set(r,s)),s.has(t)?!0:(s.add(t),!1)}for(const r of i.audits){const t=r.pageUrl??r.scope;for(const o of r.violations){if(!o.wcagCriterion)continue;const d=n.get(o.wcagCriterion);if(!d)continue;const c=o.ruleId.startsWith("ai-"),u=o.target.selector;if(i.acknowledgedMatchKeys.has(o.matchKey)){const h=`ack::${o.ruleId}::${t}::${u}`;if(l(o.wcagCriterion,h))continue;d.evidence.push({source:c?"ai":"axe",ruleOrStepId:o.ruleId,outcome:"ack",pageUrl:t,selector:u});continue}if(o.needsReview){const h=`needsReview::${o.ruleId}::${t}::${u}`;if(l(o.wcagCriterion,h))continue;d.evidence.push({source:"ai",ruleOrStepId:o.ruleId,outcome:"incomplete",pageUrl:t,selector:u,resolutionHint:"Acknowledge in the Matrix view if not an issue, or fix the underlying alt text."});continue}const p=`fail::${o.ruleId}::${t}::${u}`;l(o.wcagCriterion,p)||d.evidence.push({source:c?"ai":"axe",ruleOrStepId:o.ruleId,outcome:"fail",pageUrl:t,selector:u,resolutionHint:`Fix ${o.ruleId} on ${u}.`})}const s=r.axeRulesEvaluated;if(s){for(const o of s.passed){const d=n.get(o.wcagCriterion);if(!d)continue;const c=`axe::${o.ruleId}::${t}::pass`;l(o.wcagCriterion,c)||d.evidence.push({source:"axe",ruleOrStepId:o.ruleId,outcome:"pass",pageUrl:t})}for(const o of s.inapplicable){const d=n.get(o.wcagCriterion);if(!d)continue;const c=`axe::${o.ruleId}::${t}::inapplicable`;l(o.wcagCriterion,c)||d.evidence.push({source:"axe",ruleOrStepId:o.ruleId,outcome:"inapplicable",pageUrl:t})}for(const o of s.incomplete){const d=n.get(o.wcagCriterion);if(!d)continue;const c=`axe::${o.ruleId}::${t}::incomplete`,u=d.evidence.findIndex(p=>p.source==="axe"&&p.outcome==="incomplete"&&p.ruleOrStepId===o.ruleId&&p.pageUrl===t);if(u>=0){if(o.elements&&o.elements.length>0){const p=d.evidence[u],h=new Set((p.elements??[]).map(m=>m.selector));for(const m of o.elements)h.has(m.selector)||((p.elements??(p.elements=[])).push(m),h.add(m.selector))}continue}l(o.wcagCriterion,c)||d.evidence.push({source:"axe",ruleOrStepId:o.ruleId,outcome:"incomplete",pageUrl:t,elements:o.elements?[...o.elements]:void 0,resolutionHint:"axe-core couldn't fully determine. Common causes: text against an image/gradient background, or aria-role on a hidden element. Review the page manually."})}}}if(i.incompleteResolutions&&i.incompleteResolutions.length>0){const r=new Map;for(const t of i.incompleteResolutions)r.set(`${t.pageUrl}::${t.ruleId}::${t.selector}`,t);for(const t of n.values()){const s=[];for(const o of t.evidence){if(o.source!=="axe"||o.outcome!=="incomplete"||!o.elements||o.elements.length===0){s.push(o);continue}const d=[];for(const c of o.elements){const u=`${o.pageUrl}::${o.ruleOrStepId}::${c.selector}`,p=r.get(u);if(!p){d.push(c);continue}p.verdict==="pass"?s.push({source:"ai",ruleOrStepId:`ai-resolved::${o.ruleOrStepId}`,outcome:"pass",pageUrl:o.pageUrl,selector:c.selector,notes:p.reasoning}):p.verdict==="fail"?s.push({source:"ai",ruleOrStepId:`ai-resolved::${o.ruleOrStepId}`,outcome:"fail",pageUrl:o.pageUrl,selector:c.selector,notes:p.reasoning,resolutionHint:`AI determined ${o.ruleOrStepId} fails on this element. Review and fix or override.`}):d.push(c)}d.length>0&&s.push({...o,elements:d})}t.evidence=s}}if(i.interactiveAuditResults&&i.interactiveAuditResults.length>0)for(const r of i.interactiveAuditResults){const t=n.get(r.criterionId);t&&t.evidence.push({source:"ai",ruleOrStepId:r.ruleId,outcome:r.verdict==="pass"?"pass":r.verdict==="fail"?"fail":"incomplete",pageUrl:r.pageUrl,notes:r.reasoning,resolutionHint:r.verdict==="fail"?"Review the AI walkthrough in the Compliance tab; fix the underlying focus-order issue and re-run.":r.verdict==="uncertain"?"Re-run the interactive audit, or manually verify via Guided Tests.":void 0})}for(const r of i.workflows)for(const t of r.steps){if(!t.wcag)continue;const s=n.get(t.wcag);if(s)for(const o of i.igtRuns){if(o.workflowId!==r.id)continue;const d=o.steps[t.id],c=`${r.id}.${t.id}`;if(!d){s.evidence.push({source:"igt",ruleOrStepId:c,outcome:"skip",resolutionHint:`Open Guided Tests → ${r.name} → answer "${t.id}" as Pass / Fail / N/A.`});continue}d.status==="pass"?s.evidence.push({source:"igt",ruleOrStepId:c,outcome:"pass",notes:d.notes}):d.status==="fail"?s.evidence.push({source:"igt",ruleOrStepId:c,outcome:"fail",notes:d.notes,resolutionHint:`Address the failing manual check: ${t.question}`}):d.status==="not-applicable"?s.evidence.push({source:"igt",ruleOrStepId:c,outcome:"n/a",notes:d.notes}):d.status==="skip"&&s.evidence.push({source:"igt",ruleOrStepId:c,outcome:"skip",notes:d.notes,resolutionHint:`Open Guided Tests → ${r.name} → re-answer "${t.id}" as Pass / Fail / N/A.`})}}for(const r of n.values())r.state=ae(r.evidence);if(i.auditScope==="single-page")for(const r of re){const t=n.get(r);t&&t.state==="not-evaluated"&&(t.state="not-applicable",t.evidence.push({source:"axe",ruleOrStepId:"wcc-multi-page-only-na",outcome:"n/a",notes:"Single-page audit cannot evaluate this cross-page criterion. Treated as N/A for this audit; run Site Crawl to evaluate."}))}if(i.humanCriterionVerdicts&&i.humanCriterionVerdicts.length>0)for(const r of i.humanCriterionVerdicts){const t=n.get(r.criterionId);if(!t)continue;const s=r.verdict==="na"?"n/a":r.verdict,o=r.verdict==="na"?"not-applicable":r.verdict==="fail"?"fail":"pass";t.state=o,t.evidence.push({source:"human",ruleOrStepId:"human-criterion-verdict",outcome:s,notes:`Human verified ${r.verdict.toUpperCase()} on ${r.verifiedAt}: ${r.note}`})}return n}function ae(i){return i.length===0?"not-evaluated":i.some(n=>n.outcome==="fail")?"fail":i.some(n=>n.outcome==="incomplete"||n.outcome==="skip")?"inconclusive":i.some(n=>n.outcome==="pass"||n.outcome==="inapplicable"||n.outcome==="ack")?"pass":"not-applicable"}function We(i){const e={pass:[],fail:[],inconclusive:[],notApplicable:[],notEvaluated:[]};for(const a of i.values())e[se(a.state)].push(a.criterionId);const n=i.size;return{pass:e.pass.length,fail:e.fail.length,inconclusive:e.inconclusive.length,notApplicable:e.notApplicable.length,notEvaluated:e.notEvaluated.length,totalApplicable:n,canClaimConformance:e.fail.length===0&&e.inconclusive.length===0&&e.notEvaluated.length===0,byState:e}}function se(i){return i==="not-applicable"?"notApplicable":i==="not-evaluated"?"notEvaluated":i}function Ve(i,e=te){const n=new Set,a=new Set,l=new Set;for(const t of i.values())for(const s of t.evidence)s.source==="axe"?n.add(t.criterionId):s.source==="ai"?a.add(t.criterionId):s.source==="igt"&&l.add(t.criterionId);for(const t of e)for(const s of t.steps)s.wcag&&i.has(s.wcag)&&l.add(s.wcag);function r(t,s){const o=Array.from(s).sort();let d=0;const c=[],u=[],p=[];for(const h of o){const m=i.get(h);if(!m)continue;const y=m.evidence.filter(g=>t==="automation"&&g.source==="axe"||t==="ai"&&g.source==="ai"||t==="human"&&g.source==="igt");if(y.length===0){p.push(h);continue}const L=y.some(g=>g.outcome==="fail"),_=y.some(g=>g.outcome==="incomplete"||g.outcome==="skip"),F=y.some(g=>g.outcome==="pass"||g.outcome==="inapplicable"||g.outcome==="ack"||g.outcome==="n/a");L?c.push(h):_?u.push(h):F?d++:p.push(h)}return{layer:t,coveredCriteria:o,cleared:d,failing:c,inconclusive:u,blocked:[...c,...u].sort(),unevaluated:p}}return{automation:r("automation",n),ai:r("ai",a),human:r("human",l)}}const k="auditCache:",de=24*60*60*1e3;async function D(i){const e=new TextEncoder().encode(i),n=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(n)).map(a=>a.toString(16).padStart(2,"0")).join("")}async function le(i){const e=k+i,a=(await chrome.storage.local.get(e))[e];return!a||Date.now()-a.cachedAt>de?null:a}async function ce(i){const e=k+i.lookupKey;await chrome.storage.local.set({[e]:i})}async function ue(){const i=await chrome.storage.local.get(null),e=Object.keys(i).filter(n=>n.startsWith(k));e.length>0&&await chrome.storage.local.remove(e)}async function pe(i){return D(JSON.stringify(i))}async function ge(i){return D(JSON.stringify([...i??[]].sort()))}const $e=Object.freeze(Object.defineProperty({__proto__:null,clearAllCachedAudits:ue,getCachedAudit:le,hashDisabledRules:ge,hashMatrixConfig:pe,setCachedAudit:ce,sha256Hex:D},Symbol.toStringTag,{value:"Module"}));function ze(i){return{...C,...i??{},enabledChecks:{...C.enabledChecks,...(i==null?void 0:i.enabledChecks)??{}}}}const C={enabled:!1,provider:"anthropic",apiKey:"",costCapUsd:5,model:"",enabledChecks:{altText:!0,headings:!0,sensory:!0,aria:!1,imageOfText:!0,colorOnlyMeaning:!0,genericLinkText:!0,wallOfText:!0,languageMismatch:!0},imageOfTextMaxImages:5,maxCandidatesPerCheck:10},he=U("ai-usage-log"),A="aiUsageLog",R=200;async function Ke(i){try{const e=await E();e.unshift(i),e.length>R&&(e.length=R),await chrome.storage.local.set({[A]:e})}catch(e){he.warn("failed to append ai usage entry",e)}}async function E(){try{const e=(await chrome.storage.local.get(A))[A];return Array.isArray(e)?e:[]}catch{return[]}}function me(i,e=10){const n=new Date,a=`${n.getUTCFullYear()}-${n.getUTCMonth()}`;let l=0,r=0,t=0;const s={};for(const o of i){l+=o.totalCostUsd,`${new Date(o.at).getUTCFullYear()}-${new Date(o.at).getUTCMonth()}`===a&&(r+=o.totalCostUsd,t++);for(const[c,u]of Object.entries(o.byCheck))u!=null&&(s[c]=(s[c]??0)+u)}return{totalSpentUsd:l,totalAudits:i.length,spentThisMonthUsd:r,auditsThisMonth:t,averageCostUsd:i.length===0?null:l/i.length,byCheck:s,recent:i.slice(0,e)}}async function Ge(i=10){const e=await E();return me(e,i)}async function Be(){await chrome.storage.local.remove(A)}export{Se as A,V as B,Oe as C,w as D,Te as E,Me as F,Le as G,Ee as H,We as I,D as J,pe as K,ge as L,le as M,ce as N,Ke as O,_e as P,$e as Q,ne as T,ie as W,fe as a,C as b,ue as c,Be as d,T as e,qe as f,ye as g,Ve as h,Ne as i,te as j,Ce as k,Ge as l,Ie as m,ke as n,De as o,Ae as p,Fe as q,we as r,be as s,xe as t,oe as u,Ue as v,b as w,Re as x,ze as y,Pe as z};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/site-report-renderer-klOJEyJa.js","assets/scheduled-audit-runner-Cad1yq0z.js","assets/preload-helper-D7HrI6pR.js","assets/crash-reporter-KD5f4utB.js","assets/diff-RnwNJg4F.js","assets/ai-usage-log-CYyG5MT2.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import"./modulepreload-polyfill-B5Qt9EMX.js";import{r as c,j as e,C as je,c as ze,R as De}from"./styles-B_kTykZT.js";import{u as b,c as Pe,a as We,l as le,b as Fe,d as Le,i as Oe,P as $e,M as _e,s as He,w as Ge,r as Me,e as Be,f as Ve,g as Ke,p as qe,h as Ye,A as Ze,j as Qe,E as Je,k as Xe}from"./ErrorBoundary-TPkmJFZP.js";import{s as T,r as et,a as tt,i as rt}from"./crash-reporter-KD5f4utB.js";import{B as ce,W as at}from"./ai-usage-log-CYyG5MT2.js";import{l as nt,a as it,g as Ce,b as ot,c as st,d as Te,r as lt,s as ct,e as dt,f as Re,h as Ae,i as ut,j as pt,k as vt,m as ht,n as gt}from"./scheduled-audit-runner-Cad1yq0z.js";import{_ as re}from"./preload-helper-D7HrI6pR.js";import{copyAiFixerPrompt as mt}from"./copy-ai-fixer-prompt-DKUDhBLv.js";import{w as ve,h as he,r as ge}from"./tier-config-client-85XOCE5d.js";import{w as me,r as fe}from"./rubric-config-client-DJcOQbG2.js";import"./_commonjsHelpers-Cpj98o6Y.js";import"./diff-RnwNJg4F.js";import"./design-system-audit-DpxJrxnb.js";function ye({initialUrl:t,isRunning:a,onCrawl:r,onVerifyFixes:s,onAuditThisPage:i,reviewEnabled:l,onToggleReview:n}){const[o,u]=c.useState(t),[v,h]=c.useState(25),[w,f]=c.useState(""),[k,y]=c.useState(""),[x,d]=c.useState(!1),[S,I]=c.useState(ce),[C,O]=c.useState(ce[0].id),[$,U]=c.useState(null),[_,A]=c.useState(!0);c.useEffect(()=>{t&&!o&&u(t)},[t]),c.useEffect(()=>{let g=!1;return Promise.all([T({type:"SETTINGS_GET",key:"matrixPresets"}),T({type:"SETTINGS_GET",key:"activePresetId"})]).then(([p,j])=>{if(g)return;const D=Array.isArray(p.data)?p.data:null;I(D&&D.length>0?D:ce),typeof j.data=="string"&&O(j.data)}),()=>{g=!0}},[]),c.useEffect(()=>{let g=!1;return T({type:"SETTINGS_GET",key:"crawlRememberSettings"}).then(async p=>{if(g)return;const D=p.data!==!1;if(A(D),!D)return;const[R,W,H]=await Promise.all([T({type:"SETTINGS_GET",key:"crawlMaxPages"}),T({type:"SETTINGS_GET",key:"crawlIncludeRegex"}),T({type:"SETTINGS_GET",key:"crawlExcludeRegex"})]);if(g)return;const q=R.data;typeof q=="number"&&q>=1&&h(Math.min(200,q));const Q=W.data,J=H.data;typeof Q=="string"&&Q&&f(Q),typeof J=="string"&&J&&y(J),(typeof Q=="string"&&Q||typeof J=="string"&&J)&&d(!0)}),()=>{g=!0}},[]);function V(g){h(g),_&&T({type:"SETTINGS_SET",key:"crawlMaxPages",value:g})}function m(g){f(g),_&&T({type:"SETTINGS_SET",key:"crawlIncludeRegex",value:g})}function z(g){y(g),_&&T({type:"SETTINGS_SET",key:"crawlExcludeRegex",value:g})}function N(g){A(g),T({type:"SETTINGS_SET",key:"crawlRememberSettings",value:g}),g&&(T({type:"SETTINGS_SET",key:"crawlMaxPages",value:v}),T({type:"SETTINGS_SET",key:"crawlIncludeRegex",value:w.trim()}),T({type:"SETTINGS_SET",key:"crawlExcludeRegex",value:k.trim()}))}function E(g){const p=S.find(j=>j.id===g);p&&(O(g),T({type:"SETTINGS_SET",key:"activePresetId",value:g}),T({type:"SETTINGS_SET",key:"stateMatrix",value:p.matrix}))}function M(){U(null);for(const[g,p]of[["Include",w.trim()],["Exclude",k.trim()]])if(p)try{new RegExp(p)}catch(j){return U(`${g} regex invalid: ${j instanceof Error?j.message:String(j)}`),!1}return!0}function F(){const g=o.trim();if(!g)return null;let p;try{p=new URL(g)}catch{return"Start URL must be a full URL starting with http:// or https://."}return p.protocol!=="http:"&&p.protocol!=="https:"?`Start URL must use http:// or https:// — ${p.protocol} can't be crawled.`:null}const P=F(),B=!!o.trim()&&!P;function K(g){if(!M()||!B)return;const p={startUrl:o.trim(),maxPages:v,includeRegex:w.trim(),excludeRegex:k.trim()};g&&s?s(p):r(p)}return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--v2-pad-3)",textAlign:"left"},children:[e.jsxs(X,{label:"Start URL",children:[e.jsx("input",{type:"url",value:o,onChange:g=>u(g.target.value),placeholder:"https://yoursite.com",disabled:a,"aria-invalid":!!P,className:"v2-mono",style:ee}),P&&e.jsx("p",{role:"alert",style:{margin:"4px 0 0",fontSize:11,color:"var(--v2-critical)",lineHeight:1.4},children:P})]}),e.jsx(X,{label:"Max pages",hint:"1–200. Each page runs the full pipeline you configured.",children:e.jsx("input",{type:"number",min:1,max:200,value:v,onChange:g=>V(Math.min(200,Math.max(1,parseInt(g.target.value,10)||25))),disabled:a,className:"v2-mono",style:{...ee,maxWidth:100}})}),e.jsx(X,{label:"Audit depth",hint:"State matrix preset applied to every crawled page.",children:e.jsx("select",{value:C,onChange:g=>E(g.target.value),disabled:a,style:ee,children:S.map(g=>e.jsx("option",{value:g.id,children:g.name},g.id))})}),e.jsx("button",{type:"button",onClick:()=>d(g=>!g),className:"v2-eyebrow",style:{background:"none",border:"none",padding:0,cursor:"pointer",color:"var(--v2-ink-secondary)",textAlign:"left",alignSelf:"flex-start"},children:x?"− hide advanced filters":"+ show URL filters (include / exclude)"}),x&&e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"Include only URLs matching",hint:"Optional regex. Empty = no filter.",children:e.jsx("input",{type:"text",value:w,onChange:g=>m(g.target.value),placeholder:"^https://example\\.com/products/",disabled:a,className:"v2-mono",style:ee})}),e.jsx(X,{label:"Exclude URLs matching",hint:"Optional regex. Useful for /admin or /login while logged in.",children:e.jsx("input",{type:"text",value:k,onChange:g=>z(g.target.value),placeholder:"/admin|/dashboard|/login",disabled:a,className:"v2-mono",style:ee})})]}),$&&e.jsx("p",{role:"alert",style:{color:"var(--v2-critical)",fontSize:12,margin:0,padding:"var(--v2-pad-2) var(--v2-pad-3)",border:"1px solid var(--v2-critical)",borderRadius:4,background:"rgba(207, 44, 44, 0.06)"},children:$}),e.jsxs("label",{style:{display:"flex",alignItems:"flex-start",gap:"var(--v2-pad-2)",fontSize:12,lineHeight:1.4,color:"var(--v2-ink-secondary)",cursor:"pointer"},children:[e.jsx("input",{type:"checkbox",checked:_,disabled:a,onChange:g=>N(g.target.checked),style:{marginTop:2}}),e.jsxs("span",{children:[e.jsx("strong",{style:{color:"var(--v2-ink-primary)"},children:"Remember these settings."})," ","Keep max pages + the include/exclude filters for next time (the audit-depth preset is always remembered)."]})]}),e.jsxs("label",{style:{display:"flex",alignItems:"flex-start",gap:"var(--v2-pad-2)",fontSize:12,lineHeight:1.4,color:"var(--v2-ink-secondary)",cursor:"pointer"},children:[e.jsx("input",{type:"checkbox",checked:l,disabled:a,onChange:g=>n(g.target.checked),style:{marginTop:2}}),e.jsxs("span",{children:[e.jsx("strong",{style:{color:"var(--v2-ink-primary)"},children:"Review pages before auditing."})," ","List every page that would be crawled, then remove any you don't want before the audit runs."]})]}),e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-2)",flexWrap:"wrap",marginTop:"var(--v2-pad-2)"},children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary",disabled:a||!B,onClick:()=>K(!1),children:a?"Crawling…":l?"Find pages to audit":"Crawl whole site"}),s&&e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",disabled:a||!B,onClick:()=>K(!0),title:"Skip walkthroughs that previously passed or were human-verified",children:"Verify fixes only"}),i&&e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",disabled:a,onClick:i,title:"Single-page audit on the active tab (no crawl)",children:"Just this page"})]})]})}function ft(){var h;const t=b(w=>w.siteCrawlProgress),a=b(w=>w.siteCrawlStatus),r=b(w=>w.progress),s=b(w=>w.aiProgress),[i,l]=c.useState(!1);function n(){l(!0),T({type:"CANCEL_SITE_CRAWL"})}if(a!=="running")return null;const o=t?Math.min(100,Math.max(0,t.current/Math.max(1,t.total)*100)):0,u=r?Math.min(100,Math.max(0,r.current/Math.max(1,r.total)*100)):0,v=r!=null&&r.currentState?[r.currentState.pseudoState,r.currentState.theme&&r.currentState.theme!=="light"?r.currentState.theme:null,r.currentState.direction&&r.currentState.direction!=="ltr"?r.currentState.direction:null,(h=r.currentState.breakpoint)!=null&&h.id&&r.currentState.breakpoint.id!=="desktop"?r.currentState.breakpoint.id:null].filter(Boolean).join(" · "):"";return e.jsxs("div",{role:"status","aria-live":"polite",style:{background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:6,padding:"var(--v2-pad-4)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-3)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--v2-pad-3)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,color:"var(--v2-action)"},children:"crawling…"}),e.jsx("p",{className:"v2-mono",style:{margin:0,fontSize:12,fontWeight:600,color:"var(--v2-ink-primary)",fontVariantNumeric:"tabular-nums"},children:t?`${t.current} / ${t.total}`:"…"})]}),e.jsx("div",{role:"progressbar","aria-valuenow":(t==null?void 0:t.current)??0,"aria-valuemin":0,"aria-valuemax":(t==null?void 0:t.total)??1,"aria-label":"Crawl progress",style:{height:8,background:"var(--v2-bg-elev-2)",borderRadius:4,overflow:"hidden"},children:e.jsx("div",{style:{height:"100%",width:`${o}%`,background:"var(--v2-action)",transition:"width 240ms ease"}})}),(t==null?void 0:t.url)&&e.jsxs("div",{children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,marginBottom:4},children:"current page"}),e.jsx("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-secondary)",wordBreak:"break-all"},children:t.url})]}),(t==null?void 0:t.lastViolations)!==void 0&&t.lastViolations>0&&e.jsxs("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",fontVariantNumeric:"tabular-nums"},children:["last page: ",t.lastViolations," axe violation",t.lastViolations===1?"":"s"]}),r&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-2)",paddingTop:"var(--v2-pad-3)",borderTop:"1px solid var(--v2-border)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--v2-pad-3)"},children:[e.jsx("span",{className:"v2-eyebrow",style:{color:"var(--v2-ink-tertiary)"},children:"this page · auditing"}),e.jsxs("span",{className:"v2-mono",style:{fontSize:11,color:"var(--v2-ink-secondary)",fontVariantNumeric:"tabular-nums"},children:[r.current," / ",r.total]})]}),e.jsx("div",{role:"progressbar","aria-valuenow":r.current,"aria-valuemin":0,"aria-valuemax":r.total,"aria-label":"Current page audit progress",style:{height:4,background:"var(--v2-bg-elev-2)",borderRadius:2,overflow:"hidden"},children:e.jsx("div",{style:{height:"100%",width:`${u}%`,background:"var(--v2-ink-tertiary)",transition:"width 240ms ease"}})}),v&&e.jsxs("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)"},children:["state: ",v]}),s&&e.jsxs("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-needs-review)",fontVariantNumeric:"tabular-nums"},children:["AI: ",s.current," / ",s.total," · ",s.currentCheckLabel,s.candidatesTotal&&s.candidatesTotal>0?` (${s.candidatesDone??0}/${s.candidatesTotal})`:""]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-3)"},children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:n,disabled:i,children:i?"Cancelling…":"Cancel crawl"}),i&&e.jsx("span",{"aria-live":"polite",style:{fontSize:11,color:"var(--v2-ink-tertiary)"},children:"Wrapping up current page audit — final cancel can take up to a few seconds."})]})]})}function yt(){const t=b(i=>i.crawlDiscoveryStatus),a=b(i=>i.crawlDiscoveryFound),r=b(i=>i.crawlDiscoveryLastUrl);function s(){T({type:"CANCEL_CRAWL_DISCOVERY"}),b.getState().resetCrawlDiscovery()}return t!=="discovering"?null:e.jsxs("div",{role:"status","aria-live":"polite",style:{background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:6,padding:"var(--v2-pad-4)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-3)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,color:"var(--v2-action)"},children:"finding pages…"}),e.jsxs("p",{className:"v2-mono",style:{margin:0,fontSize:12,fontWeight:600,color:"var(--v2-ink-primary)",fontVariantNumeric:"tabular-nums"},children:[a," page",a===1?"":"s"," found"]}),r&&e.jsx("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-secondary)",wordBreak:"break-all"},children:r}),e.jsx("p",{style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.4},children:"Loading each page to read its links — no audit yet. You'll prune the list before anything is audited."}),e.jsx("div",{children:e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:s,children:"Cancel"})})]})}function xt({onAudit:t}){const a=b(n=>n.crawlDiscoveryStatus),r=b(n=>n.crawlDiscoveryUrls),[s,i]=c.useState(new Set);c.useEffect(()=>{a==="reviewing"&&i(new Set(r))},[a,r]);function l(){T({type:"CANCEL_CRAWL_DISCOVERY"}),b.getState().resetCrawlDiscovery()}return a!=="reviewing"?null:e.jsxs("div",{style:{background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:6,padding:"var(--v2-pad-4)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-3)",textAlign:"left"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,color:"var(--v2-action)"},children:"review pages to audit"}),e.jsxs("p",{style:{margin:0,fontSize:12,color:"var(--v2-ink-secondary)",lineHeight:1.4},children:["Found ",e.jsx("strong",{style:{color:"var(--v2-ink-primary)"},children:r.length})," page",r.length===1?"":"s",". Uncheck any you don't want, then audit the rest. ",e.jsx("strong",{style:{color:"var(--v2-ink-primary)"},children:s.size})," selected."]}),r.length===0?e.jsx("p",{style:{margin:0,fontSize:12,color:"var(--v2-ink-tertiary)"},children:"No pages discovered from this URL. Check the start URL + filters and try again."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-3)"},children:[e.jsx("button",{type:"button",onClick:()=>i(new Set(r)),style:{background:"none",border:"none",padding:0,cursor:"pointer",color:"var(--v2-action)",fontSize:11},children:"select all"}),e.jsx("button",{type:"button",onClick:()=>i(new Set),style:{background:"none",border:"none",padding:0,cursor:"pointer",color:"var(--v2-action)",fontSize:11},children:"select none"})]}),e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0,maxHeight:300,overflowY:"auto",border:"1px solid var(--v2-border)",borderRadius:4},children:r.map(n=>e.jsx("li",{style:{borderBottom:"1px solid var(--v2-border)"},children:e.jsxs("label",{style:{display:"flex",alignItems:"flex-start",gap:"var(--v2-pad-2)",padding:"6px 10px",fontSize:11,cursor:"pointer"},children:[e.jsx("input",{type:"checkbox",checked:s.has(n),onChange:o=>i(u=>{const v=new Set(u);return o.target.checked?v.add(n):v.delete(n),v}),style:{marginTop:2}}),e.jsx("span",{className:"v2-mono",style:{wordBreak:"break-all",color:"var(--v2-ink-secondary)"},children:n})]})},n))})]}),e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-2)",flexWrap:"wrap"},children:[e.jsxs("button",{type:"button",className:"v2-btn v2-btn-primary",disabled:s.size===0,onClick:()=>t(r.filter(n=>s.has(n))),children:["Audit ",s.size," page",s.size===1?"":"s"]}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:l,children:"Cancel"})]})]})}function bt(){const t=b(h=>h.status),a=b(h=>h.progress),r=b(h=>h.aiProgress),[s,i]=c.useState(!1);if(t!=="running")return null;const l=a?a.current>=a.total:!1,n=a?l?"Running deep analyzers…":`Auditing… ${a.current} / ${a.total}`:"Starting audit…",o=a?l?"reading order · tab order · typography · CSS vars · AI candidates":kt(a.currentState):"Loading axe + DOM analyzers",u=a?l?100:a.current/Math.max(1,a.total)*100:0;function v(){i(!0),T({type:"CANCEL_AUDIT"})}return e.jsxs("div",{role:"status","aria-live":"polite",style:{background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:6,padding:"var(--v2-pad-4)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-4)"},children:[e.jsx(xe,{label:n,detail:o,pct:u,valuenow:a?Math.min(a.current,a.total):0,valuemax:a?a.total:1,ariaLabel:a?l?"Running deep analyzers: reading order, tab order, typography, custom properties, AI candidates.":`Audit progress: ${a.current} of ${a.total} states`:"Audit starting",fillColor:"var(--v2-action)"}),r&&e.jsx(xe,{label:`AI augmentation… ${r.current} / ${r.total}`,detail:r.candidatesTotal&&r.candidatesTotal>0?`${r.currentCheckLabel} (${r.candidatesDone??0}/${r.candidatesTotal})`:r.currentCheckLabel,pct:r.current/Math.max(1,r.total)*100,valuenow:r.current,valuemax:r.total,ariaLabel:`AI augmentation: ${r.current} of ${r.total} checks. ${r.currentCheckLabel}`,fillColor:"var(--v2-needs-review)"}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-3)"},children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:v,disabled:s,children:s?"Cancelling…":"Cancel audit"}),s&&e.jsx("span",{"aria-live":"polite",style:{fontSize:11,color:"var(--v2-ink-tertiary)"},children:"Wrapping up — final cancel can take up to a few seconds."})]})]})}function xe({label:t,detail:a,pct:r,valuenow:s,valuemax:i,ariaLabel:l,fillColor:n}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:[e.jsx("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--v2-pad-3)"},children:e.jsx("span",{className:"v2-eyebrow",style:{margin:0,color:"var(--v2-action)"},children:t})}),e.jsx("div",{role:"progressbar","aria-valuenow":s,"aria-valuemin":0,"aria-valuemax":i,"aria-label":l,style:{height:6,background:"var(--v2-bg-elev-2)",borderRadius:3,overflow:"hidden"},children:e.jsx("div",{style:{height:"100%",width:`${r}%`,background:n,transition:"width 240ms ease"}})}),a&&e.jsx("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-secondary)",wordBreak:"break-all"},children:a})]})}function kt(t){if(!t)return"";const a=[t.pseudoState];return t.theme&&t.theme!=="light"&&a.push(t.theme),t.direction&&t.direction!=="ltr"&&a.push(t.direction),a.join(" · ")}function X({label:t,hint:a,children:r}){return e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:4},children:[e.jsx("span",{className:"v2-eyebrow",style:{color:"var(--v2-ink-secondary)"},children:t}),r,a&&e.jsx("span",{style:{fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.4},children:a})]})}const ee={fontFamily:"var(--v2-body)",fontSize:12,padding:"8px 10px",background:"var(--v2-bg)",color:"var(--v2-ink-primary)",border:"1px solid var(--v2-border-strong)",borderRadius:4,outline:"none"};function oe(){const t=b(u=>u.siteCrawlReport),a=b(u=>u.results),r=b(u=>u.delta),s=b(u=>u.componentId),i=b(u=>u.status),l=b(u=>u.siteCrawlStatus),[n,o]=c.useState({report:null,resolvedFails:[]});return c.useEffect(()=>{var w;let u=!1;async function v(f){return f.length===0?[]:(await Promise.all(f.map(y=>Ce(y)))).flat().map(ot).map(st).filter(y=>y.verdict==="fail")}if(l==="running"||i==="running"){o({report:null,resolvedFails:[]});return}if(t)return(async()=>{const f=t.pages.map(y=>y.url),k=await v(f);u||o({report:t,resolvedFails:k})})(),()=>{u=!0};if(a.length===0||!s){o({report:null,resolvedFails:[]});return}const h=(w=a[0])==null?void 0:w.pageUrl;if(!h){o({report:null,resolvedFails:[]});return}return(async()=>{try{const[f,k]=await Promise.all([nt(a),v([h])]),y=new Date().toISOString(),x=it(h,[{url:h,results:a,delta:r,componentId:s,durationMs:0}],y,y,0,f.walkthroughsByComponent,f.walkthroughAcksByComponent,f.ackedKeysByComponent,f.humanVerdictsByComponent,f.incompleteResolutionsByComponent);u||o({report:x,resolvedFails:k})}catch(f){console.warn("[view-model] synthesize single-page report failed",f),u||o({report:null,resolvedFails:[]})}})(),()=>{u=!0}},[t,a,r,s,i,l]),n}const wt={"1.2.1":{howToCheck:"Confirm any audio-only or video-only media has a text alternative (transcript, captions, descriptive title). If the page has no audio or video at all, mark N/A with that note."},"1.2.2":{howToCheck:"For every prerecorded video with audio, verify captions are present and synchronized. Open each video, turn captions on, and spot-check 10–15 seconds. If the page has no video with audio, mark N/A."},"1.2.3":{howToCheck:"For every prerecorded video, confirm an audio description track OR a full text alternative is available. If no prerecorded video, mark N/A."},"1.2.4":{howToCheck:"For any live streaming media with audio, verify live captions are provided. If the page has no live media, mark N/A."},"1.2.5":{howToCheck:"For prerecorded video, confirm an audio description track is provided (separate from the main audio). If no prerecorded video, mark N/A."},"1.3.1":{howToCheck:"Inspect headings, lists, tables, and form labels. Programmatic structure should match visual structure: h1→h2→h3, real <ul>/<ol>, real <table> with <th>, every form field has a <label> or aria-label. Tabbing through the page should reveal the same structure a screen reader would announce."},"1.4.3":{howToCheck:"Open the inconclusive elements. Most commonly axe failed because the background is transparent, a gradient, or an image. Identify the EFFECTIVE background color a user sees and compute the contrast ratio against the foreground; needs ≥4.5:1 for normal text, ≥3:1 for large text (18pt+ or 14pt+ bold)."},"1.4.4":{howToCheck:"Zoom the page to 200% (Ctrl+Plus four times in most browsers). Verify all content remains visible and functional — no overlapping text, no clipped buttons, no horizontal scrollbar at 1280×1024 viewport."},"1.4.10":{howToCheck:"Resize the browser to 320 CSS px wide (or use devtools mobile emulation at 320×256). Confirm content reflows without two-dimensional scrolling — vertical scroll only, no horizontal scroll except for genuinely two-dimensional content (data tables, images, complex maps)."},"1.4.11":{howToCheck:"Verify every UI component's boundary (button borders, form field outlines, focus indicators) has ≥3:1 contrast against its adjacent color. Same for meaningful graphics (icons, infographic elements). Decorative graphics are exempt."},"1.4.12":{howToCheck:"Apply this CSS via devtools and confirm no content is clipped or hidden: line-height: 1.5; letter-spacing: 0.12em; word-spacing: 0.16em; paragraph spacing 2× font-size. If layout breaks, the page fails."},"2.1.1":{howToCheck:"Tab through every interactive element. Every button, link, form field, and custom control must be reachable AND operable via keyboard alone (Enter, Space, arrow keys as appropriate). Mouse-only affordances fail."},"2.1.2":{howToCheck:"Tab into every interactive component. Confirm Tab/Shift+Tab moves focus out. No element should trap focus (typical offenders: poorly-coded modals, embedded players)."},"2.4.1":{howToCheck:"Verify a skip-to-main-content link exists (typically first focusable element, visible on focus) OR landmark regions (<main>, <nav>) are present. Either lets keyboard users bypass repeated nav."},"2.4.3":{howToCheck:"Tab through the page in source order. Focus must move in a sequence that preserves meaning — usually left-to-right, top-to-bottom. Particularly check skip links and modals."},"2.4.4":{howToCheck:`Read each link's text WITH its surrounding context (parent paragraph, list item, table cell). The combined text must convey where the link goes. "Click here" alone is ambiguous; "Click here to read our pricing" passes when context is included.`},"2.4.5":{howToCheck:"Confirm at least two ways to find a given page exist: site search, sitemap, A-Z index, table of contents, or persistent navigation. Single-page sites and process-step pages (checkout) are exempt."},"2.4.6":{howToCheck:"Read each heading and form-field label in isolation. Each should describe the topic of its section or the purpose of its field WITHOUT requiring the surrounding content to make sense."},"2.4.7":{howToCheck:"Tab through every focusable element. The current focus must be VISUALLY distinct from neighbors — an outline, a box-shadow, a background change. The default browser outline counts; CSS that removes it without replacing fails."},"2.5.3":{howToCheck:"For every control with both a visible text label and an accessible name (aria-label, alt, etc.), verify the visible label appears (verbatim, or as a substring) in the accessible name. Otherwise voice-control users can't target it by saying its visible label."},"3.1.1":{howToCheck:'View source. Confirm <html lang="..."> is present with a valid language tag (e.g. "en", "en-US", "fr").'},"3.1.2":{howToCheck:"Find any passage of foreign-language text on the page (a quote, a borrowed phrase, an entire alternate-language section). Confirm it's wrapped with the appropriate lang attribute. If the entire page is in one language, mark N/A."},"3.2.1":{howToCheck:"Tab to each focusable element. Confirm receiving focus alone does NOT trigger a context change: no navigation, no modal opening, no form submission. Action only on explicit activation (click, Enter)."},"3.2.2":{howToCheck:"In each form, change one input value (type in a field, check a checkbox, change a select). Confirm this does NOT submit the form, navigate the page, or open a modal without first warning the user."},"3.2.3":{howToCheck:"Open at least three different pages on the site. Confirm the main navigation, footer navigation, and any breadcrumb appear in the SAME relative order on each. Reordering items between pages is a fail; adding or removing items based on auth state is acceptable."},"3.2.4":{howToCheck:"Identify a few common functional elements on the site (e.g., the search input, login button, cart button, social-share icons). Verify each appears with the SAME accessible name, label, and icon on every page where it appears. Inconsistent naming is the fail mode."},"3.3.1":{howToCheck:"Submit a form with invalid data. Confirm errors are identified in text (not just color), describe what went wrong, and ideally indicate which field. Browser-default validation messages count."},"3.3.2":{howToCheck:"Every form input should have a visible label (or visible placeholder + accessible name combination) AND an instruction when format matters (date format, password rules). Placeholder-only labels fail because they disappear on focus."},"3.3.3":{howToCheck:'Submit a form with invalid data. Confirm the error message describes HOW to fix the problem (e.g., "Email must contain @" not just "Invalid email"). Exempts cases where suggestion would compromise security (password rules).'},"3.3.4":{howToCheck:"For any form that submits a legal commitment, financial transaction, or modifies/deletes user data: confirm submissions are reversible, validated for errors before commit, OR show a confirmation step before final commit."},"4.1.3":{howToCheck:'Trigger any status update (form submitted, item added to cart, search completed, error appeared). Confirm screen-reader users receive the update via an aria-live region or role="status"/"alert" — without moving focus to the update.'}};function St(t){return wt[t]??null}const jt={"1.1.1":{whatAiAdds:'alt-text descriptiveness (catches generic alts like "image", "figure 1")',mode:"per-finding"},"1.3.3":{whatAiAdds:'sensory-language detection ("click the green button")',mode:"per-finding"},"1.4.1":{whatAiAdds:"color-only meaning detection",mode:"per-finding"},"1.4.5":{whatAiAdds:"image-of-text identification",mode:"per-finding"},"2.4.4":{whatAiAdds:'generic link text ("click here", "read more")',mode:"per-finding"},"2.4.6":{whatAiAdds:"heading clarity vs section content",mode:"per-finding"},"3.1.1":{whatAiAdds:"declared-language vs actual content",mode:"per-finding"},"3.1.2":{whatAiAdds:"declared-language vs actual content (parts)",mode:"per-finding"},"3.1.5":{whatAiAdds:"wall-of-text / readability",mode:"per-finding"},"4.1.2":{whatAiAdds:"ARIA role semantic correctness",mode:"per-finding"},"1.3.2":{whatAiAdds:"reading-order DOM vs visual (AI vision walkthrough)",mode:"walkthrough"},"1.4.11":{whatAiAdds:"non-text contrast against backgrounds",mode:"walkthrough"},"2.1.2":{whatAiAdds:"no keyboard trap (Tab cycle walkthrough)",mode:"walkthrough"},"2.4.3":{whatAiAdds:"focus order vs visual layout",mode:"walkthrough"},"2.4.7":{whatAiAdds:"focus visibility (screenshot walkthrough)",mode:"walkthrough"},"2.5.3":{whatAiAdds:"visible label vs accessible name match",mode:"walkthrough"}};function ae(t){return jt[t]??null}function Ie(t){var a;return t.storeComponentId?t.storeComponentId:(a=t.storeCrawlReport)!=null&&a.startUrl?t.storeCrawlReport.startUrl:t.pageUrls[0]?t.pageUrls[0]:null}const be="aiConfig";function Ct(t){return`https://www.w3.org/WAI/WCAG22/Understanding/${t}`}const Tt=new Map(at.map(t=>[t.id,t]));async function Rt(t){const r=(await chrome.tabs.query({active:!0,currentWindow:!0}))[0];if(!(r!=null&&r.id))return{ok:!1,error:"No active tab."};const s=r.id,i=ie(t.pageUrl),l=ie(r.url??"");if(!(r.url===t.pageUrl)){try{await chrome.tabs.update(s,{url:t.pageUrl})}catch(h){return{ok:!1,error:h instanceof Error?h.message:"Failed to navigate tab."}}if(!await At(s,t.pageUrl,12e3))return{ok:!1,error:"Page did not finish loading in time."}}if(!t.selector)return{ok:!0,found:!1,matchCount:0};const o=[120,250,500,800,1200,800];let u="";for(let v=0;v<=o.length;v++)try{const h=await et(s,{type:"HIGHLIGHT_SHOW_REQUEST",tabId:s,selector:t.selector,scrollIntoView:!0});return{ok:!0,found:h.found,matchCount:h.matchCount}}catch(h){const w=h instanceof Error?h.message:String(h);if(u=w,!(w.includes("Could not establish connection")||w.includes("Receiving end does not exist")))break;const k=o[v];if(k===void 0)break;await new Promise(y=>setTimeout(y,k))}return{ok:!1,error:i!==l?`Navigated to ${t.pageUrl} — but the in-page highlighter couldn't attach (${u}).`:u}}function ie(t){try{return new URL(t).origin}catch{return""}}function At(t,a,r){return new Promise(s=>{let i=!1;const l=setTimeout(()=>{i||(i=!0,chrome.tabs.onUpdated.removeListener(n),s(!1))},r);function n(o,u,v){if(o!==t||u.status!=="complete")return;const h=ie(v.url??""),w=ie(a);w&&h&&h!==w||i||(i=!0,clearTimeout(l),chrome.tabs.onUpdated.removeListener(n),s(!0))}chrome.tabs.onUpdated.addListener(n)})}function ke(t){try{const a=new URL(t),r=a.pathname+a.search+a.hash||"/";return r.length>60?r.slice(0,57)+"...":r}catch{return t}}function It(t){return t.length>70?t.slice(0,67)+"...":t}function Et(t){try{const a=new Date(t),r=new Date,s=a.toDateString()===r.toDateString(),i=new Date(r);i.setDate(i.getDate()-1);const l=a.toDateString()===i.toDateString(),n=a.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"});return s?`today, ${n}`:l?`yesterday, ${n}`:`${a.toLocaleDateString(void 0,{month:"short",day:"numeric"})}, ${n}`}catch{return t}}function Nt(){const{report:t}=oe(),a=b(d=>d.componentId),r=b(d=>d.siteCrawlReport),[s,i]=c.useState(!1),[l,n]=c.useState(new Set),[o,u]=c.useState(0),v=c.useRef(""),[h,w]=c.useState(!1),[f,k]=c.useState("claude-sonnet-4-6");c.useEffect(()=>{(async()=>{const S=(await chrome.storage.local.get(be))[be];v.current=(S==null?void 0:S.apiKey)??"",w(!!(S!=null&&S.apiKey)),S!=null&&S.model&&k(S.model)})()},[]);const y=Ie({storeComponentId:a,storeCrawlReport:r,pageUrls:(t==null?void 0:t.pages.map(d=>d.url))??[]});if(c.useEffect(()=>{let d=!1;return(async()=>{if(!y){d||n(new Set);return}try{const S=await Te([y]);if(d)return;n(new Set(S.map(I=>I.criterionId)))}catch{d||n(new Set)}})(),()=>{d=!0}},[y,o]),!t)return null;const x=t.blockingCriteria;return!x||x.length===0||t.siteGrade!=="A"&&t.siteGrade!=="B"?null:e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)",padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-border)",borderRadius:4,background:"var(--v2-bg-elev)"},children:[e.jsxs("button",{type:"button",onClick:()=>i(d=>!d),"aria-expanded":s,style:{appearance:"none",background:"none",border:"none",padding:0,cursor:"pointer",color:"var(--v2-ink-primary)",fontSize:13,fontWeight:500,textAlign:"left",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--v2-pad-3)",width:"100%"},children:[e.jsx("span",{children:(()=>{const d=x.length,S=x.filter(C=>l.has(C.criterionId)).length,I=d-S;return S===0?`${d} criteri${d===1?"on":"a"} need${d===1?"s":""} your judgment`:I===0?`${d} criteri${d===1?"on":"a"} verified — re-crawl to lift the grade`:`${S} of ${d} verified · ${I} remaining`})()}),e.jsx("span",{"aria-hidden":"true",style:{fontSize:11,color:"var(--v2-ink-tertiary)"},children:s?"▾":"▸"})]}),s&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:[e.jsx("p",{style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:"Each criterion below has no affirmative evidence yet. Mark it Pass / N/A / Fail with a note about what you checked. Verdicts persist as forensic evidence and contribute to the audit's chain of custody."}),x.map(d=>e.jsx(Ut,{criterionId:d.criterionId,title:d.title,state:d.state,evidence:d.evidence,targetComponentId:y,apiKeyRef:v,apiKeyPresent:h,model:f,onVerdictChange:()=>u(S=>S+1)},d.criterionId))]})]})}function Ut({criterionId:t,title:a,state:r,evidence:s,targetComponentId:i,apiKeyRef:l,apiKeyPresent:n,model:o,onVerdictChange:u}){var j,D;const[v,h]=c.useState(null),[w,f]=c.useState(""),[k,y]=c.useState(!1),[x,d]=c.useState(null),[S,I]=c.useState(null),[C,O]=c.useState(!0),[$,U]=c.useState(!1),[_,A]=c.useState(null),[V,m]=c.useState(null),[z,N]=c.useState(null),E={untested:"No evidence — automation has no rule for this criterion",inconclusive:"Inconclusive — axe / AI ran but couldn't determine",failing:"Failing — at least one fail signal across the audit"};c.useEffect(()=>{let R=!1;return(async()=>{if(!i){R||O(!1);return}try{const H=(await Te([i])).find(q=>q.criterionId===t);if(R)return;I(H?{verdict:H.verdict,note:H.note,verifiedAt:H.verifiedAt}:null)}catch{R||I(null)}finally{R||O(!1)}})(),()=>{R=!0}},[t,i]);async function M(){if(i){y(!0),d(null);try{await lt(i,t),I(null),u()}catch(R){d(R instanceof Error?R.message:String(R))}finally{y(!1)}}}const F=Tt.get(t),P=F==null?void 0:F.shortDescription,B=F==null?void 0:F.understandingSlug,K=St(t);async function g(){if(!l.current){m("Set an Anthropic API key in extension Options first.");return}U(!0),m(null);try{const W=`Explain WCAG ${t} (${a}) in the context of this audit. State: ${r==="untested"?"no automated evidence (no axe rule covers it)":r==="inconclusive"?"inconclusive — axe or AI ran but could not produce a definitive pass/fail":"failing — at least one fail signal across the audit"}. Cover: (1) what the criterion actually requires in plain language, (2) common failure modes a developer should look for, (3) how to manually verify it on this site, (4) when to mark N/A vs Pass vs Fail. Keep it tight — 5–8 sentences total.`,H=await Pe({apiKey:l.current,model:o,messages:[{role:"user",content:W}],system:`You are wcagcheckr's WCAG explainer. The user is sitting in front of a forensic-grade audit tool and needs to record a manual verdict on a criterion the automation can't decide. Be precise. No marketing tone. When citing a verification step, name the exact device/browser/devtool action (e.g., "Resize Chrome devtools to 320 CSS px").`,maxTokens:600,maxCostUsd:.05});A(H.text),N(H.costUsd)}catch(R){m(R instanceof Error?R.message:String(R))}finally{U(!1)}}async function p(R){if(!i){d("No componentId available — re-run an audit first.");return}if(!w.trim()){d("Note is required — describe what you checked and why this verdict applies.");return}y(!0),d(null);const W=new Date().toISOString(),H=w.trim();try{await ct({componentId:i,criterionId:t,verdict:R,note:H,verifiedAt:W}),I({verdict:R,note:H,verifiedAt:W}),h(null),f(""),u()}catch(q){d(q instanceof Error?q.message:String(q))}finally{y(!1)}}if(S){const W={pass:{bg:"rgba(15, 143, 94, 0.08)",border:"var(--v2-verified)",ink:"var(--v2-verified)",label:"Pass"},na:{bg:"rgba(100, 116, 139, 0.10)",border:"var(--v2-border-strong)",ink:"var(--v2-ink-secondary)",label:"N/A"},fail:{bg:"rgba(207, 44, 44, 0.06)",border:"var(--v2-critical)",ink:"var(--v2-critical)",label:"Fail"}}[S.verdict];return e.jsxs("div",{role:"status",style:{padding:"var(--v2-pad-3) var(--v2-pad-4)",background:W.bg,border:`1px solid ${W.border}`,borderRadius:4},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--v2-pad-3)",flexWrap:"wrap"},children:[e.jsxs("span",{className:"v2-mono",style:{fontSize:11,fontWeight:600,color:"var(--v2-ink-tertiary)"},children:["WCAG ",t]}),e.jsx("span",{style:{fontSize:13,fontWeight:500,color:"var(--v2-ink-primary)"},children:a}),e.jsxs("span",{className:"v2-mono",style:{fontSize:10,fontWeight:700,textTransform:"uppercase",letterSpacing:"0.04em",padding:"2px 6px",borderRadius:3,color:"var(--v2-bg)",background:W.ink},children:["✓ ",W.label]})]}),e.jsx("p",{style:{margin:"6px 0 0",fontSize:12,color:"var(--v2-ink-primary)",lineHeight:1.5,whiteSpace:"pre-wrap"},children:S.note}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-3)",marginTop:"var(--v2-pad-2)",flexWrap:"wrap"},children:[e.jsxs("span",{className:"v2-mono",style:{fontSize:10,color:"var(--v2-ink-tertiary)"},children:["verified ",Et(S.verifiedAt)]}),e.jsx("button",{type:"button",onClick:M,disabled:k,style:{appearance:"none",background:"none",border:"none",padding:0,cursor:k?"wait":"pointer",fontSize:11,color:"var(--v2-ink-secondary)",textDecoration:"underline",textUnderlineOffset:2},children:k?"Un-marking…":"Un-mark this criterion"}),x&&e.jsx("span",{role:"alert",style:{fontSize:11,color:"var(--v2-critical)"},children:x})]})]})}return C?e.jsx("div",{"aria-hidden":"true",style:{padding:"var(--v2-pad-3) var(--v2-pad-4)",background:"var(--v2-bg)",border:"1px solid var(--v2-border)",borderRadius:4,minHeight:56}}):e.jsxs("div",{style:{padding:"var(--v2-pad-3) var(--v2-pad-4)",background:"var(--v2-bg)",border:"1px solid var(--v2-border)",borderRadius:4},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--v2-pad-3)",flexWrap:"wrap"},children:[e.jsxs("span",{className:"v2-mono",style:{fontSize:11,fontWeight:600,color:"var(--v2-ink-tertiary)"},children:["WCAG ",t]}),e.jsx("span",{style:{fontSize:13,fontWeight:500,color:"var(--v2-ink-primary)"},children:a}),!n&&ae(t)&&e.jsx("span",{title:`AI would add: ${(j=ae(t))==null?void 0:j.whatAiAdds}. Add an API key in Settings → AI to enable.`,style:{fontSize:10,fontWeight:600,padding:"1px 6px",borderRadius:3,background:"var(--v2-bg-elev)",color:"var(--v2-ink-tertiary)",border:"1px solid var(--v2-border)",letterSpacing:"0.02em"},children:"AI skipped"})]}),P&&e.jsx("p",{style:{margin:"4px 0 0",fontSize:12,color:"var(--v2-ink-secondary)",lineHeight:1.5},children:P}),!n&&ae(t)&&e.jsxs("p",{style:{margin:"4px 0 0",fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5,fontStyle:"italic"},children:["AI would judge: ",(D=ae(t))==null?void 0:D.whatAiAdds]}),e.jsx("p",{style:{margin:"6px 0 0",fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:E[r]}),K&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-2)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,fontSize:10},children:"how to check"}),e.jsx("p",{style:{margin:"2px 0 0",fontSize:12,color:"var(--v2-ink-secondary)",lineHeight:1.5},children:K.howToCheck})]}),s.length>0&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)"},children:[e.jsxs("p",{className:"v2-eyebrow",style:{margin:0,fontSize:10},children:["suspect locations · ",s.length]}),e.jsx("ul",{style:{listStyle:"none",padding:0,margin:"4px 0 0",display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:s.map((R,W)=>e.jsx(zt,{ev:R},`${R.pageUrl}::${R.selector??""}::${W}`))})]}),e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-3)",marginTop:"var(--v2-pad-2)",flexWrap:"wrap",alignItems:"center"},children:[B&&e.jsx("a",{href:Ct(B),target:"_blank",rel:"noreferrer noopener",style:{fontSize:11,color:"var(--v2-ink-secondary)",textDecoration:"underline",textUnderlineOffset:2},children:"Read W3C guidance ↗"}),n&&e.jsx("button",{type:"button",onClick:g,disabled:$,style:{appearance:"none",background:"none",border:"none",padding:0,cursor:$?"wait":"pointer",fontSize:11,color:"var(--v2-ink-secondary)",textDecoration:"underline",textUnderlineOffset:2},children:$?"Explaining…":_?"Re-explain with AI":"Explain with AI ↗"})]}),(_||V)&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-2)",padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:4},children:[_&&e.jsx("p",{style:{margin:0,fontSize:12,color:"var(--v2-ink-primary)",lineHeight:1.55,whiteSpace:"pre-wrap"},children:_}),V&&e.jsx("p",{role:"alert",style:{margin:0,fontSize:11,color:"var(--v2-critical)"},children:V}),z!==null&&e.jsxs("p",{className:"v2-mono",style:{margin:"4px 0 0",fontSize:10,color:"var(--v2-ink-tertiary)"},children:["$",z.toFixed(4)," · ",o]})]}),e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-2)",marginTop:"var(--v2-pad-3)",flexWrap:"wrap"},children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>{h(v==="pass"?null:"pass"),d(null)},"aria-expanded":v==="pass",children:v==="pass"?"Cancel":"Mark Pass"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>{h(v==="na"?null:"na"),d(null)},"aria-expanded":v==="na",children:v==="na"?"Cancel":"Mark N/A"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>{h(v==="fail"?null:"fail"),d(null)},"aria-expanded":v==="fail",children:v==="fail"?"Cancel":"Mark Fail"})]}),v&&e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0},children:"verification note · required"}),e.jsx("p",{style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.4},children:v==="na"?'Describe why this criterion does not apply to this audit (e.g., "no audio/video content on this page").':v==="pass"?'Describe what you checked to verify pass (e.g., "manually browsed page in keyboard-only mode, no focus traps").':'Describe the failure (e.g., "modal does not return focus to the trigger when closed").'}),e.jsx("textarea",{value:w,onChange:R=>f(R.target.value),rows:3,style:{width:"100%",fontFamily:"var(--v2-body)",fontSize:12,padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"var(--v2-bg)",color:"var(--v2-ink-primary)",border:"1px solid var(--v2-border-strong)",borderRadius:4,resize:"vertical",minHeight:56},placeholder:v==="na"?"e.g., No audio or video content present on this page; criterion is not applicable.":v==="pass"?"e.g., Manually verified — page resizes correctly at 200% zoom without horizontal scroll.":"e.g., Focus visible indicator missing on dark-mode buttons."}),x&&e.jsx("p",{role:"alert",style:{margin:0,padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"rgba(207, 44, 44, 0.06)",border:"1px solid var(--v2-critical)",borderRadius:4,color:"var(--v2-critical)",fontSize:11},children:x}),e.jsx("div",{children:e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:()=>p(v),disabled:k||!w.trim(),children:k?"Saving…":`Confirm ${v.toUpperCase()}`})})]})]})}function zt({ev:t}){const[a,r]=c.useState(!1),[s,i]=c.useState(null);async function l(){r(!0),i(null);try{const n=await Rt({pageUrl:t.pageUrl,selector:t.selector});n.ok?t.selector?n.found?i({kind:"ok",text:`Element highlighted (${n.matchCount} match${n.matchCount===1?"":"es"}).`}):i({kind:"warn",text:"Page opened but the selector matched zero elements — DOM may have changed since the audit."}):i({kind:"ok",text:`Opened ${ke(t.pageUrl)} — no element selector available; verify manually.`}):i({kind:"err",text:n.error})}finally{r(!1)}}return e.jsxs("li",{style:{padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"var(--v2-bg)",border:"1px solid var(--v2-border)",borderRadius:4,display:"flex",flexDirection:"column",gap:4},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--v2-pad-2)",flexWrap:"wrap"},children:[e.jsx("span",{className:"v2-mono",title:t.pageUrl,style:{fontSize:11,color:"var(--v2-ink-secondary)",overflowWrap:"anywhere"},children:ke(t.pageUrl)}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:l,disabled:a,children:a?"Opening…":t.selector?"Show on page":"Open page"})]}),t.selector&&e.jsx("span",{className:"v2-mono",title:t.selector,style:{fontSize:11,color:"var(--v2-ink-tertiary)",overflowWrap:"anywhere"},children:It(t.selector)}),t.notes&&e.jsx("span",{style:{fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.4},children:t.notes}),s&&e.jsx("span",{role:s.kind==="err"?"alert":"status",style:{fontSize:11,color:s.kind==="err"?"var(--v2-critical)":s.kind==="warn"?"var(--v2-needs-review)":"var(--v2-verified)"},children:s.text})]})}function Dt({sealed:t}){const[a,r]=c.useState(!1),s=JSON.stringify({claim:t.claim,hash:t.hash,receipt:t.receipt},null,2),i=new Date(t.claim.auditedAt).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"}),l=()=>{navigator.clipboard.writeText(s).then(()=>{r(!0),setTimeout(()=>r(!1),2500)})};return e.jsxs("div",{role:"group","aria-label":"Wall of Fame badge",style:{marginTop:"var(--v2-pad-5)",padding:"var(--v2-pad-4)",border:"1px solid var(--v2-verified, #15803d)",borderRadius:6,background:"var(--v2-verified-bg, rgba(21,128,61,0.06))",maxWidth:640},children:[e.jsx("p",{style:{margin:0,fontWeight:600,fontSize:13,color:"var(--v2-ink-primary)"},children:"🏆 You earned a Wall of Fame badge"}),e.jsxs("p",{style:{margin:"var(--v2-pad-2) 0 0",fontSize:12,color:"var(--v2-ink-secondary)"},children:["WCAG ",t.claim.wcagLevel," · grade ",t.claim.grade," · ",t.claim.pageCount," page",t.claim.pageCount===1?"":"s"," · audited ",i]}),e.jsxs("p",{style:{margin:"var(--v2-pad-2) 0 0",fontSize:11,lineHeight:1.5,color:"var(--v2-ink-tertiary)"},children:["Submit this signed attestation at ",e.jsx("strong",{children:"accessibilitywatch.org"})," to claim a public, dated, verifiable badge for ",e.jsx("strong",{children:t.claim.domain}),". They verify the signature and confirm you control the domain before it goes live."]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-2)",marginTop:"var(--v2-pad-3)"},children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:l,children:a?"Copied ✓":"Copy attestation"}),e.jsx("span",{role:"status","aria-live":"polite",style:{fontSize:11,color:"var(--v2-verified, #15803d)"},children:a?"Attestation copied to clipboard.":""})]})]})}function Pt(t){const[a,r]=c.useState(null);return c.useEffect(()=>{if(!t){r(null);return}let s=!1;const i=()=>tt({type:"SITE_CLAIM_GET_REQUEST",domain:t}).then(n=>{s||r(n.claim)}).catch(()=>{s||r(null)});i();const l=n=>{typeof n=="object"&&n!==null&&n.type==="SITE_CLAIM_SEALED_EVENT"&&n.domain===t&&i()};return chrome.runtime.onMessage.addListener(l),()=>{s=!0,chrome.runtime.onMessage.removeListener(l)}},[t]),a}function Wt(){const{report:t,resolvedFails:a}=oe(),r=b(p=>p.siteCrawlReport),s=b(p=>p.siteCrawlStatus),i=b(p=>p.siteCrawlError),l=b(p=>p.status),n=s==="running",u=n||l==="running"&&!n,v=!!t&&!r,h=!v&&(t==null?void 0:t.siteGrade)==="A"&&t.startUrl?dt(t.startUrl):null,w=Pt(h),[f,k]=c.useState(null);c.useEffect(()=>{let p=!1;return chrome.tabs.query({active:!0,currentWindow:!0}).then(j=>{var D;p||k(((D=j[0])==null?void 0:D.url)??null)}),()=>{p=!0}},[]);const[y,x]=c.useState(!1),d=b(p=>p.crawlDiscoveryStatus),[S,I]=c.useState(!0),[C,O]=c.useState("");c.useEffect(()=>{T({type:"SETTINGS_GET",key:"crawlReviewEnabled"}).then(p=>{const j=p.data;typeof j=="boolean"&&I(j)})},[]);function $(p){I(p),T({type:"SETTINGS_SET",key:"crawlReviewEnabled",value:p})}function U(p,j=!1){if(p.startUrl){if(S&&!j){O(p.startUrl),b.getState().setSiteCrawlError(null),b.getState().setCrawlDiscoveryStatus("discovering"),Fe({type:"START_CRAWL_DISCOVERY",startUrl:p.startUrl,maxPages:p.maxPages,...p.includeRegex?{includeRegex:p.includeRegex}:{},...p.excludeRegex?{excludeRegex:p.excludeRegex}:{}});return}b.getState().setSiteCrawlStatus("running"),b.getState().setSiteCrawlReport(null),b.getState().setSiteCrawlError(null),le({type:"START_SITE_CRAWL",startUrl:p.startUrl,maxPages:p.maxPages,...p.includeRegex?{includeRegex:p.includeRegex}:{},...p.excludeRegex?{excludeRegex:p.excludeRegex}:{},...j?{verifyFixesOnly:!0}:{}})}}function _(p){p.length!==0&&(b.getState().setSiteCrawlStatus("running"),b.getState().setSiteCrawlReport(null),b.getState().setSiteCrawlError(null),b.getState().resetCrawlDiscovery(),le({type:"START_SITE_CRAWL",startUrl:C,urls:p}))}function A(){le({type:"START_AUDIT",mode:"full-page"}),b.getState().startNewScan()}const[V,m]=c.useState(!1),[z,N]=c.useState(null),[E,M]=c.useState(null);async function F(){m(!0),N(null),M(null);const p=(t==null?void 0:t.siteGrade)??"A";try{const j=await T({type:"REGRADE_SITE_CRAWL"});if((j==null?void 0:j.ok)===!0)setTimeout(()=>{var W;const R=((W=b.getState().siteCrawlReport)==null?void 0:W.siteGrade)??p;M({prevGrade:p,nextGrade:R,at:Date.now()})},0);else{const R=(j==null?void 0:j.reason)??"Regrade failed.";N(R)}}catch(j){N(j instanceof Error?j.message:String(j))}finally{m(!1)}}if(c.useEffect(()=>{if(!E)return;const p=setTimeout(()=>M(null),6e3);return()=>clearTimeout(p)},[E]),u)return e.jsx("section",{"aria-label":"Audit in progress",style:{padding:"var(--v2-pad-5) var(--v2-pad-5)",borderBottom:"1px solid var(--v2-border)"},children:n?e.jsx(ft,{}):e.jsx(bt,{})});if(d==="discovering"||d==="reviewing")return e.jsx("section",{"aria-label":"Choose pages to audit",style:{padding:"var(--v2-pad-5) var(--v2-pad-5)",borderBottom:"1px solid var(--v2-border)",maxWidth:640,margin:"0 auto"},children:d==="discovering"?e.jsx(yt,{}):e.jsx(xt,{onAudit:_})});if(!t)return e.jsxs("section",{"aria-label":"No audit yet",style:{padding:"var(--v2-pad-6) var(--v2-pad-5)",borderBottom:"1px solid var(--v2-border)",maxWidth:640,margin:"0 auto"},children:[e.jsx("p",{className:"v2-eyebrow",style:{marginBottom:"var(--v2-pad-2)"},children:"new audit"}),e.jsx("h1",{className:"v2-display",style:{fontSize:28,fontWeight:500,letterSpacing:"-0.02em",color:"var(--v2-ink-primary)",margin:0,marginBottom:"var(--v2-pad-2)"},children:"Configure your crawl."}),i&&e.jsxs("div",{role:"alert",style:{marginBottom:"var(--v2-pad-4)",padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-critical)",borderRadius:4,background:"rgba(207, 44, 44, 0.06)",color:"var(--v2-critical)",fontSize:12,lineHeight:1.5},children:[e.jsx("strong",{style:{fontWeight:600,marginRight:6},children:"Last crawl failed:"}),i]}),e.jsx("p",{style:{color:"var(--v2-ink-secondary)",margin:0,marginBottom:"var(--v2-pad-5)",maxWidth:520},children:"The crawler follows internal links from the start URL, same-origin only. Each page runs your full audit pipeline (axe + DOM analyzers + AI walkthroughs). Findings appear below as a single unified list."}),e.jsx(ye,{initialUrl:f??"",isRunning:u,onCrawl:p=>U(p,!1),onAuditThisPage:A,reviewEnabled:S,onToggleReview:$})]});const P=a.length,B=(t.totalWalkthroughFindings??0)+t.totalUniqueViolations+P,K=(t.walkthroughAcknowledgements??[]).length,g=t.totalNeedsReview;return e.jsxs("section",{"aria-label":"Audit summary",style:{padding:"var(--v2-pad-6) var(--v2-pad-5)",borderBottom:"1px solid var(--v2-border)"},children:[e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"var(--v2-pad-6)"},children:[e.jsx(Lt,{grade:t.siteGrade}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",gap:"var(--v2-pad-3)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0},children:v?"page grade · single-page audit":`site grade · ${t.pagesAudited} page${t.pagesAudited===1?"":"s"}`}),e.jsxs("p",{style:{margin:0,fontSize:11,lineHeight:1.4,color:"var(--v2-ink-tertiary)"},children:["Your ",e.jsx("strong",{children:"combined grade"})," — severity (your most serious finding) and breadth (how many of the 9 areas have issues) together, with a legal floor so a serious issue can't be averaged away. The Dev view shows the same letter."]}),e.jsx("h1",{className:"v2-display",style:{fontSize:22,fontWeight:500,letterSpacing:"-0.01em",color:"var(--v2-ink-primary)",margin:0,lineHeight:1.25},children:(()=>{var D;const p=B+g,j=((D=t.blockingCriteria)==null?void 0:D.length)??0;return p===0&&j===0?"All clear — nothing open.":p===0&&j>0?`Visible findings clear — ${j} criteri${j===1?"on":"a"} still need${j===1?"s":""} your judgment.`:`${p} finding${p===1?"":"s"} to address.`})()}),e.jsx(Ot,{openCount:B,reviewCount:g,verifiedCount:K,axeCount:t.totalUniqueViolations,walkthroughCount:t.totalWalkthroughFindings??0,autoCount:P}),f&&!Ft(f,t.startUrl)&&e.jsxs("p",{className:"v2-mono",style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",wordBreak:"break-all"},children:["Active tab: ",f]}),e.jsxs("div",{style:{display:"flex",gap:"var(--v2-pad-2)",marginTop:"var(--v2-pad-2)",flexWrap:"wrap"},children:[v?e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary",onClick:A,title:"Re-audit the current page",children:"Re-audit this page"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:()=>x(p=>!p),"aria-expanded":y,title:"Open crawl setup to audit the whole site instead",children:y?"Hide crawl options":"Crawl whole site"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary",onClick:F,disabled:V,title:"Re-aggregate this audit against your latest verdicts + acks. No re-crawl. Use this after marking criteria in the Coverage gaps panel.",children:V?"Regrading…":"Regrade"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:()=>U({startUrl:t.startUrl,maxPages:25,includeRegex:"",excludeRegex:""},!1),title:`Re-crawl ${t.startUrl} (same options) — full audit re-run, use when page code changed`,children:"Re-crawl"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:A,title:"Single-page audit of the active tab (no crawl)",children:"Just this page"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:()=>U({startUrl:t.startUrl,maxPages:25,includeRegex:"",excludeRegex:""},!0),title:"Skip walkthroughs that previously passed or were human-verified",children:"Verify fixes only"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost",onClick:()=>x(p=>!p),"aria-expanded":y,children:y?"Hide options":"Adjust options"})]}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>void We(),title:"Wipe these results so you can start fresh",style:{marginLeft:"auto"},children:"Clear results"})]}),z&&e.jsx("p",{role:"alert",style:{margin:"var(--v2-pad-2) 0 0",fontSize:11,color:"var(--v2-critical)"},children:z}),E&&!z&&e.jsx("p",{role:"status",style:{margin:"var(--v2-pad-2) 0 0",fontSize:11,color:"var(--v2-verified)"},children:E.prevGrade===E.nextGrade?`Regraded — grade unchanged at ${E.nextGrade}. Any verdict changes you made were already in this report.`:`Regraded — grade ${E.prevGrade} → ${E.nextGrade}.`})]})]}),(w==null?void 0:w.receipt)&&e.jsx(Dt,{sealed:w}),e.jsx(Nt,{}),y&&e.jsx("div",{style:{marginTop:"var(--v2-pad-5)",paddingTop:"var(--v2-pad-4)",borderTop:"1px solid var(--v2-border)",maxWidth:640},children:e.jsx(ye,{initialUrl:t.startUrl,isRunning:u,onCrawl:p=>U(p,!1),onVerifyFixes:p=>U(p,!0),onAuditThisPage:A,reviewEnabled:S,onToggleReview:$})})]})}function Ft(t,a){try{return new URL(t).origin===new URL(a).origin}catch{return!1}}function Lt({grade:t}){const a={A:"var(--v2-grade-a)",B:"var(--v2-grade-b)",C:"var(--v2-grade-c)",D:"var(--v2-grade-d)",F:"var(--v2-grade-f)"};return e.jsx("div",{"aria-label":`Grade ${t}`,role:"img",style:{display:"flex",alignItems:"center",justifyContent:"center",minWidth:140},children:e.jsx("span",{className:"v2-display",style:{fontSize:132,lineHeight:1,fontWeight:500,color:a[t],letterSpacing:"-0.04em",fontVariationSettings:'"opsz" 144'},children:t})})}function Ot({openCount:t,reviewCount:a,verifiedCount:r,axeCount:s,walkthroughCount:i,autoCount:l}){return e.jsxs("dl",{style:{display:"flex",gap:"var(--v2-pad-4)",flexWrap:"wrap",margin:0,color:"var(--v2-ink-secondary)",fontSize:12},children:[e.jsx(Y,{term:"open",value:t,tone:t>0?"attention":"neutral"}),e.jsx(Y,{term:"review",value:a,tone:a>0?"review":"neutral"}),e.jsx(Y,{term:"verified",value:r,tone:r>0?"positive":"neutral"}),e.jsx("span",{style:{color:"var(--v2-ink-faint)"},children:"·"}),e.jsx(Y,{term:"axe",value:s,tone:"neutral"}),e.jsx(Y,{term:"walkthrough",value:i,tone:"neutral"}),l>0&&e.jsx(Y,{term:"auto-contrast",value:l,tone:"neutral"})]})}function Y({term:t,value:a,tone:r}){const s={attention:"var(--v2-critical)",review:"var(--v2-needs-review)",positive:"var(--v2-verified)",neutral:"var(--v2-ink-secondary)"};return e.jsxs("div",{style:{display:"inline-flex",alignItems:"baseline",gap:6},children:[e.jsx("dt",{className:"v2-eyebrow",style:{display:"inline",margin:0,color:"var(--v2-ink-tertiary)"},children:t}),e.jsx("dd",{className:"v2-mono",style:{margin:0,fontWeight:600,fontSize:13,color:s[r],fontVariantNumeric:"tabular-nums"},children:a})]})}const $t=new Set(["2.4.3","2.1.2","2.4.7","1.3.2","1.4.11","2.5.3"]);function we(t){return $t.has(t)}async function Se(t){var s,i;const a=b.getState();if(a.componentId&&((s=a.results[0])==null?void 0:s.pageUrl)===t)return a.componentId;const r=await Re();return((i=r==null?void 0:r.find(l=>l.url===t))==null?void 0:i.componentId)??null}async function _t(t,a){var l;const r=b.getState(),s=[];if(r.componentId&&r.results.length>0){const n=(l=r.results[0])==null?void 0:l.pageUrl,o=a.find(u=>u.url===n);if(o){for(const u of r.results)for(const v of u.violations)v.ruleId===t&&v.target.selector===o.selector&&s.push({componentId:r.componentId,matchKey:v.matchKey});if(s.length>0)return s}}const i=await Re()??[];for(const n of a){const o=i.find(u=>u.url===n.url);if(o)for(const u of o.results)for(const v of u.violations)v.ruleId===t&&v.target.selector===n.selector&&s.push({componentId:o.componentId,matchKey:v.matchKey})}return s}function Ht({row:t}){return e.jsxs("details",{style:{background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:6,overflow:"hidden"},children:[e.jsxs("summary",{style:{cursor:"pointer",padding:"var(--v2-pad-3) var(--v2-pad-4)",listStyle:"none",display:"flex",alignItems:"flex-start",gap:"var(--v2-pad-3)"},children:[e.jsx(Gt,{row:t}),e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx(Mt,{row:t}),e.jsx(Bt,{row:t})]}),e.jsx(Vt,{})]}),e.jsx("div",{style:{padding:"0 var(--v2-pad-4) var(--v2-pad-4)",borderTop:"1px solid var(--v2-border)"},children:e.jsx(Kt,{row:t})})]})}function Gt({row:t}){if(t.kind==="walkthrough-ack")return e.jsx("span",{className:"v2-chip v2-chip-verified","aria-label":"Status: human verified",children:"verified"});if(t.kind==="needs-review")return e.jsx("span",{className:"v2-chip v2-chip-review","aria-label":"Status: needs human review",children:"review"});if(t.kind==="auto-contrast")return e.jsx("span",{className:"v2-chip v2-chip-serious","aria-label":"Severity: serious, auto-resolved by pixel sampler",title:"Empirical pixel-contrast measurement, not an axe-confirmed violation. Human verification recommended.",children:"auto · serious"});if(t.kind==="walkthrough-fail")return e.jsx("span",{className:t.verdict==="fail"?"v2-chip v2-chip-serious":"v2-chip v2-chip-moderate","aria-label":`Severity: ${t.verdict}`,children:t.verdict});const a={critical:"v2-chip-critical",serious:"v2-chip-serious",moderate:"v2-chip-moderate",minor:"v2-chip-minor"};return e.jsx("span",{className:`v2-chip ${a[t.impact]}`,"aria-label":`Severity: ${t.impact}`,children:t.impact})}function Mt({row:t}){const a=t.kind==="walkthrough-fail"||t.kind==="walkthrough-ack"||t.kind==="needs-review"||t.kind==="axe"||t.kind==="auto-contrast"?t.criterion:null,r=t.kind==="walkthrough-fail"?`AI walkthrough ${t.verdict} on this criterion.`:t.kind==="walkthrough-ack"?"Human-verified by an auditor.":t.kind==="needs-review"?t.description:t.kind==="auto-contrast"?"Empirical contrast measurement fell below threshold.":t.description;return e.jsxs("p",{style:{margin:0,marginBottom:4,color:"var(--v2-ink-primary)",fontSize:13,fontWeight:500,lineHeight:1.4},children:[a&&e.jsxs("span",{className:"v2-mono",style:{fontSize:11,fontWeight:600,color:"var(--v2-ink-tertiary)",marginRight:8},children:["WCAG ",a]}),r]})}function Bt({row:t}){const a=t.kind==="axe"||t.kind==="needs-review"?t.pages.length:1,r=t.kind==="axe"||t.kind==="needs-review"||t.kind==="auto-contrast"?t.selector:null,s=t.kind==="walkthrough-fail"||t.kind==="walkthrough-ack"||t.kind==="auto-contrast"?t.pageUrl:null;return e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--v2-pad-2)",flexWrap:"wrap"},children:[r&&e.jsx("code",{className:"v2-mono",style:{fontSize:11,color:"var(--v2-ink-secondary)",background:"var(--v2-bg-elev-2)",padding:"2px 6px",borderRadius:2,wordBreak:"break-all"},children:r}),s&&e.jsx("span",{className:"v2-mono",style:{fontSize:11,color:"var(--v2-ink-tertiary)",wordBreak:"break-all"},children:s}),a>1&&e.jsxs("span",{className:"v2-eyebrow",style:{marginLeft:"auto"},children:["on ",a," pages"]})]})}function Vt(){return e.jsx("span",{"aria-hidden":"true",style:{color:"var(--v2-ink-tertiary)",fontFamily:"var(--v2-mono)",fontSize:12,marginLeft:8,marginTop:2},children:"⏵"})}function Kt({row:t}){return t.kind==="walkthrough-fail"?e.jsx(Yt,{row:t}):t.kind==="walkthrough-ack"?e.jsx(Zt,{row:t}):t.kind==="needs-review"?e.jsx(Qt,{row:t}):t.kind==="auto-contrast"?e.jsx(qt,{row:t}):e.jsx(Jt,{row:t})}function qt({row:t}){const[a,r]=c.useState(!1),[s,i]=c.useState(!1),[l,n]=c.useState(""),[o,u]=c.useState(!1),[v,h]=c.useState(!1),[w,f]=c.useState(null),k=Ae(t.ruleId);async function y(){if(u(!0),f(null),!l.trim()){f("Note is required — explain why the empirical contrast measurement is wrong, or why this element is acceptable in context."),u(!1);return}try{const d=(await Ce(t.pageUrl)).find(I=>I.ruleId===t.ruleId&&I.selector===t.selector),S={pageUrl:t.pageUrl,ruleId:t.ruleId,selector:t.selector,verdict:"pass",reasoning:`Human override: ${l.trim()}
|
|
3
|
-
|
|
4
|
-
(Original empirical reasoning: ${t.reasoning})`,resolvedAt:new Date().toISOString(),costUsd:0,wcagCriterion:t.criterion,inputHash:d==null?void 0:d.inputHash};await pt(S),h(!0),r(!1)}catch(x){f(x instanceof Error?x.message:String(x))}finally{u(!1)}}return e.jsxs("div",{style:{paddingTop:"var(--v2-pad-3)"},children:[e.jsx(te,{label:"Empirical measurement",children:e.jsx("p",{style:{margin:0,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.6,whiteSpace:"pre-wrap"},children:t.reasoning})}),e.jsx("p",{style:{margin:0,marginBottom:"var(--v2-pad-3)",fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5,fontStyle:"italic"},children:"This finding came from a pixel-level screenshot diff of text against the rendered background, not from axe-core. Treat as a strong hint for human review, not a confirmed violation — gradients, translucent overlays, and animated backdrops can fool the sampler."}),v?e.jsx(ue,{}):e.jsxs(e.Fragment,{children:[e.jsxs(pe,{children:[k&&e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>i(x=>!x),"aria-expanded":s,children:s?"Hide fix recipe":"Show fix recipe"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:()=>r(x=>!x),"aria-expanded":a,children:a?"Cancel":"Mark verified manually"})]}),s&&k&&e.jsx(Ne,{summary:k.summary,snippet:k.snippet}),a&&e.jsx(de,{note:l,setNote:n,busy:o,err:w,onConfirm:y,hint:"Why the empirical measurement is wrong, or why this is acceptable. Overrides the resolution to pass.",placeholder:"e.g., Text sits over a video poster image; static screenshot misreads the rendered background. Production poster passes 7:1."}),w&&!a&&e.jsx(se,{message:w})]})]})}function Yt({row:t}){const[a,r]=c.useState(!1),[s,i]=c.useState(""),[l,n]=c.useState(!1),[o,u]=c.useState(!1),[v,h]=c.useState(!1),[w,f]=c.useState(null),[k,y]=c.useState(null),x=we(t.criterion),d=Le();async function S(){if(n(!0),y(null),!s.trim()){y("Note is required — explain how you manually verified this."),n(!1);return}try{const C=await Se(t.pageUrl);if(!C){y("Could not find this page in the audit data. Re-run the audit and try again.");return}await ut({componentId:C,criterionId:t.criterion,pageUrl:t.pageUrl,note:s.trim(),acknowledgedAt:new Date().toISOString(),verdictAtAck:t.verdict}),u(!0),r(!1)}catch(C){y(C instanceof Error?C.message:String(C))}finally{n(!1)}}async function I(){var C;h(!0),f(null),y(null);try{const $=(C=(await chrome.tabs.query({active:!0,currentWindow:!0}))[0])==null?void 0:C.id;if(!$){y("Open the audited page in your active tab to re-run.");return}const U=await Se(t.pageUrl);if(!U){y("Could not find this page in the audit data.");return}if(!we(t.criterion)){y(`Re-run is only available for interactive criteria. ${t.criterion} is not supported.`);return}const A=await T({type:"INTERACTIVE_AUDIT_REQUEST",criterionId:t.criterion,tabId:$,componentId:U,pageUrl:t.pageUrl});if(!A.ok){y(A.error??"Re-run failed.");return}f(`Re-run verdict: ${A.verdict??"unknown"}. Re-audit the page to refresh this list.`)}catch(O){y(O instanceof Error?O.message:String(O))}finally{h(!1)}}return e.jsxs("div",{style:{paddingTop:"var(--v2-pad-3)"},children:[e.jsx(te,{label:"AI reasoning",children:e.jsx("p",{style:{margin:0,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.6},children:t.reasoning})}),o?e.jsx(ue,{}):e.jsxs(e.Fragment,{children:[e.jsxs(pe,{children:[x&&e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:I,disabled:v||!d,title:d?void 0:"AI walkthroughs need an Anthropic API key. Add one in Settings → AI.",children:v?"Re-running…":"Re-run walkthrough"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:()=>r(C=>!C),"aria-expanded":a,children:a?"Cancel":"Mark verified manually"})]}),w&&e.jsx("p",{role:"status",style:{marginTop:"var(--v2-pad-2)",padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"rgba(15, 143, 94, 0.08)",border:"1px solid var(--v2-verified)",borderRadius:4,color:"var(--v2-verified)",fontSize:11,lineHeight:1.5},children:w}),a&&e.jsx(de,{note:s,setNote:i,busy:l,err:k,onConfirm:S,hint:"Explain what you checked. This goes into the forensic record.",placeholder:"e.g., Verified — focus indicator visible on every interactive control under :focus-visible; tested with keyboard nav."}),k&&!a&&e.jsx(se,{message:k})]})]})}function Zt({row:t}){return e.jsxs("div",{style:{paddingTop:"var(--v2-pad-3)"},children:[e.jsx(te,{label:"What the human verified",children:e.jsx("p",{style:{margin:0,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.6},children:t.reasoning})}),e.jsxs("p",{style:{color:"var(--v2-ink-tertiary)",fontSize:11,margin:0,marginTop:"var(--v2-pad-2)"},children:["Original AI verdict: ",e.jsx("strong",{children:t.verdict}),". Now treated as pass for conformance."]})]})}function Qt({row:t}){return e.jsx(Ee,{row:t,kind:"needs-review"})}function Jt({row:t}){return e.jsx(Ee,{row:t,kind:"axe"})}function Ee({row:t,kind:a}){const[r,s]=c.useState(!1),[i,l]=c.useState(""),[n,o]=c.useState(!1),[u,v]=c.useState(!1),[h,w]=c.useState(!1),[f,k]=c.useState(null),y=Ae(t.ruleId);async function x(){if(o(!0),k(null),!i.trim()){k(a==="needs-review"?"Note is required — explain your review judgment.":"Note is required — explain why this isn't actually an issue in your context."),o(!1);return}try{const d=await _t(t.ruleId,t.pages);if(d.length===0){k("Could not find this finding in the persisted audit data. Re-run the audit and try again.");return}for(const S of d)await vt({componentId:S.componentId,matchKey:S.matchKey,ruleId:t.ruleId,note:i.trim()});v(!0),s(!1)}catch(d){k(d instanceof Error?d.message:String(d))}finally{o(!1)}}return e.jsxs("div",{style:{paddingTop:"var(--v2-pad-3)"},children:[a==="needs-review"&&t.failureSummary&&e.jsx(te,{label:"AI assessment",children:e.jsx("p",{style:{margin:0,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.6,whiteSpace:"pre-wrap"},children:t.failureSummary})}),e.jsx(te,{label:"Affected",children:e.jsxs("ul",{style:{margin:0,padding:0,listStyle:"none",display:"flex",flexDirection:"column",gap:4},children:[t.pages.slice(0,8).map(d=>e.jsx("li",{children:e.jsx("a",{href:d.url,target:"_blank",rel:"noopener noreferrer",className:"v2-mono",style:{fontSize:11,color:"var(--v2-ink-secondary)",textDecoration:"underline",textDecorationColor:"var(--v2-ink-faint)",textUnderlineOffset:2},children:d.url})},d.url)),t.pages.length>8&&e.jsxs("li",{className:"v2-eyebrow",children:["+ ",t.pages.length-8," more"]})]})}),u?e.jsx(ue,{}):e.jsxs(e.Fragment,{children:[e.jsxs(pe,{children:[a==="axe"&&y&&e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>w(d=>!d),"aria-expanded":h,children:h?"Hide fix recipe":"Show fix recipe"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:()=>s(d=>!d),"aria-expanded":r,children:r?"Cancel":"Mark verified manually"})]}),h&&y&&e.jsx(Ne,{summary:y.summary,snippet:y.snippet}),r&&e.jsx(de,{note:i,setNote:l,busy:n,err:f,onConfirm:x,hint:a==="needs-review"?"Your review judgment. Goes into the forensic record.":"Why this isn't actually an issue in your context. Goes into the forensic record.",placeholder:a==="needs-review"?"e.g., Verified — image is a portrait of the named founder; alt text correctly identifies subject and role.":'e.g., This element is decorative; aria-hidden + role="presentation" applied via design system.',confirmLabel:`Confirm — acknowledge on ${t.pages.length} page${t.pages.length===1?"":"s"}`}),f&&!r&&e.jsx(se,{message:f})]})]})}function de({note:t,setNote:a,busy:r,err:s,onConfirm:i,hint:l,placeholder:n,confirmLabel:o="Confirm acknowledgement"}){return e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)",padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-border-strong)",borderRadius:4,background:"var(--v2-bg)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,marginBottom:6},children:"verification note · required"}),e.jsx("p",{style:{margin:0,marginBottom:"var(--v2-pad-2)",fontSize:11,color:"var(--v2-ink-tertiary)"},children:l}),e.jsx("textarea",{value:t,onChange:u=>a(u.target.value),placeholder:n,rows:3,style:{width:"100%",fontFamily:"var(--v2-body)",fontSize:12,lineHeight:1.5,padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"var(--v2-bg)",color:"var(--v2-ink-primary)",border:"1px solid var(--v2-border-strong)",borderRadius:4,resize:"vertical",minHeight:70},autoFocus:!0}),s&&e.jsx(se,{message:s}),e.jsx("div",{style:{marginTop:"var(--v2-pad-2)"},children:e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:i,disabled:r||!t.trim(),children:r?"Saving…":o})})]})}function Ne({summary:t,snippet:a}){return e.jsxs("div",{style:{marginTop:"var(--v2-pad-3)",padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-verified)",borderRadius:4,background:"rgba(15, 143, 94, 0.06)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,marginBottom:6,color:"var(--v2-verified)"},children:"how to fix"}),e.jsx("p",{style:{margin:0,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.6},children:t}),a&&e.jsx("pre",{className:"v2-mono",style:{marginTop:"var(--v2-pad-2)",marginBottom:0,padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"var(--v2-bg)",border:"1px solid var(--v2-border)",borderRadius:3,fontSize:11,color:"var(--v2-ink-primary)",overflowX:"auto",whiteSpace:"pre"},children:e.jsx("code",{children:a})})]})}function ue(){return e.jsxs("div",{role:"status",style:{marginTop:"var(--v2-pad-2)",padding:"var(--v2-pad-2) var(--v2-pad-3)",background:"rgba(15, 143, 94, 0.08)",border:"1px solid var(--v2-verified)",borderRadius:4,color:"var(--v2-verified)",fontSize:12,lineHeight:1.5},children:[e.jsx("strong",{style:{fontWeight:600},children:"✓ Acknowledged."})," ","The ack is saved. Re-audit or re-crawl to see this finding drop out of the list."]})}function se({message:t}){return e.jsx("p",{role:"alert",style:{marginTop:"var(--v2-pad-2)",marginBottom:0,padding:"var(--v2-pad-2) var(--v2-pad-3)",border:"1px solid var(--v2-critical)",background:"rgba(207, 44, 44, 0.06)",borderRadius:4,color:"var(--v2-critical)",fontSize:11,lineHeight:1.4},children:t})}function te({label:t,children:a}){return e.jsxs("div",{style:{marginBottom:"var(--v2-pad-3)"},children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,marginBottom:6},children:t}),a]})}function pe({children:t}){return e.jsx("div",{style:{display:"flex",gap:"var(--v2-pad-2)",flexWrap:"wrap",marginTop:"var(--v2-pad-2)"},children:t})}function Xt(){const{report:t,resolvedFails:a}=oe(),[r,s]=c.useState("open"),i=c.useMemo(()=>t?rr(t.pages,t.findingGroups??[],a):[],[t,a]),l=c.useMemo(()=>r==="all"?i:i.filter(o=>r==="verified"?o.kind==="walkthrough-ack":r==="review"?o.kind==="needs-review":r==="open"?o.kind==="axe"||o.kind==="walkthrough-fail"||o.kind==="auto-contrast":!0),[i,r]);if(!t)return null;const n={all:i.length,open:i.filter(o=>o.kind==="axe"||o.kind==="walkthrough-fail"||o.kind==="auto-contrast").length,review:i.filter(o=>o.kind==="needs-review").length,verified:i.filter(o=>o.kind==="walkthrough-ack").length};return e.jsxs("section",{"aria-labelledby":"findings-heading",style:{padding:"var(--v2-pad-5) var(--v2-pad-5) var(--v2-pad-7)"},children:[e.jsxs("header",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--v2-pad-3)",marginBottom:"var(--v2-pad-4)",flexWrap:"wrap"},children:[e.jsx("h2",{id:"findings-heading",className:"v2-display",style:{fontSize:20,fontWeight:500,letterSpacing:"-0.01em",color:"var(--v2-ink-primary)",margin:0},children:"Findings"}),e.jsx(er,{filter:r,setFilter:s,counts:n})]}),l.length===0?e.jsx(tr,{filter:r}):e.jsx("ul",{"aria-label":`${r} findings, ${l.length} items`,style:{listStyle:"none",padding:0,margin:0,display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:l.map((o,u)=>e.jsx("li",{style:{animation:`v2-row-in 240ms ease ${Math.min(u,12)*30}ms both`},children:e.jsx(Ht,{row:o})},o.key))})]})}function er({filter:t,setFilter:a,counts:r}){const s=[{id:"open",label:"Open"},{id:"review",label:"Review"},{id:"verified",label:"Verified"},{id:"all",label:"All"}];return e.jsx("div",{role:"tablist","aria-label":"Filter findings",style:{display:"inline-flex",gap:4,background:"var(--v2-bg-elev)",padding:3,borderRadius:6,border:"1px solid var(--v2-border)"},children:s.map(i=>{const l=t===i.id;return e.jsxs("button",{type:"button",role:"tab","aria-selected":l,onClick:()=>a(i.id),style:{fontFamily:"var(--v2-body)",fontSize:11,padding:"5px 10px",borderRadius:4,border:"none",cursor:"pointer",background:l?"var(--v2-bg-elev-2)":"transparent",color:l?"var(--v2-ink-primary)":"var(--v2-ink-secondary)",fontWeight:l?600:500,transition:"background 120ms ease, color 120ms ease",display:"inline-flex",alignItems:"baseline",gap:5},children:[i.label,e.jsx("span",{className:"v2-mono",style:{fontSize:10,color:"var(--v2-ink-tertiary)",fontVariantNumeric:"tabular-nums"},children:r[i.id]})]},i.id)})})}function tr({filter:t}){const r={open:{headline:"Nothing open.",sub:"No axe violations or AI walkthrough failures across the audited pages. Switch to All to see everything, or to Verified for a record of acknowledged items."},review:{headline:"No items awaiting review.",sub:"AI walkthroughs returned definitive verdicts (or human verifications) for every criterion that needed judgment."},verified:{headline:"No human verifications recorded.",sub:"When you mark a walkthrough finding as manually verified, it appears here with your note + timestamp."},all:{headline:"Nothing to show.",sub:"No audit data yet — run a scan to begin."}}[t];return e.jsxs("div",{role:"status","aria-live":"polite",style:{padding:"var(--v2-pad-6) var(--v2-pad-4)",textAlign:"center",border:"1px dashed var(--v2-border)",borderRadius:6},children:[e.jsx("p",{className:"v2-display",style:{fontSize:18,fontWeight:500,color:"var(--v2-ink-primary)",margin:0,marginBottom:"var(--v2-pad-2)"},children:r.headline}),e.jsx("p",{style:{color:"var(--v2-ink-secondary)",margin:0,maxWidth:440,marginInline:"auto"},children:r.sub})]})}function rr(t,a,r=[]){const s=[];for(const n of a)n.needsReview?s.push({kind:"needs-review",key:`nr::${n.ruleId}::${n.representativeSelector}`,criterion:n.wcagCriterion,ruleId:n.ruleId,description:n.axeDescription,selector:n.representativeSelector,failureSummary:n.failureSummary,pages:n.pages,group:n}):s.push({kind:"axe",key:`axe::${n.ruleId}::${n.representativeSelector}`,criterion:n.wcagCriterion,ruleId:n.ruleId,impact:n.impact,description:n.axeDescription,selector:n.representativeSelector,pages:n.pages,isShared:n.isShared});const i=new Set;for(const n of t){for(const o of n.walkthroughFindings??[]){const u=`wt-fail::${o.criterionId}::${o.pageUrl}`;i.has(u)||(i.add(u),s.push({kind:"walkthrough-fail",key:u,criterion:o.criterionId,verdict:o.verdict,impact:o.impact,reasoning:o.reasoning,pageUrl:o.pageUrl}))}for(const o of n.walkthroughAcknowledgements??[]){const u=`wt-ack::${o.criterionId}::${o.pageUrl}`;i.has(u)||(i.add(u),s.push({kind:"walkthrough-ack",key:u,criterion:o.criterionId,verdict:o.verdict,reasoning:o.reasoning,pageUrl:o.pageUrl}))}}for(const n of r)s.push({kind:"auto-contrast",key:`auto::${n.ruleId}::${n.selector}::${n.pageUrl}`,criterion:n.wcagCriterion??"1.4.3",ruleId:n.ruleId,impact:"serious",selector:n.selector,pageUrl:n.pageUrl,reasoning:n.reasoning});const l={critical:0,serious:1,moderate:2,minor:3,"needs-review":4,ack:5};return s.sort((n,o)=>{const u=n.kind==="walkthrough-ack"?l.ack:n.kind==="needs-review"?l["needs-review"]:l[n.impact],v=o.kind==="walkthrough-ack"?l.ack:o.kind==="needs-review"?l["needs-review"]:l[o.impact];return(u??99)-(v??99)}),s}function ar({open:t,onClose:a}){const{report:r}=oe(),s=b(m=>m.siteCrawlReport),i=b(m=>m.results),l=b(m=>m.componentId),n=b(m=>m.delta),o=!!s,u=o||i.length>0,v=b(m=>m.tier),h=m=>!Oe(v,m),[w,f]=c.useState(!1),k=()=>f(!0),y=o?"ai-prompt-site-crawl":"ai-prompt",x=Ie({storeComponentId:l,storeCrawlReport:s,pageUrls:(r==null?void 0:r.pages.map(m=>m.url))??[]}),[d,S]=c.useState({}),I=c.useRef(null);c.useEffect(()=>{var z;if(!t)return;const m=N=>{N.key==="Escape"&&a()};return document.addEventListener("keydown",m),(z=I.current)==null||z.focus(),()=>document.removeEventListener("keydown",m)},[t,a]);function C(m,z){S(N=>({...N,[m]:z}))}async function O(){C("ai-prompt",{state:"busy"});try{if(o){const m=await T({type:"EXPORT_REQUEST",format:"ai-prompt-site-crawl",results:[],...r?{siteCrawlReport:r}:{}});if(!(m!=null&&m.content))throw new Error("Empty response");await navigator.clipboard.writeText(m.content),await ne(m.content,"ai-fixer-prompt.md","text/markdown"),C("ai-prompt",{state:"done",message:"Copied to clipboard + opened in a new tab."})}else{if(!i.length)throw new Error("No audit results yet");await mt({results:i,componentId:l??null,delta:n}),C("ai-prompt",{state:"done",message:"Copied to clipboard + opened in a new tab."})}}catch(m){C("ai-prompt",{state:"error",message:m instanceof Error?m.message:String(m)})}}async function $(){C("html",{state:"busy"});try{if(o&&r){const{renderSiteReportHtml:m}=await re(async()=>{const{renderSiteReportHtml:N}=await import("./site-report-renderer-klOJEyJa.js");return{renderSiteReportHtml:N}},__vite__mapDeps([0,1,2,3,4,5])),z=m(r);await ne(z,"site-report.html","text/html"),C("html",{state:"done",message:"Opened in a new tab — Save as PDF or use Cmd/Ctrl+S."})}else{if(!i.length)throw new Error("No audit results yet");const{toHtmlPrint:m}=await re(async()=>{const{toHtmlPrint:N}=await import("./scheduled-audit-runner-Cad1yq0z.js").then(E=>E.aW);return{toHtmlPrint:N}},__vite__mapDeps([1,2,3,4,5])),z=m(i,n??void 0);await ne(z,"page-report.html","text/html"),C("html",{state:"done",message:"Opened in a new tab — Save as PDF or use Cmd/Ctrl+S."})}}catch(m){C("html",{state:"error",message:m instanceof Error?m.message:String(m)})}}async function U(m,z,N){C(m,{state:"busy"});try{const E=await T({type:"EXPORT_REQUEST",format:m,results:o?[]:i,...n&&!o?{delta:n}:{},...o?{siteCrawlSource:!0}:{},...x?{auditTargetId:x}:{}});if(!(E!=null&&E.content))throw new Error("Empty response");await ne(E.content,N,"text/html"),C(m,{state:"done",message:`${z} opened in a new tab.`})}catch(E){C(m,{state:"error",message:E instanceof Error?E.message:String(E)})}}async function _(){const{createZip:m}=await re(async()=>{const{createZip:P}=await import("./zip-encoder-CtULHXx_.js");return{createZip:P}},[]),{renderSiteReportHtml:z}=await re(async()=>{const{renderSiteReportHtml:P}=await import("./site-report-renderer-klOJEyJa.js");return{renderSiteReportHtml:P}},__vite__mapDeps([0,1,2,3,4,5])),N=[],E=o?[{format:"ai-prompt-site-crawl",filename:"ai-fixer-prompt.md"},{format:"defense-bundle",filename:"defense-bundle.html"},{format:"deposition-packet",filename:"deposition-packet.html"},{format:"evidence-bundle",filename:"evidence-bundle.html"},{format:"vpat",filename:"vpat.html"},{format:"conformance-crosswalk",filename:"conformance-crosswalk.html"},{format:"methodology-doc",filename:"methodology-doc.html"},{format:"executive-report",filename:"executive-report.html"}]:[{format:"ai-prompt",filename:"ai-fixer-prompt.md"},{format:"html-print",filename:"page-report.html"}],M=E.length+(o&&r?1:0);let F=0;C("zip",{state:"busy",progress:{current:0,total:M,label:"Starting…"}});try{if(o&&r){F++,C("zip",{state:"busy",progress:{current:F,total:M,label:"site-report.html (client-side)"}});try{N.push({name:"site-report.html",content:z(r)})}catch{}}for(const{format:p,filename:j}of E){F++,C("zip",{state:"busy",progress:{current:F,total:M,label:j}});try{const D=await T({type:"EXPORT_REQUEST",format:p,results:o?[]:i,...n&&!o?{delta:n}:{},...o?{siteCrawlSource:!0}:{},...x?{auditTargetId:x}:{}});D!=null&&D.content&&N.push({name:j,content:D.content})}catch{}}if(N.length===0)throw new Error("All exports failed");const P=m(N),B=new Blob([P],{type:"application/zip"}),K=URL.createObjectURL(B),g=document.createElement("a");g.href=K,g.download=o?"wcagcheckr-site-bundle.zip":"wcagcheckr-page-bundle.zip",g.click(),setTimeout(()=>URL.revokeObjectURL(K),6e4),C("zip",{state:"done",message:`Downloaded ${N.length} file${N.length===1?"":"s"}.`})}catch(P){C("zip",{state:"error",message:P instanceof Error?P.message:String(P)})}}function A(m){b.getState().setView(m),b.getState().setUserMode("dev"),T({type:"SETTINGS_SET",key:"userMode",value:"dev"}),a()}function V(){T({type:"OPEN_SETTINGS"})}return t?e.jsxs("div",{role:"dialog","aria-modal":"true","aria-label":"Tools and exports",style:{position:"fixed",inset:0,zIndex:50,display:"flex"},children:[e.jsx("div",{onClick:a,style:{position:"absolute",inset:0,background:"rgba(26, 20, 16, 0.35)",backdropFilter:"blur(2px)"},"aria-hidden":"true"}),e.jsxs("div",{style:{position:"relative",marginLeft:"auto",width:"min(100%, 440px)",height:"100%",background:"var(--v2-bg)",borderLeft:"1px solid var(--v2-border-strong)",boxShadow:"-12px 0 28px rgba(26, 20, 16, 0.18)",overflowY:"auto",display:"flex",flexDirection:"column"},children:[e.jsxs("div",{style:{position:"sticky",top:0,background:"var(--v2-bg)",borderBottom:"1px solid var(--v2-border)",padding:"var(--v2-pad-4) var(--v2-pad-5)",display:"flex",alignItems:"center",justifyContent:"space-between",zIndex:1},children:[e.jsx("h2",{className:"v2-display",style:{margin:0,fontSize:18,fontWeight:500,color:"var(--v2-ink-primary)"},children:"Tools"}),e.jsx("button",{ref:I,type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:a,"aria-label":"Close tools drawer",children:"Close"})]}),e.jsxs("div",{style:{padding:"var(--v2-pad-5)",display:"flex",flexDirection:"column",gap:"var(--v2-pad-5)"},children:[!u&&e.jsx("p",{style:{margin:0,padding:"var(--v2-pad-3) var(--v2-pad-4)",background:"var(--v2-bg-elev)",border:"1px solid var(--v2-border)",borderRadius:4,color:"var(--v2-ink-secondary)",fontSize:12,lineHeight:1.5},children:"Most tools need an audit to act on. Run an audit first, then come back here."}),u&&e.jsxs(e.Fragment,{children:[e.jsx(Z,{title:"AI fixer",children:e.jsx(G,{status:d["ai-prompt"],label:o?"Copy site-wide AI fix prompt":"Copy AI fix prompt",description:o?"Multi-page markdown for ChatGPT/Claude/Copilot. Site-wide summary, consistency findings, per-page violations + fix recipes.":"Markdown for ChatGPT/Claude/Copilot. Every violation with fix recipes, AI-resolved fails, acknowledged context.",onClick:O,locked:h(y),onUpgrade:k})}),e.jsxs(Z,{title:"Reports",children:[e.jsx(G,{status:d.html,label:o?"Site report (HTML)":"Page report (HTML)",description:o?"Full crawl summary with per-page grades, top violations, consistency findings. Print-ready.":"Print-friendly single-page report.",onClick:$}),e.jsx(G,{status:d["executive-report"],label:"Executive report",description:"Hero grade + framing, top risks, next steps. For non-technical readers.",onClick:()=>U("executive-report","Executive report","executive-report.html"),locked:h("executive-report"),onUpgrade:k}),o&&e.jsx(G,{status:d["ticket-bundle"],label:"Ticket bundle",description:"Markdown formatted for paste into Linear / Jira / GitHub Issues — one ticket per finding, sorted by severity.",onClick:()=>U("ticket-bundle","Ticket bundle","ticket-bundle.md")})]}),e.jsxs(Z,{title:"Compliance & legal",children:[e.jsx(G,{status:d["defense-bundle"],label:"Defense bundle",description:"Anchored chain-of-custody evidence package. Use in pre-litigation.",onClick:()=>U("defense-bundle","Defense bundle","defense-bundle.html"),locked:h("defense-bundle"),onUpgrade:k}),e.jsx(G,{status:d["deposition-packet"],label:"Deposition packet",description:"Full evidence bundle — anchor, receipts, fingerprints, signing cert.",onClick:()=>U("deposition-packet","Deposition packet","deposition-packet.html"),locked:h("deposition-packet"),onUpgrade:k}),e.jsx(G,{status:d.vpat,label:"VPAT",description:"Voluntary Product Accessibility Template. Procurement-ready.",onClick:()=>U("vpat","VPAT","vpat.html"),locked:h("vpat"),onUpgrade:k}),e.jsx(G,{status:d["conformance-crosswalk"],label:"Conformance crosswalk",description:"WCAG ↔ Section 508 ↔ EN 301 549 mapping.",onClick:()=>U("conformance-crosswalk","Conformance crosswalk","conformance-crosswalk.html"),locked:h("conformance-crosswalk"),onUpgrade:k}),e.jsx(G,{status:d["methodology-doc"],label:"Methodology PDF",description:"Auditor-explainable methodology — what was tested, how, with what tools.",onClick:()=>U("methodology-doc","Methodology doc","methodology-doc.html"),locked:h("methodology-doc"),onUpgrade:k}),e.jsx(G,{status:d["evidence-bundle"],label:"Evidence bundle",description:"Lighter than defense bundle — audit records + summary.",onClick:()=>U("evidence-bundle","Evidence bundle","evidence-bundle.html"),locked:h("evidence-bundle"),onUpgrade:k})]}),e.jsx(Z,{title:"Bulk",children:e.jsx(G,{status:d.zip,label:o?"Download all as ZIP":"Download both as ZIP",description:o?"Every format above bundled in one ZIP. Runs each export in sequence — ~30s for an 8-page crawl.":"AI fix prompt + page report in one ZIP.",onClick:_,locked:h(o?"defense-bundle":"ai-prompt"),onUpgrade:k})})]}),e.jsxs(Z,{title:"Specialized views (classic UI)",children:[e.jsx("p",{style:{margin:0,marginBottom:"var(--v2-pad-2)",fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:`These surfaces aren't ported to v2 yet — clicking opens them in the classic UI. Return to v2 anytime via the "Try v2 UI" button in the classic Header.`}),e.jsx(L,{label:"State matrix",description:"Per-state findings grid (hover · focus · dark · RTL · etc.)",onClick:()=>A("matrix")}),e.jsx(L,{label:"Per-area compliance",description:"9 sub-grade areas with drill-in: Color & contrast, Keyboard, etc.",onClick:()=>A("report")}),e.jsx(L,{label:"Baseline delta",description:"New vs. persistent vs. fixed vs. acknowledged since the last baseline.",onClick:()=>A("delta")}),e.jsx(L,{label:"Forensic log",description:"Anchored audit history with chain-of-custody.",onClick:()=>A("forensic")}),e.jsx(L,{label:"Risk dashboard",description:"Lawsuit / conformance risk tiers with prioritized actions.",onClick:()=>A("risk")}),e.jsx(L,{label:"WCAG 3 mapping",description:"Outcome-level grouping per WCAG 3 snapshot.",onClick:()=>A("wcag3")}),e.jsx(L,{label:"WCAG-EM verdicts",description:"Formal per-criterion verdict map.",onClick:()=>A("compliance")}),e.jsx(L,{label:"Schedules",description:"Recurring audit management with email alerts.",onClick:()=>A("schedules")}),e.jsx(L,{label:"Copilot chat",description:"Anthropic-powered Q&A over your audit context.",onClick:()=>A("copilot")}),e.jsx(L,{label:"Accessibility tree",description:"Inspect the live aria tree as assistive tech sees it.",onClick:()=>A("ax-tree")}),e.jsx(L,{label:"Design tokens",description:"CSS-token / design-system audit.",onClick:()=>A("tokens")}),e.jsx(L,{label:"Guided audit",description:"13 manual IGT workflows (keyboard, screen reader, etc.).",onClick:()=>A("guided")}),e.jsx(L,{label:"Per-component scorecard",description:"Custom rules, baselines, per-component drill-in.",onClick:()=>A("scorecard")}),e.jsx(L,{label:"User journey flows",description:"Multi-step audit recordings.",onClick:()=>A("flows")}),e.jsx(L,{label:"Activity / IGT runs",description:"Manual workflow run history.",onClick:()=>A("activity")})]}),e.jsx(Z,{title:"Settings",children:e.jsx(G,{status:void 0,label:"Open settings",description:"Matrix preset, AI config, axe rule overrides, breakpoints, auto-export.",onClick:V})})]})]}),e.jsx(je,{open:w,onClose:()=>f(!1)})]}):null}async function ne(t,a,r){const s=new Blob([t],{type:r}),i=URL.createObjectURL(s);try{await chrome.tabs.create({url:i})}catch{const l=document.createElement("a");l.href=i,l.download=a,l.click()}setTimeout(()=>URL.revokeObjectURL(i),6e4)}function Z({title:t,children:a}){return e.jsxs("div",{children:[e.jsx("p",{className:"v2-eyebrow",style:{margin:0,marginBottom:"var(--v2-pad-2)",color:"var(--v2-ink-tertiary)"},children:t}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)"},children:a})]})}function G({label:t,description:a,status:r,onClick:s,locked:i=!1,onUpgrade:l}){const n=(r==null?void 0:r.state)==="busy",o=(r==null?void 0:r.state)==="done",u=(r==null?void 0:r.state)==="error";return i?e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:4,padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-warning, #f59e0b)",borderRadius:4,background:"var(--v2-warning-bg, rgba(245,158,11,0.08))"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--v2-pad-3)"},children:[e.jsxs("span",{style:{fontSize:13,fontWeight:500,color:"var(--v2-ink-primary)"},children:["🔒 ",t]}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-sm",onClick:l,children:"Upgrade"})]}),e.jsxs("p",{style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:[e.jsx("strong",{children:"Upgrade to unlock"}),a?` · ${a}`:""]})]}):e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:4,padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-border)",borderRadius:4,background:"var(--v2-bg)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--v2-pad-3)"},children:[e.jsx("span",{style:{fontSize:13,fontWeight:500,color:"var(--v2-ink-primary)"},children:t}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:s,disabled:n,children:n?"Working…":o?"Run again":"Run"})]}),a&&e.jsx("p",{style:{margin:0,fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:a}),n&&(r==null?void 0:r.progress)&&e.jsxs("p",{role:"status","aria-live":"polite",style:{margin:0,marginTop:4,fontSize:11,color:"var(--v2-ink-secondary)"},children:[r.progress.current,"/",r.progress.total," — ",r.progress.label??""]}),o&&(r==null?void 0:r.message)&&e.jsxs("p",{role:"status",style:{margin:0,marginTop:4,fontSize:11,color:"var(--v2-verified)"},children:["✓ ",r.message]}),u&&(r==null?void 0:r.message)&&e.jsx("p",{role:"alert",style:{margin:0,marginTop:4,fontSize:11,color:"var(--v2-critical)"},children:r.message})]})}function L({label:t,description:a,onClick:r}){return e.jsxs("button",{type:"button",onClick:r,style:{appearance:"none",cursor:"pointer",display:"flex",flexDirection:"column",gap:4,padding:"var(--v2-pad-3) var(--v2-pad-4)",border:"1px solid var(--v2-border)",borderRadius:4,background:"var(--v2-bg)",textAlign:"left",font:"inherit",color:"var(--v2-ink-primary)",width:"100%"},children:[e.jsxs("span",{style:{fontSize:13,fontWeight:500},children:[t," →"]}),e.jsx("span",{style:{fontSize:11,color:"var(--v2-ink-tertiary)",lineHeight:1.5},children:a})]})}function nr(){var l,n;const t=b(o=>o.siteCrawlReport),a=b(o=>o.results),[r,s]=c.useState(!1),i=(t==null?void 0:t.startUrl)??((l=a[0])==null?void 0:l.pageUrl)??((n=a[0])==null?void 0:n.scope)??null;return e.jsxs(e.Fragment,{children:[e.jsxs("header",{role:"banner",style:{display:"flex",flexDirection:"column",gap:"var(--v2-pad-2)",padding:"var(--v2-pad-3) var(--v2-pad-5)",borderBottom:"1px solid var(--v2-border)",background:"var(--v2-bg)"},children:[e.jsx("a",{href:"#main-content",className:"v2-skip-link",style:{position:"absolute",left:-9999},onFocus:o=>{o.currentTarget.style.left="var(--v2-pad-4)",o.currentTarget.style.top="var(--v2-pad-4)"},onBlur:o=>{o.currentTarget.style.left="-9999px"},children:"Skip to main content"}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-3)",minWidth:0,minHeight:28},children:[e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--v2-pad-2)"},children:[e.jsx("span",{className:"v2-display",style:{fontSize:18,fontWeight:600,letterSpacing:"-0.01em",color:"var(--v2-ink-primary)"},children:"wcagcheckr"}),e.jsx("span",{className:"v2-eyebrow",children:"v2"})]}),i&&e.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--v2-pad-2)",minWidth:0,flex:1},children:[e.jsx("span",{className:"v2-eyebrow",children:"scope"}),e.jsx("span",{className:"v2-mono",style:{fontSize:11,color:"var(--v2-ink-secondary)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},title:i,children:i})]}),e.jsx("div",{style:{marginLeft:"auto"},children:e.jsx($e,{})})]}),e.jsxs("nav",{"aria-label":"Application",style:{display:"flex",alignItems:"center",gap:"var(--v2-pad-2)",justifyContent:"flex-end"},children:[e.jsx(_e,{}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-primary v2-btn-sm",onClick:()=>s(!0),"aria-label":"Open tools and exports drawer","aria-expanded":r,title:"Exports, baselines, schedules, forensic log, settings, more",children:"Tools"}),e.jsx("button",{type:"button",className:"v2-btn v2-btn-ghost v2-btn-sm",onClick:()=>void T({type:"OPEN_SETTINGS"}),"aria-label":"Open settings",title:"Settings",children:"⚙"})]})]}),e.jsx(ar,{open:r,onClose:()=>s(!1)})]})}function ir(){return c.useEffect(()=>{const t=He(),r=new URLSearchParams(window.location.search).get("context")==="overlay"?null:chrome.runtime.connect({name:"sidepanel-tracker"}),s=Ge();Me({forceRefresh:!0}).catch(()=>{}),Be().catch(()=>{}),Ve().catch(()=>{}),Ke().catch(()=>{}),qe().catch(()=>{}),Ye().catch(()=>{}),ht().then(l=>{b.getState().setAcknowledgedKeys(new Set(l.map(n=>n.matchKey)))}).catch(()=>{});let i=!1;return gt().then(l=>{i||l&&b.setState({siteCrawlReport:l})}).catch(()=>{}),()=>{i=!0,s();try{t.disconnect()}catch{}try{r==null||r.disconnect()}catch{}}},[]),e.jsxs("div",{className:"v2-root",children:[e.jsx(nr,{}),e.jsx(Ze,{}),e.jsx(Qe,{}),e.jsxs("main",{id:"main-content","aria-label":"wcagcheckr findings",children:[e.jsx(Wt,{}),e.jsx(Xt,{})]})]})}function or({persona:t,children:a}){const r=t==="power"?"Power user":"Dev",[s,i]=c.useState(!1),l=c.useRef(null);c.useEffect(()=>{const o=l.current;o&&(o.inert=!0)},[]);function n(){chrome.storage.local.set({userMode:"owner",v2UiEnabled:!1}),T({type:"SETTINGS_SET",key:"userMode",value:"owner"})}return e.jsxs("div",{className:"relative h-screen overflow-hidden",children:[e.jsx("div",{ref:l,"aria-hidden":"true",className:"h-full overflow-hidden blur-[2px] opacity-50 pointer-events-none select-none",children:a}),e.jsx("div",{className:"absolute inset-0 z-50 flex items-center justify-center bg-slate-900/40 p-4",children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"locked-persona-title",className:"max-w-sm w-full bg-white border border-slate-200 rounded-xl shadow-xl p-5 space-y-3 text-sm",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xl","aria-hidden":"true",children:"🔒"}),e.jsxs("h2",{id:"locked-persona-title",className:"text-base font-semibold text-slate-900",children:[r," mode is a paid feature"]})]}),e.jsxs("p",{className:"text-xs text-slate-600 leading-snug",children:[r," mode unlocks the full WCAG findings, fix recipes, and exports for every page — that needs a license. On the free plan, ",e.jsx("strong",{children:"Owner mode"})," ","(the lawsuit-target screener) is yours to use, no license required."]}),e.jsxs("div",{className:"flex flex-col gap-2 pt-1",children:[e.jsx("button",{type:"button",onClick:()=>i(!0),className:"w-full text-sm px-4 py-2 bg-brand-500 text-white rounded hover:bg-brand-600 font-medium",children:"Upgrade to unlock →"}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("button",{type:"button",onClick:()=>void T({type:"OPEN_SETTINGS"}),className:"text-xs text-slate-600 hover:text-slate-900 underline-offset-2 hover:underline",children:"I have a license token"}),e.jsx("button",{type:"button",onClick:n,className:"text-xs font-medium text-brand-700 hover:underline",children:"← Back to Owner mode"})]})]})]})}),e.jsx(je,{open:s,onClose:()=>i(!1)})]})}function sr(){return e.jsxs("div",{role:"alert",className:"flex flex-col items-center justify-center min-h-screen gap-4 px-6 py-10 text-center",children:[e.jsx("div",{className:"text-3xl","aria-hidden":"true",children:"📡"}),e.jsx("h1",{className:"text-base font-semibold text-slate-800",children:"Internet connection required"}),e.jsx("p",{className:"max-w-xs text-sm leading-relaxed text-slate-600",children:"wcagcheckr needs to reach its license server to run. Connect to the internet and reload."}),e.jsx("button",{type:"button",onClick:()=>window.location.reload(),className:"rounded bg-slate-800 px-4 py-1.5 text-sm font-medium text-white hover:bg-slate-700",children:"Reload"})]})}rt("side-panel");function lr(){const[t,a]=c.useState(null),[r,s]=c.useState(!1),[,i]=c.useState(0),[l,n]=c.useState(null),[o,u]=c.useState(!1),[v,h]=c.useState(!1);if(c.useEffect(()=>{let f=!1;(async()=>{if(await Promise.all([ve(),me()]),!f){if(s(!0),await he()){f||n(!0),Promise.all([ge(),fe()]).then(()=>{f||i(x=>x+1)}).catch(()=>{});return}await Promise.all([ge(),fe()]).catch(()=>{}),!f&&(i(x=>x+1),n(await he()))}})(),chrome.storage.local.get("licenseToken").then(x=>{f||h(!!x.licenseToken)}).catch(()=>{}).finally(()=>{f||u(!0)});function k(x){const d=x.userMode,S=!!x.v2UiEnabled;let I;d==="owner"||d==="power"||d==="dev"?I=d:I=S?"power":"owner",f||a(I)}chrome.storage.local.get(["userMode","v2UiEnabled"]).then(k).catch(()=>a("owner"));const y=(x,d)=>{d==="local"&&("tierConfig:cache"in x&&ve().then(()=>{f||i(S=>S+1)}),"rubricConfigCache"in x&&me().then(()=>{f||i(S=>S+1)}),"licenseToken"in x&&chrome.storage.local.get("licenseToken").then(S=>{f||h(!!S.licenseToken)}),!(!("userMode"in x)&&!("v2UiEnabled"in x))&&chrome.storage.local.get(["userMode","v2UiEnabled"]).then(k))};return chrome.storage.onChanged.addListener(y),()=>{f=!0,chrome.storage.onChanged.removeListener(y)}},[]),t===null||!r||!o||l===null)return null;if(!l)return e.jsx(sr,{});const w=t==="power"?e.jsx(ir,{}):e.jsx(Xe,{});return(t==="power"||t==="dev")&&!v?e.jsx(or,{persona:t,children:w}):w}const Ue=document.getElementById("root");if(!Ue)throw new Error("side-panel: #root not found");ze(Ue).render(e.jsx(De.StrictMode,{children:e.jsx(Je,{children:e.jsx(lr,{})})}));
|