<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Scan Report: www-regeringen-se--2026-04-23T07-41-03-322Z--sweden-weekly-desktop-light-chromium</title>
    <style>
        :root {
            color-scheme: light;
            --bg: #f5f5f5;
            --panel-bg: #fff;
            --panel-border: #e0e0e0;
            --text: #222;
            --muted: #666;
            --link: #005a9c;
            --link-visited: #5e35b1;
            --header-bg: #0a2540;
            --header-text: #fff;
            --pill-critical: #d32f2f;
            --pill-warning: #b95e00;
            --pill-info: #0d47a1;
            --card-bg: #fafafa;
            --bar-bg: #e0e0e0;
            --code-bg: #f5f5f5;
            --focus: #90caf9;
        }
        @media (prefers-color-scheme: dark) {
            :root {
                color-scheme: dark;
                --bg: #0f141a;
                --panel-bg: #121826;
                --panel-border: #1f2937;
                --text: #e5e7eb;
                --muted: #9ca3af;
                --link: #7cb7ff;
                --link-visited: #c4b5fd;
                --header-bg: #0a2540;
                --header-text: #e5e7eb;
                --pill-critical: #ef4444;
                --pill-warning: #fb923c;
                --pill-info: #3b82f6;
                --card-bg: #1f2937;
                --bar-bg: #1f2937;
                --code-bg: #111827;
                --focus: #7cb7ff;
            }
        }
        [data-theme="light"] {
            color-scheme: light;
            --bg: #f5f5f5;
            --panel-bg: #fff;
            --panel-border: #e0e0e0;
            --text: #222;
            --muted: #666;
            --link: #005a9c;
            --link-visited: #5e35b1;
            --header-bg: #0a2540;
            --header-text: #fff;
            --pill-critical: #d32f2f;
            --pill-warning: #b95e00;
            --pill-info: #0d47a1;
            --card-bg: #fafafa;
            --bar-bg: #e0e0e0;
            --code-bg: #f5f5f5;
            --focus: #90caf9;
        }
        [data-theme="dark"] {
            color-scheme: dark;
            --bg: #0f141a;
            --panel-bg: #121826;
            --panel-border: #1f2937;
            --text: #e5e7eb;
            --muted: #9ca3af;
            --link: #7cb7ff;
            --link-visited: #c4b5fd;
            --header-bg: #0a2540;
            --header-text: #e5e7eb;
            --pill-critical: #ef4444;
            --pill-warning: #fb923c;
            --pill-info: #3b82f6;
            --card-bg: #1f2937;
            --bar-bg: #1f2937;
            --code-bg: #111827;
            --focus: #7cb7ff;
        }
        * { box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 0; background: var(--bg); color: var(--text); }
        a { color: var(--link); text-decoration: underline; }
        a:hover { text-decoration: underline; }
        a:visited { color: var(--link-visited); }
        h1, h2, h3, h4 { margin: 0; }
        strong { color: var(--text); }

        header { background: var(--header-bg); color: var(--header-text); padding: 2rem 1rem; }
        .header-content { max-width: 1200px; margin: 0 auto; display: flex; flex-direction: column; gap: 0.5rem; }
        .header-top { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
        .header-actions { display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap; }
        .site-logo { color: var(--header-text); font-size: 20px; display: inline-block; font-weight: 700; text-decoration: none; }
        .site-logo:hover { color: var(--header-text); text-decoration: underline; }
        .back-link { color: var(--header-text); font-size: 14px; display: inline-block; font-weight: 700; text-decoration: underline; }
        .back-link:hover { color: var(--header-text); text-decoration: underline; }
        h1 { font-size: 28px; font-weight: 700; }
        .meta { margin-top: 0.25rem; font-size: 14px; color: var(--header-text); opacity: 1; }
        .meta strong { color: var(--header-text); }
        .download-link { display: inline-block; margin-top: 0.5rem; padding: 10px 16px; background: var(--panel-bg); color: #000; border-radius: 4px; font-weight: 600; border: 1px solid var(--panel-border); text-align: center; }
        .download-link:hover { background: var(--card-bg); text-decoration: none; }
        button.download-link { cursor: pointer; }

        .container { max-width: 1200px; margin: -40px auto 0 auto; padding: 0 1rem 2rem 1rem; }
        .layout { display: grid; grid-template-columns: 2fr 0.9fr; gap: 1.5rem; align-items: start; }
        @media (max-width: 960px) { .layout { grid-template-columns: 1fr; } }

        .panel { background: var(--panel-bg); border: 1px solid var(--panel-border); border-radius: 6px; box-shadow: 0 6px 18px rgba(0,0,0,0.04); padding: 1.5rem; }
        .panel + .panel { margin-top: 1rem; }
        .panel h3 { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 0.75rem; }
        .panel small { color: var(--muted); }

        .search-row { display: flex; gap: 0.75rem; margin-bottom: 1rem; flex-wrap: wrap; align-items: center; }
        .search-input { flex: 1 1 260px; padding: 10px 12px; border: 1px solid var(--panel-border); border-radius: 4px; font-size: 14px; background: var(--panel-bg); color: var(--text); }
        .search-input:focus { outline: 2px solid var(--focus); border-color: var(--focus); }

        .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 1rem; }
        .card { background: var(--card-bg); border: 1px solid var(--panel-border); border-radius: 6px; padding: 1rem; }
        .card h2 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted); margin-bottom: 0.35rem; font-weight: normal; }
        .card .value { font-size: 30px; font-weight: 700; color: #000; background: #fff; padding: 2px 4px; border-radius: 3px; display: inline-block; }
        .card .subtext { font-size: 12px; color: var(--muted); margin-top: 4px; }
        [data-theme="dark"] .card .value { color: #fff; background: #0f141a; }

        .mini-trend { margin-top: 1rem; border-top: 1px solid var(--panel-border); padding-top: 1rem; }
        .mini-trend h4 { margin: 0 0 0.5rem 0; font-size: 14px; }
        .mini-trend svg { width: 100%; height: 120px; border: 1px solid var(--panel-border); border-radius: 4px; background: var(--card-bg); }
        .mini-trend-status { margin-top: 0.35rem; color: var(--muted); font-size: 13px; }
        .mini-dot { fill: var(--pill-info); }
        .mini-line { stroke: var(--pill-info); stroke-width: 1.5; fill: none; }

        .bar { background: var(--bar-bg); height: 22px; border-radius: 4px; overflow: hidden; display: flex; margin: 10px 0; }
        .bar-segment { height: 100%; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 12px; font-weight: 700; }
        .bar-auto { background: var(--pill-info); }

        .top-pages { display: grid; gap: 0.5rem; }
        .page-row { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem; border: 1px solid var(--panel-border); border-radius: 4px; }
        .page-row .url { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size: 13px; overflow-wrap: anywhere; color: var(--text); }
        .pill { padding: 4px 10px; border-radius: 999px; font-weight: 700; font-size: 12px; white-space: nowrap; color: #fff; }

        .issues-by-severity { margin-top: 1.5rem; }
        .severity-group { border: 1px solid var(--panel-border); border-radius: 6px; overflow: hidden; margin-bottom: 1rem; }
        .severity-header { background: var(--card-bg); padding: 1rem; display: flex; justify-content: space-between; align-items: center; cursor: pointer; border: none; width: 100%; text-align: left; color: var(--text); }
        .severity-header .title { font-weight: 700; }
        .severity-header .count { background: #e0e0e0; padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: 700; color: #111; }
        [data-theme="dark"] .severity-header .count { background: #1f2937; color: var(--text); }
        .severity-content { padding: 1rem; }

        .violation-item { border-bottom: 1px solid var(--panel-border); padding: 0.75rem 0; }
        .violation-item:last-child { border-bottom: none; }
        .violation-id { font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; color: var(--text); }
        .violation-help { color: var(--muted); margin: 4px 0 6px 0; }
        .violation-meta { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
        .node-list { background: var(--card-bg); border: 1px solid var(--panel-border); border-radius: 4px; padding: 0; font-size: 13px; overflow: hidden; }
        .node-item { margin-bottom: 0; padding: 10px; border-bottom: 1px solid var(--panel-border); }
        .node-item:nth-child(odd) { background: var(--panel-bg); }
        .node-item:nth-child(even) { background: var(--code-bg); }
        .node-item:last-child { border-bottom: none; }
        .node-url { font-weight: 700; color: var(--text); }
        .node-selector { color: #005a9c; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; margin-top: 4px; }
        .node-html { margin-top: 4px; color: var(--text); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; overflow-wrap: anywhere; background: var(--card-bg); padding: 6px; border-radius: 4px; max-height: 300px; overflow-y: auto; }
        .node-fix { margin-top: 6px; color: var(--muted); font-size: 12px; background: var(--card-bg); padding: 6px; border-radius: 4px; }
        .node-unique { margin-top: 6px; color: var(--muted); font-size: 11px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
        .see-more-btn { display: inline-block; margin-top: 0.75rem; padding: 8px 12px; background: var(--link); color: #fff; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; font-size: 13px; }
        .see-more-btn:hover { opacity: 0.9; }
        .see-more-btn:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
        .copy-btn { display: inline-block; padding: 6px 10px; background: var(--link); color: #fff; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; font-size: 12px; margin-top: 0.5rem; }
        .copy-btn:hover { opacity: 0.9; }
        .copy-btn:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
        .copy-btn.copied { background: #4caf50; }
        .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); }
        .modal.open { display: flex; align-items: center; justify-content: center; }
        .modal-content { background: var(--panel-bg); padding: 2rem; border-radius: 8px; width: 90%; max-width: 900px; max-height: 80vh; overflow-y: auto; }
        .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; border-bottom: 1px solid var(--panel-border); padding-bottom: 1rem; }
        .modal-header h2 { margin: 0; color: var(--text); font-size: 20px; }
        .modal-close { background: none; border: none; font-size: 24px; cursor: pointer; color: var(--text); }
        .modal-close:hover { opacity: 0.7; }
        .modal-node-item { padding: 10px; border-bottom: 1px solid var(--panel-border); }
        .modal-node-item:nth-child(odd) { background: var(--panel-bg); }
        .modal-node-item:nth-child(even) { background: var(--code-bg); }
        .modal-node-item:last-child { border-bottom: none; }

        .modal-node-list { background: var(--card-bg); border: 1px solid var(--panel-border); border-radius: 4px; padding: 0; margin-top: 8px; overflow: hidden; }
        .page-violation-item { border-bottom: 1px solid var(--panel-border); padding: 12px; }
        .page-violation-item:last-child { border-bottom: none; }
        .page-violation-item:nth-child(odd) { background: var(--card-bg); }
        .page-violation-item:nth-child(even) { background: var(--panel-bg); }
        .page-violation-item .violation-id { font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; color: var(--text); font-size: 13px; }
        .page-violation-item .violation-help { color: var(--muted); margin: 4px 0; font-size: 13px; }
        .page-violation-item .violation-meta { font-size: 12px; color: var(--muted); margin: 6px 0; }
        .page-violation-item a { color: var(--link); }
        .modal-page-violations { display: flex; flex-direction: column; gap: 0; }
        .page-row button.pill { border: none; cursor: pointer; background: inherited; padding: 4px 10px; font-weight: 700; font-size: 12px; color: #fff; border-radius: 999px; }
        .page-row button.pill:hover { opacity: 0.9; }
        .page-row button.pill:focus { outline: 2px solid var(--focus); outline-offset: 2px; }

        .pill-critical { background: var(--pill-critical); }
        .pill-warning { background: var(--pill-warning); }
        .pill-info { background: var(--pill-info); }

        .no-violations { background: #11321b; border: 1px solid #1f5d2f; border-radius: 6px; padding: 1rem; color: #b7f7c0; font-weight: 600; }
        [data-theme="light"] .no-violations { background: #e8f5e9; border-color: #c8e6c9; color: #2e7d32; }

        .site-logo:focus,
        .back-link:focus,
        .download-link:focus,
        .search-input:focus,
        .severity-header:focus,
        .debug-accordion summary:focus,
        .theme-toggle:focus {
            outline: 2px solid var(--header-text);
            outline-offset: 2px;
        }

        .theme-toggle { background: var(--panel-bg); color: var(--text); border: 1px solid var(--panel-border); border-radius: 999px; padding: 6px 10px; cursor: pointer; font-weight: 600; display: inline-flex; align-items: center; gap: 8px; }
        .theme-toggle .theme-icon { display: block; width: 16px; height: 16px; }
        
        /* Default state (light mode): show moon icon */
        .sun-icon { display: none; }
        .moon-icon { display: block; }
        
        /* If system prefers dark mode, show sun icon before JS loads */
        @media (prefers-color-scheme: dark) {
            .sun-icon { display: block; }
            .moon-icon { display: none; }
        }
        
        /* Show/hide appropriate icon based on theme */
        [data-theme="dark"] .sun-icon { display: block; }
        [data-theme="dark"] .moon-icon { display: none; }
        [data-theme="light"] .sun-icon { display: none; }
        [data-theme="light"] .moon-icon { display: block; }
        
        .learn-more { color: var(--link); text-decoration: underline; }
        .violation-template { margin-top: 6px; font-size: 12px; color: var(--muted); }
        
        /* Smooth transitions for theme switching */
        * {
            transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
        }
        
        /* Respect reduced motion preference */
        @media (prefers-reduced-motion: reduce) {
            * {
                transition: none;
            }
            .modal { animation: none; }
        }
        
        @media (prefers-reduced-motion: no-preference) {
            .modal { animation: none; }
        }

        footer {
            margin-top: 3rem;
            padding: 2rem 1rem;
            border-top: 1px solid var(--panel-border);
            text-align: center;
            color: var(--muted);
            font-size: 13px;
            background: var(--card-bg);
        }
        footer a { color: var(--link); text-decoration: underline; }
        footer a:hover { text-decoration: underline; }
        footer strong { color: var(--text); }
        footer p { margin: 0; line-height: 1.6; }

        @media print {
            :root { color-scheme: light; }
            body { background: #fff; color: #000; }
            header { background: #fff; color: #000; }
            a { color: #000; text-decoration: underline; }
            .header-actions { display: none; }
            .layout { grid-template-columns: 1fr; }
            .panel { box-shadow: none; border: 1px solid #ccc; background: #fff; }
            .severity-content { display: block !important; }
            .severity-header { page-break-inside: avoid; }
            .page-row, .card, .panel { page-break-inside: avoid; }
            footer { border: none; background: #fff; }
            #insights-section { display: none; }
        }

        /* Insights panel */
        #insights-section { margin-top: 0; max-width: 1200px; margin-left: auto; margin-right: auto; padding: 0 1rem 1rem 1rem; }
        .insights-intro { color: var(--muted); font-size: 14px; margin: 0 0 1rem 0; }
        .insights-buttons { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
        .insights-btn { padding: 10px 16px; background: var(--link); color: #fff; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; font-size: 14px; }
        .insights-btn:hover { opacity: 0.9; }
        .insights-btn:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
        .insights-btn:disabled { opacity: 0.5; cursor: not-allowed; }
        .insights-btn.active { background: #2e7d32; }
        #ai-status { font-size: 13px; color: var(--muted); margin-bottom: 0.75rem; min-height: 1.2em; }
        .insights-output { margin-top: 1rem; padding: 1rem; border: 1px solid var(--panel-border); border-radius: 4px; background: var(--card-bg); min-height: 3rem; font-size: 14px; line-height: 1.6; white-space: pre-wrap; display: none; }
        .insights-output.visible { display: block; }
        .insights-output h3, .insights-output h4, .insights-output h5 { color: var(--text); margin: 0.75rem 0 0.25rem 0; }
        .insights-output ul, .insights-output ol { padding-left: 1.5rem; margin: 0.5rem 0; }
        .insights-output p { margin: 0.5rem 0; }
        .ai-warning { background: #fff3e0; border: 1px solid #f57c00; border-radius: 4px; padding: 8px 12px; margin-bottom: 0.75rem; color: #b35900; font-size: 13px; font-weight: 600; }
        [data-theme="dark"] .ai-warning { background: #2a1f00; border-color: #f57c00; color: #ffb74d; }
        .ai-cached-note { font-size: 12px; color: var(--muted); margin-top: 0.5rem; }
        .insights-fallback { margin-top: 0.75rem; }
        .fallback-prompt-wrap { margin-top: 0.75rem; }
        .fallback-prompt-label { font-size: 13px; font-weight: 600; margin-bottom: 0.25rem; }
        .fallback-prompt-text { font-size: 12px; background: var(--code-bg); border: 1px solid var(--panel-border); border-radius: 4px; padding: 8px; max-height: 120px; overflow-y: auto; white-space: pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
        .fallback-prompt-text:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
        .copy-prompt-btn { margin-top: 4px; padding: 5px 10px; background: var(--link); color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 600; }
        .copy-prompt-btn:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
        .copy-prompt-btn.copied { background: #4caf50; }
        .insights-trends { margin-top: 1.5rem; border-top: 1px solid var(--panel-border); padding-top: 1rem; }
        .insights-trends h4 { margin: 0 0 0.75rem 0; font-size: 15px; }
        .trends-charts-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
        @media (max-width: 640px) { .trends-charts-row { grid-template-columns: 1fr; } }
        .trend-chart-wrap { }
        .trend-chart-label { font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 4px; }
        .insight-trend-svg { width: 100%; height: 120px; border: 1px solid var(--panel-border); border-radius: 4px; background: var(--card-bg); display: block; }
        .regression-alerts { margin-top: 1rem; }
        .regression-alert { border-radius: 4px; padding: 10px 14px; font-size: 13px; margin-bottom: 0.5rem; }
        .regression-alert.new { background: #fff3e0; border: 1px solid #f57c00; color: #b35900; }
        .regression-alert.spike { background: #ffebee; border: 1px solid #ef9a9a; color: #b71c1c; }
        .regression-alert.improved { background: #e8f5e9; border: 1px solid #a5d6a7; color: #1b5e20; }
        [data-theme="dark"] .regression-alert.new { background: #2a1f00; border-color: #f57c00; color: #ffb74d; }
        [data-theme="dark"] .regression-alert.spike { background: #2a0000; border-color: #ef9a9a; color: #ff8a80; }
        [data-theme="dark"] .regression-alert.improved { background: #0a1f0a; border-color: #a5d6a7; color: #69f0ae; }

        /* Dedupe and Patterns section */
        #dedupe-section { margin-top: 0; max-width: 1200px; margin-left: auto; margin-right: auto; padding: 0 1rem 1rem 1rem; }
        .dedupe-intro { color: var(--muted); font-size: 14px; margin: 0 0 1rem 0; }
        .dedupe-summary-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.75rem; margin: 0 0 1rem 0; }
        .dedupe-ai-status { font-size: 13px; color: var(--muted); margin: 0.5rem 0; min-height: 1.2em; }
        .dedupe-buttons { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
        .dedupe-progress { font-size: 13px; color: var(--muted); margin: 0.5rem 0; }
        .dedupe-cap-note { font-size: 12px; color: var(--muted); margin-top: 0.5rem; font-style: italic; }
        #dedupe-groups-section h4,
        #dedupe-clusters-section h4,
        #dedupe-actions-section h4 { margin: 1rem 0 0.5rem 0; font-size: 15px; border-bottom: 1px solid var(--panel-border); padding-bottom: 0.5rem; color: var(--text); }
        .dedupe-group-card { border: 1px solid var(--panel-border); border-radius: 4px; padding: 0.75rem; margin-bottom: 0.5rem; background: var(--card-bg); }
        .dg-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.35rem; gap: 0.5rem; }
        .dg-rule { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: 700; font-size: 13px; color: var(--text); }
        .dg-count { background: var(--pill-info); color: #fff; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; white-space: nowrap; }
        .dg-message { color: var(--muted); font-size: 13px; margin-bottom: 0.35rem; }
        .dg-meta { font-size: 12px; color: var(--muted); margin-bottom: 0.5rem; }
        .dg-examples { font-size: 12px; display: flex; flex-direction: column; gap: 3px; }
        .dg-example { background: var(--code-bg); border-radius: 3px; padding: 4px 6px; }
        .dg-ex-page { color: var(--link); overflow-wrap: anywhere; }
        .dg-ex-selector { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; color: var(--muted); overflow-wrap: anywhere; }
        .dedupe-cluster-card { border: 1px solid var(--panel-border); border-radius: 4px; padding: 0.75rem; margin-bottom: 0.75rem; background: var(--card-bg); }
        .dc-name { font-weight: 700; font-size: 15px; color: var(--text); margin-bottom: 0.25rem; }
        .dc-root-cause { color: var(--text); font-size: 13px; margin-bottom: 0.5rem; }
        .dc-fix-title { font-weight: 600; font-size: 13px; color: var(--text); margin-bottom: 0.25rem; }
        .dc-fix-steps { padding-left: 1.25rem; margin: 0.25rem 0 0.5rem 0; font-size: 13px; color: var(--text); }
        .dc-meta { font-size: 12px; color: var(--muted); }
        .dedupe-action-card { border-left: 3px solid var(--pill-info); padding: 0.75rem; margin-bottom: 0.5rem; background: var(--card-bg); border-radius: 0 4px 4px 0; }
        .da-title { font-weight: 700; color: var(--text); margin-bottom: 0.25rem; font-size: 14px; }
        .da-why { font-size: 13px; color: var(--muted); margin-bottom: 0.25rem; }
        .da-blast { font-size: 12px; font-weight: 700; }
        .da-blast-low { color: #2e7d32; }
        .da-blast-medium { color: #b95e00; }
        .da-blast-high { color: #d32f2f; }
        [data-theme="dark"] .da-blast-low { color: #69f0ae; }
        [data-theme="dark"] .da-blast-medium { color: #ffb74d; }
        [data-theme="dark"] .da-blast-high { color: #ff8a80; }
        .dedupe-error { background: #ffebee; border: 1px solid #ef9a9a; border-radius: 4px; padding: 8px 12px; font-size: 13px; color: #b71c1c; margin-top: 0.5rem; }
        [data-theme="dark"] .dedupe-error { background: #2a0000; border-color: #ef9a9a; color: #ff8a80; }
        @media print {
            #dedupe-section { display: none; }
        }
    </style>
</head>
<body>
    <a href="#main" style="position:absolute;left:-999px;top:-999px;">Skip to main content</a>
    <header>
        <div class="header-content">
            <div class="header-top">
                <a href="#" class="site-logo" id="homeLogo">🎩 O-Hat Scanner</a>
                <div class="header-actions">
                    <button id="theme-toggle" class="theme-toggle" type="button" aria-label="Switch to dark mode">
                        <svg aria-hidden="true" class="theme-icon sun-icon" viewBox="0 0 24 24" width="16" height="16">
                            <circle cx="12" cy="12" r="5" fill="currentColor"/>
                            <path fill="currentColor" d="M12 1v3M12 20v3M4.22 4.22l2.12 2.12M17.66 17.66l2.12 2.12M1 12h3M20 12h3M4.22 19.78l2.12-2.12M17.66 6.34l2.12-2.12"/>
                        </svg>
                        <svg aria-hidden="true" class="theme-icon moon-icon" viewBox="0 0 24 24" width="16" height="16">
                            <path fill="currentColor" d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
                        </svg>
                    </button>
                </div>
            </div>
            <h1>Accessibility Scan Report</h1>
            <p class="meta">
                <strong>Scan ID:</strong> www-regeringen-se--2026-04-23T07-41-03-322Z--sweden-weekly-desktop-light-chromium · <strong>Date:</strong> 4/23/2026, 7:41:03 AM · <strong>Mode:</strong> ci · <strong>Viewport:</strong> Desktop · <strong>Color:</strong> Light · <strong>Max pages:</strong> 100 · <strong>Sampling:</strong> shuffle (seed sweden-weekly)
            </p>
            <div class="header-actions">
                <a href="report.csv" class="download-link" download>Download CSV</a>
                <a href="results.json" class="download-link" download>Download JSON</a>
                <a href="report.mhtml" class="download-link" download>Download MHTML</a>
                <button id="printButton" class="download-link" type="button" aria-label="Save this report as a PDF">Save as PDF</button>
            </div>
        </div>
    </header>

    <main id="main">
    <div class="container">
        <div class="layout">
            <!-- Main column -->
            <div class="panel">
                <div class="search-row">
                    <label for="issueSearch">Search issues</label>
                    <input id="issueSearch" class="search-input" type="search" placeholder="Search issues (ID, description, page)..." aria-label="Search issues">
                </div>

                <div class="summary-grid">
                    <div class="card">
                        <h2>Pages scanned</h2>
                        <div class="value">100</div>
                        <div class="subtext">Targets from sitemap or config</div>
                    </div>
                    <div class="card">
                        <h2>Pages with issues</h2>
                        <div class="value">24</div>
                        <div class="subtext">24% of pages</div>
                    </div>
                    <div class="card critical">
                        <h2>Must Fix</h2>
                        <div class="value">1</div>
                        <div class="subtext">Critical / Serious impacts</div>
                    </div>
                    <div class="card warning">
                        <h2>Good to Fix</h2>
                        <div class="value">24</div>
                        <div class="subtext">Moderate / Minor impacts</div>
                    </div>
                    <div class="card info">
                        <h2>Manual review</h2>
                        <div class="value">0</div>
                        <div class="subtext">Potential false positives</div>
                    </div>
                </div>

                <div class="panel" style="margin-top: 1rem;">
                    <h3>WCAG compliance snapshot</h3>
                    <small>Automated coverage only; manual verification still required.</small>
                    <div class="bar" role="img" aria-label="Automation coverage">
                        <div class="bar-segment bar-auto" style="width: 100%">100% automation</div>
                        <div class="bar-segment" style="background:#e0e0e0; width: 0%"></div>
                    </div>
                </div>

                
                <div class="panel" style="margin-top: 1rem;">
                    <h3>Top pages to review</h3>
                    <div class="top-pages">
                        
                                <div class="page-row">
                                    <div class="url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/</a></div>
                                    <button class="pill pill-warning" onclick="document.getElementById('modal-page-https---www-regeringen-se-sveriges-regering-finansdepartementet-statens-budget-').classList.add('open')" type="button">2 issues</button>
                                    <div id="modal-page-https---www-regeringen-se-sveriges-regering-finansdepartementet-statens-budget-" class="modal">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h2>Issues on Statens budget - Regeringen.se</h2>
                                                <div style="display: flex; gap: 0.5rem; align-items: center;">
                                                    <button class="copy-btn" type="button" data-copy-page-violations="true" aria-label="Copy all issues on this page">Copy all issues</button>
                                                    <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                </div>
                                            </div>
                                            <div class="modal-page-violations">
                                    <div class="page-violation-item">
                                        <div class="violation-id">heading-order</div>
                                        <div class="violation-help">Heading levels should only increase by one</div>
                                        <div class="violation-meta">Impact: moderate · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/heading-order?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix any of the following:
  Heading order invalid</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: .block--mediavertical__title</div>
                                                <div class="node-html">&lt;h3 class=&quot;block--mediavertical__title&quot;&gt;Vårbudgeten 2026 på fem minuter&lt;/h3&gt;</div>
                                                <div class="node-unique">Unique: c2fe2aecc21eaa257c9cd9d6eac8a30b</div>
                                            </div>
                                        </div>
                                    </div>
                                
                                    <div class="page-violation-item">
                                        <div class="violation-id">region</div>
                                        <div class="violation-help">All page content should be contained by landmarks</div>
                                        <div class="violation-meta">Impact: moderate · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/region?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: #loading</div>
                                                <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                <div class="node-unique">Unique: 79f17f18c2e42887a826c536553d61e5</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                        </div>
                                    </div>
                                </div>
                            
                                <div class="page-row">
                                    <div class="url"><a href="https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618" target="_blank" rel="noopener">https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618</a></div>
                                    <button class="pill pill-critical" onclick="document.getElementById('modal-page-https---www-regeringen-se-rattsliga-dokument-kommittedirektiv-2026-03-dir--202618').classList.add('open')" type="button">1 issues</button>
                                    <div id="modal-page-https---www-regeringen-se-rattsliga-dokument-kommittedirektiv-2026-03-dir--202618" class="modal">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h2>Issues on Värnpliktigas tjänstgöring i Natos samlade avskräckning och försvar - Regeringen.se</h2>
                                                <div style="display: flex; gap: 0.5rem; align-items: center;">
                                                    <button class="copy-btn" type="button" data-copy-page-violations="true" aria-label="Copy all issues on this page">Copy all issues</button>
                                                    <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                </div>
                                            </div>
                                            <div class="modal-page-violations">
                                    <div class="page-violation-item">
                                        <div class="violation-id">aria-allowed-attr</div>
                                        <div class="violation-help">Elements must only use supported ARIA attributes</div>
                                        <div class="violation-meta">Impact: critical · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/aria-allowed-attr?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix all of the following:
  ARIA attribute is not allowed: aria-expanded=&quot;false&quot;</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: .c-accordion__action</div>
                                                <div class="node-html">&lt;div class=&quot;js-toggle c-accordion__action c-accordion__action--background&quot; data-target=&quot;&quot; data-type=&quot;slide&quot; aria-expanded=&quot;false&quot; aria-haspopup=&quot;true&quot;</div>
                                                <div class="node-unique">Unique: 869a9fa41b96537b6924dbd677ef5cf2</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                        </div>
                                    </div>
                                </div>
                            
                                <div class="page-row">
                                    <div class="url"><a href="https://www.regeringen.se/" target="_blank" rel="noopener">https://www.regeringen.se/</a></div>
                                    <button class="pill pill-warning" onclick="document.getElementById('modal-page-https---www-regeringen-se-').classList.add('open')" type="button">1 issues</button>
                                    <div id="modal-page-https---www-regeringen-se-" class="modal">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h2>Issues on Startsidan - Regeringen.se</h2>
                                                <div style="display: flex; gap: 0.5rem; align-items: center;">
                                                    <button class="copy-btn" type="button" data-copy-page-violations="true" aria-label="Copy all issues on this page">Copy all issues</button>
                                                    <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                </div>
                                            </div>
                                            <div class="modal-page-violations">
                                    <div class="page-violation-item">
                                        <div class="violation-id">region</div>
                                        <div class="violation-help">All page content should be contained by landmarks</div>
                                        <div class="violation-meta">Impact: moderate · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/region?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: #loading</div>
                                                <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                <div class="node-unique">Unique: e6a17a1c657f683e316c37c7bb9a64ac</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                        </div>
                                    </div>
                                </div>
                            
                                <div class="page-row">
                                    <div class="url"><a href="https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/</a></div>
                                    <button class="pill pill-warning" onclick="document.getElementById('modal-page-https---www-regeringen-se-sveriges-regering-arbetsmarknadsdepartementet-').classList.add('open')" type="button">1 issues</button>
                                    <div id="modal-page-https---www-regeringen-se-sveriges-regering-arbetsmarknadsdepartementet-" class="modal">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h2>Issues on Arbetsmarknads­departementet - Regeringen.se</h2>
                                                <div style="display: flex; gap: 0.5rem; align-items: center;">
                                                    <button class="copy-btn" type="button" data-copy-page-violations="true" aria-label="Copy all issues on this page">Copy all issues</button>
                                                    <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                </div>
                                            </div>
                                            <div class="modal-page-violations">
                                    <div class="page-violation-item">
                                        <div class="violation-id">region</div>
                                        <div class="violation-help">All page content should be contained by landmarks</div>
                                        <div class="violation-meta">Impact: moderate · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/region?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: #loading</div>
                                                <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                <div class="node-unique">Unique: 39882a7acbf61043e56821ff8a17f0f2</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                        </div>
                                    </div>
                                </div>
                            
                                <div class="page-row">
                                    <div class="url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/</a></div>
                                    <button class="pill pill-warning" onclick="document.getElementById('modal-page-https---www-regeringen-se-sveriges-regering-finansdepartementet-').classList.add('open')" type="button">1 issues</button>
                                    <div id="modal-page-https---www-regeringen-se-sveriges-regering-finansdepartementet-" class="modal">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h2>Issues on Finansdepartementet - Regeringen.se</h2>
                                                <div style="display: flex; gap: 0.5rem; align-items: center;">
                                                    <button class="copy-btn" type="button" data-copy-page-violations="true" aria-label="Copy all issues on this page">Copy all issues</button>
                                                    <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                </div>
                                            </div>
                                            <div class="modal-page-violations">
                                    <div class="page-violation-item">
                                        <div class="violation-id">region</div>
                                        <div class="violation-help">All page content should be contained by landmarks</div>
                                        <div class="violation-meta">Impact: moderate · 1 node</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/region?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        
                                        <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        <div class="modal-node-list">
                                            <div class="modal-node-item">
                                                <div class="node-selector">Selector: #loading</div>
                                                <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                <div class="node-unique">Unique: 15994268799bcaa31c338ccac4a1142c</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                        </div>
                                    </div>
                                </div>
                            
                    </div>
                </div>

                <div class="panel issues-by-severity" style="margin-top: 1rem;">
                    <h3>Issues grouped by impact</h3>
                    
                        <div class="severity-group" data-severity="critical">
                            <button class="severity-header" type="button" aria-expanded="true">
                                <span class="title">Must Fix</span>
                                <span class="count pill-critical">1 occurrences</span>
                            </button>
                            <div class="severity-content">
                                
                                    <div class="violation-item" data-violation="aria-allowed-attr">
                                        <div class="violation-id">aria-allowed-attr</div>
                                        <div class="violation-help">Elements must only use supported ARIA attributes</div>
                                        <div class="violation-meta">Impact: critical · Pages with issue: 1 / 100 scanned</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/aria-allowed-attr?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        
                                                
                                                <div class="node-fix">Fix all of the following:
  ARIA attribute is not allowed: aria-expanded=&quot;false&quot;</div>
                                                <div class="node-list">
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618" target="_blank" rel="noopener">https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: .c-accordion__action</div>
                                                        <div class="node-html">&lt;div class=&quot;js-toggle c-accordion__action c-accordion__action--background&quot; data-target=&quot;&quot; data-type=&quot;slide&quot; aria-expanded=&quot;false&quot; aria-haspopup=&quot;true&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 869a9fa41b96537b6924dbd677ef5cf2</div>
                                                    
                                                </div>
                                            </div>
                                                
                                            
                                    </div>
                                
                            </div>
                        </div>
                        <div class="severity-group" data-severity="moderate">
                            <button class="severity-header" type="button" aria-expanded="false">
                                <span class="title">Good to Fix</span>
                                <span class="count pill-warning">24 occurrences</span>
                            </button>
                            <div class="severity-content">
                                
                                    <div class="violation-item" data-violation="region">
                                        <div class="violation-id">region</div>
                                        <div class="violation-help">All page content should be contained by landmarks</div>
                                        <div class="violation-meta">Impact: moderate · Pages with issue: 23 / 100 scanned</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/region?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        
                                                <div class="violation-template">Template match: 23 nodes share the same snippet.</div>
                                                <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                                <div class="node-list">
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/" target="_blank" rel="noopener">https://www.regeringen.se/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: e6a17a1c657f683e316c37c7bb9a64ac</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 39882a7acbf61043e56821ff8a17f0f2</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 15994268799bcaa31c338ccac4a1142c</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: a163ff3fed32f1cc820002ea100be5b1</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/justitiedepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/justitiedepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: c3f4a8932cb02e41a17bd39b8cbd249f</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/kulturdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/kulturdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 9e8cb750f0f45f8446363be838dfbfbe</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 5e0cece442264389651ff102fdb84252</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 79f17f18c2e42887a826c536553d61e5</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/arbetsmarknad/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/arbetsmarknad/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 1e25ad217fa21606b2c5ef6204401c6c</div>
                                                    
                                                </div>
                                            
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/barnets-rattigheter/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/barnets-rattigheter/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 27ae83a4dc4bb0a5273ab3219c7330ce</div>
                                                    
                                                </div>
                                            </div>
                                                
                                                    <button class="see-more-btn" onclick="document.getElementById('modal-region').classList.add('open')" type="button">
                                                        See all 23 affected pages
                                                    </button>
                                                    <div id="modal-region" class="modal">
                                                        <div class="modal-content">
                                                            <div class="modal-header">
                                                                <h2>All page content should be contained by landmarks</h2>
                                                                <button class="modal-close" onclick="this.closest('.modal').classList.remove('open')" type="button" aria-label="Close">×</button>
                                                            </div>
                                                            <div class="violation-template">Template match: 23 nodes share the same snippet.</div>
                                                            <div class="node-fix">Fix any of the following:
  Some page content is not contained by landmarks</div>
                                                            <div>
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/" target="_blank" rel="noopener">https://www.regeringen.se/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: e6a17a1c657f683e316c37c7bb9a64ac</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 39882a7acbf61043e56821ff8a17f0f2</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 15994268799bcaa31c338ccac4a1142c</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: a163ff3fed32f1cc820002ea100be5b1</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/justitiedepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/justitiedepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: c3f4a8932cb02e41a17bd39b8cbd249f</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/kulturdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/kulturdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 9e8cb750f0f45f8446363be838dfbfbe</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 5e0cece442264389651ff102fdb84252</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 79f17f18c2e42887a826c536553d61e5</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/arbetsmarknad/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/arbetsmarknad/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 1e25ad217fa21606b2c5ef6204401c6c</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/barnets-rattigheter/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/barnets-rattigheter/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 27ae83a4dc4bb0a5273ab3219c7330ce</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/barn--och-ungdomsutbildning/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/barn--och-ungdomsutbildning/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 5d062fa1c1364c6bdc41f92cf5ea0c38</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/energi/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/energi/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 09db052f6b90095943f57151eac7a383</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/folkhalsa/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/folkhalsa/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 5c2ab02c546f687ca9e23cab568e149f</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/hogskola-forskning-och-rymd/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/hogskola-forskning-och-rymd/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 75862b431d56ec8fabb9668a7622383d</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/jamstalldhet/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/jamstalldhet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: fbe81ab06edbed14c52e578e5c2da146</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/kultur/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/kultur/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 3054578e53b91f3dcac99fa4421c03cd</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/migration-och-asyl/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/migration-och-asyl/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 5cac3c6be31d9471e91047c1f431c7c3</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/miljo-och-klimat/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/miljo-och-klimat/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 8865a952956dfa1f0e0f2aea9da4c2ce</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/psykiatri-och-psykisk-halsa/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/psykiatri-och-psykisk-halsa/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: e68a63c09621532ff1bdcc52fb9649e5</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/rattsvasendet/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/rattsvasendet/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 8a5822dafa7f4636ee2ae326edef7f9c</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/sjukvard/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/sjukvard/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 6a387a1cef3e2078f465c6d81fca09ee</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/socialtjanst/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/socialtjanst/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: d99e61df30646c0a1d674a40dd01b4d8</div>
                                                    
                                                </div>
                                            
                                                <div class="modal-node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/regeringens-politik/transporter-och-infrastruktur/" target="_blank" rel="noopener">https://www.regeringen.se/regeringens-politik/transporter-och-infrastruktur/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: #loading</div>
                                                        <div class="node-html">&lt;img src=&quot;/dist/images/ajax-loader.gif&quot; id=&quot;loading&quot; alt=&quot;Laddar...&quot; style=&quot;display: inline;&quot;&gt;</div>
                                                        <div class="node-unique">Unique: 42f3ab47fa119b4e09c3aa15cdfc7824</div>
                                                    
                                                </div>
                                            </div>
                                                        </div>
                                                    </div>
                                                
                                            
                                    </div>
                                
                                    <div class="violation-item" data-violation="heading-order">
                                        <div class="violation-id">heading-order</div>
                                        <div class="violation-help">Heading levels should only increase by one</div>
                                        <div class="violation-meta">Impact: moderate · Pages with issue: 1 / 100 scanned</div>
                                        <div><a class="learn-more" href="https://dequeuniversity.com/rules/axe/4.11/heading-order?application=playwright" target="_blank" rel="noopener">Learn more</a></div>
                                        <button class="copy-btn" type="button" data-copy-violation="true">Copy failure details</button>
                                        
                                                
                                                <div class="node-fix">Fix any of the following:
  Heading order invalid</div>
                                                <div class="node-list">
                                                <div class="node-item">
                                                    <div class="node-url"><a href="https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/" target="_blank" rel="noopener">https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/</a> (1 node)</div>
                                                    
                                                        <div class="node-selector">Selector: .block--mediavertical__title</div>
                                                        <div class="node-html">&lt;h3 class=&quot;block--mediavertical__title&quot;&gt;Vårbudgeten 2026 på fem minuter&lt;/h3&gt;</div>
                                                        <div class="node-unique">Unique: c2fe2aecc21eaa257c9cd9d6eac8a30b</div>
                                                    
                                                </div>
                                            </div>
                                                
                                            
                                    </div>
                                
                            </div>
                        </div>
                    
                </div>
            </div>

            <!-- Sidebar -->
            <div class="panel">
                <h3>About this scan</h3>
                <div style="margin-bottom: 0.5rem; font-weight: 600;">4/23/2026, 7:41:03 AM (UTC)</div>
                <div style="margin-bottom: 0.25rem;">Target: www.regeringen.se</div>
                <div style="margin-bottom: 0.25rem;">Viewport: Desktop</div>
                <div style="margin-bottom: 0.25rem;">Color scheme: Light</div>
                <div style="margin-bottom: 0.25rem;">Browser: chromium</div>
                <div style="margin-bottom: 0.25rem;">Mode: ci</div>
                <div style="margin-bottom: 0.25rem;">Max pages: 100</div>
                <div style="margin-bottom: 0.25rem;">Sampling: shuffle (seed sweden-weekly)</div>
                <div style="margin-top: 0.5rem;">Pages crawled: 100</div>
                <div>Total occurrences: 25</div>
                <div class="mini-trend" id="miniTrend" data-target="www.regeringen.se" data-viewport="desktop" data-color="light" data-browser="chromium">
                    <h4>Trend (total occurrences)</h4>
                    <svg id="miniTrendChart" viewBox="0 0 100 30" role="img" aria-label="Trend of total occurrences"></svg>
                    <div class="mini-trend-status" id="miniTrendStatus">Loading trend…</div>
                </div>
            </div>
        </div>
    </div>

    <section style="margin-top: 0; max-width: 1200px; margin-left: auto; margin-right: auto; padding: 0 1rem;">
        <div class="panel" style="margin-top: 1rem; background-color: #f5f0d9; border: 1px solid #d8cfa3;">
            <details class="debug-accordion">
                <summary style="cursor: pointer; font-weight: 600; outline: none;">Debug info (run config)</summary>
                <div style="margin-top: 0.75rem;">
                    <ul style="margin-top: 0.25rem; padding-left: 1.25rem; line-height: 1.5;">
                        <li>Mode: ci</li>
                        <li>Viewport: desktop</li>
                        <li>Color scheme: light</li>
                        <li>Browser: chromium</li>
                        <li>Max pages: 100</li>
                        <li>Concurrency: 2</li>
                        <li>Timeout (ms): 30000</li>
                        <li>Base URL: https://www.regeringen.se/</li>
                        <li>Targets: https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618, https://www.regeringen.se/pressmeddelanden/2026/02/regeringen-deltar-vid-munich-security-conference/, https://www.regeringen.se/, https://www.regeringen.se/sveriges-regering/, https://www.regeringen.se/sveriges-regering/statsradsberedningen/, https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/, https://www.regeringen.se/sveriges-regering/finansdepartementet/, https://www.regeringen.se/sveriges-regering/forsvarsdepartementet/, https://www.regeringen.se/sveriges-regering/justitiedepartementet/, https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/, https://www.regeringen.se/sveriges-regering/kulturdepartementet/, https://www.regeringen.se/sveriges-regering/landsbygds--och-infrastrukturdepartementet/, https://www.regeringen.se/sveriges-regering/socialdepartementet/, https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/, https://www.regeringen.se/sveriges-regering/utrikesdepartementet/, https://www.regeringen.se/regeringens-politik/regeringens-prioriteringar/, https://www.regeringen.se/tal/2025/09/regeringsforklaringen-2025/, https://www.regeringen.se/tal/2025/11/eu-deklarationen-regeringens-prioriteringar-i-eu-arbetet/, https://www.regeringen.se/tal/2026/02/utrikesdeklarationen-2026/, https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/, https://www.regeringen.se/sverige-i-eu/, https://www.regeringen.se/regeringens-politik/arbete-mot-utanforskap/, https://www.regeringen.se/regeringens-politik/arbetsmarknad/, https://www.regeringen.se/regeringens-politik/arbetsratt-och-arbetsmiljo/, https://www.regeringen.se/regeringens-politik/barn--och-ungdomsutbildning/, https://www.regeringen.se/regeringens-politik/barnets-rattigheter/, https://www.regeringen.se/regeringens-politik/bolag-med-statligt-agande/, https://www.regeringen.se/regeringens-politik/bostader-och-samhallsplanering/, https://www.regeringen.se/regeringens-politik/civila-samhallet-och-idrott/, https://www.regeringen.se/regeringens-politik/civilt-forsvar/, https://www.regeringen.se/regeringens-politik/demokrati-och-manskliga-rattigheter/, https://www.regeringen.se/regeringens-politik/digitaliseringspolitik/, https://www.regeringen.se/regeringens-politik/ekonomisk-politik/, https://www.regeringen.se/regeringens-politik/energi/, https://www.regeringen.se/regeringens-politik/familjeratt/, https://www.regeringen.se/regeringens-politik/finansmarknad/, https://www.regeringen.se/regeringens-politik/folkbildning/, https://www.regeringen.se/regeringens-politik/folkhalsa/, https://www.regeringen.se/regeringens-politik/folkratt/, https://www.regeringen.se/regeringens-politik/funktionshinder/, https://www.regeringen.se/regeringens-politik/grundlagar-och-integritet/, https://www.regeringen.se/regeringens-politik/handelspolitik-och-framjande/, https://www.regeringen.se/regeringens-politik/hogskola-forskning-och-rymd/, https://www.regeringen.se/regeringens-politik/innovation/, https://www.regeringen.se/regeringens-politik/integration/, https://www.regeringen.se/regeringens-politik/internationellt-utvecklingssamarbete/, https://www.regeringen.se/regeringens-politik/jamstalldhet/, https://www.regeringen.se/regeringens-politik/kommuner-och-regioner/, https://www.regeringen.se/regeringens-politik/konsumentpolitik/, https://www.regeringen.se/regeringens-politik/krisberedskap/, https://www.regeringen.se/regeringens-politik/kultur/, https://www.regeringen.se/regeringens-politik/landsbygd-livsmedel-och-areella-naringar/, https://www.regeringen.se/regeringens-politik/medier/, https://www.regeringen.se/regeringens-politik/migration-och-asyl/, https://www.regeringen.se/regeringens-politik/militart-forsvar/, https://www.regeringen.se/regeringens-politik/miljo-och-klimat/, https://www.regeringen.se/regeringens-politik/nordiska-fragor/, https://www.regeringen.se/regeringens-politik/naringspolitik/, https://www.regeringen.se/regeringens-politik/offentlig-upphandling/, https://www.regeringen.se/regeringens-politik/psykiatri-och-psykisk-halsa/, https://www.regeringen.se/regeringens-politik/regional-utveckling/, https://www.regeringen.se/regeringens-politik/rattsvasendet/, https://www.regeringen.se/regeringens-politik/sjukvard/, https://www.regeringen.se/regeringens-politik/skatt-och-tull/, https://www.regeringen.se/regeringens-politik/socialforsakringar/, https://www.regeringen.se/regeringens-politik/socialtjanst/, https://www.regeringen.se/regeringens-politik/spelpolitik/, https://www.regeringen.se/regeringens-politik/statlig-forvaltning/, https://www.regeringen.se/regeringens-politik/studiefinansiering/, https://www.regeringen.se/regeringens-politik/transporter-och-infrastruktur/, https://www.regeringen.se/regeringens-politik/ungdomspolitik/, https://www.regeringen.se/regeringens-politik/utbildning-for-vuxna/, https://www.regeringen.se/regeringens-politik/utrikes--och-sakerhetspolitik/, https://www.regeringen.se/regeringens-politik/aldreomsorg/, https://www.regeringen.se/dokument-och-publikationer/, https://www.regeringen.se/rattsliga-dokument/, https://www.regeringen.se/rattsliga-dokument/departementsserien-och-promemorior/, https://www.regeringen.se/rattsliga-dokument/forordningsmotiv/, https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/, https://www.regeringen.se/rattsliga-dokument/lagradsremiss/, https://www.regeringen.se/rattsliga-dokument/proposition/, https://www.regeringen.se/rattsliga-dokument/skrivelse/, https://www.regeringen.se/rattsliga-dokument/statens-offentliga-utredningar/, https://www.regeringen.se/rattsliga-dokument/sveriges-internationella-overenskommelser/, https://www.regeringen.se/faktapromemoria/, https://www.regeringen.se/informationsmaterial/, https://www.regeringen.se/internationella-mr-granskningar-av-sverige/, https://www.regeringen.se/kommenterade-dagordningar/, https://www.regeringen.se/rapporter/, https://www.regeringen.se/remisser/, https://www.regeringen.se/regeringsuppdrag/, https://www.regeringen.se/regeringsarenden/, https://www.regeringen.se/sakrad/, https://www.regeringen.se/strategier-for-internationellt-bistand/, https://www.regeringen.se/overenskommelser-och-avtal/, https://www.regeringen.se/sa-styrs-sverige/, https://www.regeringen.se/sa-styrs-sverige/arbetet-pa-nationell-niva/, https://www.regeringen.se/sa-styrs-sverige/arbetet-pa-regional-niva/, https://www.regeringen.se/sa-styrs-sverige/arbetet-pa-lokal-niva/, https://www.regeringen.se/sa-styrs-sverige/myndigheter-och-bolag-med-statligt-agande/</li>
                        <li>Sampling: shuffle (seed sweden-weekly)</li>
                        <li>Results URLs: 100</li>
                        <li>Finished: 2026-04-23T07:43:29.214Z</li>
                    </ul>
                    
                </div>
            </details>
        </div>
    </section>

    <!-- Insights panel: audience summaries + trends -->
    <section id="insights-section" aria-labelledby="insights-heading" hidden>
        <div class="panel">
            <h3 id="insights-heading">Accessibility Insights</h3>
            <p class="insights-intro">Generate audience-specific summaries using in-browser AI (Chrome Prompt API / Gemini Nano, if available). All processing is local — no data leaves your browser. Numbers are computed from scan data and cannot be altered by the model.</p>
            <div id="ai-status" role="status" aria-live="polite">Checking for in-browser AI availability…</div>
            <div class="insights-buttons" role="group" aria-label="Generate accessibility summaries">
                <button id="btn-exec" class="insights-btn" type="button" disabled>Summarize for executives</button>
                <button id="btn-dev" class="insights-btn" type="button" disabled>Summarize for dev team</button>
                <button id="btn-jira" class="insights-btn" type="button" disabled>Generate Jira checklist</button>
                <button id="btn-clear" class="insights-btn" type="button" style="background: var(--muted);" hidden>Clear output</button>
            </div>
            <div id="insights-fallback" class="insights-fallback" hidden></div>
            <div id="insights-output" class="insights-output" aria-live="polite" aria-label="Generated summary output"></div>
            <div class="insights-trends" id="insightsTrends" hidden>
                <h4>Violation trends over time</h4>
                <div class="trends-charts-row">
                    <div class="trend-chart-wrap">
                        <div class="trend-chart-label">Total violations</div>
                        <svg id="insightTrendTotal" class="insight-trend-svg" role="img" aria-label="Total violations over time"></svg>
                    </div>
                    <div class="trend-chart-wrap">
                        <div class="trend-chart-label">Critical + Serious</div>
                        <svg id="insightTrendCritical" class="insight-trend-svg" role="img" aria-label="Critical and serious violations over time"></svg>
                    </div>
                </div>
                <div id="regressionAlerts" class="regression-alerts" role="region" aria-label="Regression alerts"></div>
            </div>
        </div>
    </section>

    <!-- Dedupe and Patterns section -->
    <section id="dedupe-section" aria-labelledby="dedupe-heading" hidden>
        <div class="panel">
            <h3 id="dedupe-heading">Dedupe and Patterns</h3>
            <p class="dedupe-intro">Deterministic deduplication groups repeated findings by signature — no AI needed. In-browser AI clustering (Chrome with Prompt API) reveals root causes and "fix once, remove many" actions. All processing is local — no data leaves your browser.</p>
            <div id="dedupe-summary" class="dedupe-summary-cards" hidden></div>
            <div id="dedupe-ai-status" class="dedupe-ai-status" role="status" aria-live="polite"></div>
            <div class="dedupe-buttons" role="group" aria-label="Dedupe and clustering actions">
                <button id="btn-run-cluster" class="insights-btn" type="button" hidden>Run local clustering (Chrome AI)</button>
                <button id="btn-clear-dedupe" class="insights-btn" type="button" style="background: var(--muted);" hidden>Clear cached clustering</button>
            </div>
            <div id="dedupe-progress" class="dedupe-progress" role="status" aria-live="polite" hidden></div>
            <div id="dedupe-groups-section" hidden>
                <h4>Deduped Groups (<span id="dedupe-groups-count">0</span>)</h4>
                <div id="dedupe-groups-list"></div>
            </div>
            <div id="dedupe-clusters-section" hidden>
                <h4>AI-Identified Patterns (<span id="dedupe-clusters-count">0</span>)</h4>
                <div id="dedupe-clusters-list"></div>
            </div>
            <div id="dedupe-actions-section" hidden>
                <h4>Top Actions</h4>
                <div id="dedupe-actions-list"></div>
            </div>
        </div>
    </section>
    </main>

    <!-- Structured scan data for the Insights panel (not rendered, only parsed by JS) -->
    <script id="reportData" type="application/json">{"scan":{"date":"2026-04-23","pages_scanned":100,"violations_total":25,"by_impact":{"critical":1,"serious":0,"moderate":24,"minor":0},"top_rules":[{"rule_id":"region","count":23,"pages_affected":23,"impact":"moderate","score":1058},{"rule_id":"aria-allowed-attr","count":1,"pages_affected":1,"impact":"critical","score":10},{"rule_id":"heading-order","count":1,"pages_affected":1,"impact":"moderate","score":2}]},"trends":{"window":"last_10_scans","series":[{"date":"2026-03-26","run_id":"www-regeringen-se--2026-03-26T06-34-45-690Z--sweden-weekly-desktop-light-chromium","pages":0,"violations_total":15,"critical":0,"serious":0,"moderate":15,"minor":0},{"date":"2026-03-26","run_id":"www-regeringen-se--2026-03-26T07-40-01-098Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":17,"critical":0,"serious":0,"moderate":17,"minor":0},{"date":"2026-04-02","run_id":"www-regeringen-se--2026-04-02T06-28-46-812Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":19,"critical":1,"serious":1,"moderate":17,"minor":0},{"date":"2026-04-02","run_id":"www-regeringen-se--2026-04-02T07-37-44-983Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":22,"critical":1,"serious":0,"moderate":21,"minor":0},{"date":"2026-04-09","run_id":"www-regeringen-se--2026-04-09T06-38-22-362Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":23,"critical":1,"serious":0,"moderate":22,"minor":0},{"date":"2026-04-09","run_id":"www-regeringen-se--2026-04-09T07-40-15-219Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":22,"critical":1,"serious":0,"moderate":21,"minor":0},{"date":"2026-04-16","run_id":"www-regeringen-se--2026-04-16T06-40-22-861Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":23,"critical":1,"serious":0,"moderate":22,"minor":0},{"date":"2026-04-16","run_id":"www-regeringen-se--2026-04-16T07-37-35-317Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":17,"critical":1,"serious":0,"moderate":16,"minor":0},{"date":"2026-04-23","run_id":"www-regeringen-se--2026-04-23T06-50-33-813Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":16,"critical":1,"serious":0,"moderate":15,"minor":0},{"date":"2026-04-23","run_id":"www-regeringen-se--2026-04-23T07-41-03-322Z--sweden-weekly-desktop-light-chromium","pages":100,"violations_total":25,"critical":1,"serious":0,"moderate":24,"minor":0}],"delta_vs_last":{"violations_total":9,"critical":0,"serious":0},"delta_vs_baseline":{"violations_total":10,"critical":1,"serious":0},"top_movers":[{"rule_id":"region","change":9}],"new_rules":[]},"recommended_priorities":[{"rule_id":"region","count":23,"pages_affected":23,"impact":"moderate","score":1058},{"rule_id":"aria-allowed-attr","count":1,"pages_affected":1,"impact":"critical","score":10},{"rule_id":"heading-order","count":1,"pages_affected":1,"impact":"moderate","score":2}],"constraints":{"no_invented_numbers":true,"no_policy_claims":true,"output_format":"markdown"}}</script>

    <!-- Compact findings for client-side deduplication (not rendered, only parsed by JS) -->
    <script id="findingsData" type="application/json">[{"page":"https://www.regeringen.se/rattsliga-dokument/kommittedirektiv/2026/03/dir.-202618","rule_id":"aria-allowed-attr","impact":"critical","message":"Elements must only use supported ARIA attributes","selector":".c-accordion__action","html_snippet":"<div class=\"js-toggle c-accordion__action c-accordion__action--background\" data-target=\"\" data-type=\"slide\" aria-expanded=\"false\" aria-haspopup=\"true\">"},{"page":"https://www.regeringen.se/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/arbetsmarknadsdepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/finansdepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/klimat--och-naringslivsdepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/justitiedepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/kulturdepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/utbildningsdepartementet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/","rule_id":"heading-order","impact":"moderate","message":"Heading levels should only increase by one","selector":".block--mediavertical__title","html_snippet":"<h3 class=\"block--mediavertical__title\">Vårbudgeten 2026 på fem minuter</h3>"},{"page":"https://www.regeringen.se/sveriges-regering/finansdepartementet/statens-budget/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/arbetsmarknad/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/barnets-rattigheter/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/barn--och-ungdomsutbildning/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/energi/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/folkhalsa/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/hogskola-forskning-och-rymd/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/jamstalldhet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/kultur/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/migration-och-asyl/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/miljo-och-klimat/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/psykiatri-och-psykisk-halsa/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/rattsvasendet/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/sjukvard/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/socialtjanst/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"},{"page":"https://www.regeringen.se/regeringens-politik/transporter-och-infrastruktur/","rule_id":"region","impact":"moderate","message":"All page content should be contained by landmarks","selector":"#loading","html_snippet":"<img src=\"/dist/images/ajax-loader.gif\" id=\"loading\" alt=\"Laddar...\" style=\"display: inline;\">"}]</script>

    <footer aria-label="Report footer">
        <p>
            <strong>O-Hat Scanner</strong> • 
            <a href="https://github.com/civicactions/o-hat-scanner" target="_blank" rel="noopener">View on GitHub</a> • 
            Report design inspired by Oobee
        </p>
    </footer>

    <script>
        // Toggle severity blocks (keyboard accessible)
        document.querySelectorAll('.severity-header').forEach(header => {
            const content = header.nextElementSibling;
            if (header.getAttribute('aria-expanded') === 'true') {
                content.style.display = 'block';
            }
            header.addEventListener('click', () => {
                const expanded = header.getAttribute('aria-expanded') === 'true';
                header.setAttribute('aria-expanded', String(!expanded));
                content.style.display = expanded ? 'none' : 'block';
            });
        });

        // Simple search filtering across issue text and IDs
        const searchInput = document.getElementById('issueSearch');
        searchInput?.addEventListener('input', (e) => {
            const term = e.target.value.toLowerCase();
            document.querySelectorAll('.violation-item').forEach(item => {
                const text = item.textContent.toLowerCase();
                item.style.display = text.includes(term) ? 'block' : 'none';
            });
        });

        // Theme toggle with persistence
        const themeToggle = document.getElementById('theme-toggle');
        const root = document.documentElement;
        const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
        
        // Get user preference from localStorage, or default to system preference
        const savedTheme = localStorage.getItem('report-theme');
        let currentTheme;
        let userHasOverride = false;
        
        if (savedTheme) {
            // User has explicitly set a preference
            currentTheme = savedTheme;
            userHasOverride = true;
        } else {
            // No user override - inherit from browser/OS default
            currentTheme = prefersDarkScheme.matches ? 'dark' : 'light';
        }
        
        function applyTheme(theme) {
            // Set data-theme on root; descendant CSS selectors control icon visibility
            root.setAttribute('data-theme', theme);
            
            // Update button label to reflect the action
            if (themeToggle) {
                if (theme === 'dark') {
                    themeToggle.setAttribute('aria-label', 'Switch to light mode');
                } else {
                    themeToggle.setAttribute('aria-label', 'Switch to dark mode');
                }
            }
        }
        
        themeToggle?.addEventListener('click', () => {
            const newTheme = currentTheme === 'light' ? 'dark' : 'light';
            currentTheme = newTheme;
            userHasOverride = true;
            localStorage.setItem('report-theme', newTheme);
            applyTheme(newTheme);
        });
        
        // Listen for system theme preference changes (only when no user override exists)
        prefersDarkScheme.addEventListener('change', (e) => {
            if (!userHasOverride) {
                currentTheme = e.matches ? 'dark' : 'light';
                applyTheme(currentTheme);
            }
        });
        
        // Apply theme on load
        applyTheme(currentTheme);

        function siteRootPath() {
            const parts = window.location.pathname.split('/');
            const runsIdx = parts.indexOf('runs');
            if (runsIdx > 0) {
                return parts.slice(0, runsIdx).join('/') || '/';
            }
            return '/';
        }

        const homeLogo = document.getElementById('homeLogo');
        if (homeLogo) {
            const root = siteRootPath().replace(/\/$/, '');
            homeLogo.href = root + '/index.html';
        }

        const printButton = document.getElementById('printButton');
        printButton?.addEventListener('click', () => {
            window.print();
        });

        // Mini trend sparkline (reads aggregate.csv)
        const miniChart = document.getElementById('miniTrendChart');
        const miniStatus = document.getElementById('miniTrendStatus');
        const miniContainer = document.getElementById('miniTrend');

        const newlineRe = new RegExp('\\r?\\n');

        function parseAggregateCsv(text) {
            const lines = text.trim().split(newlineRe).filter(Boolean);
            if (!lines.length) return [];
            const headers = lines.shift().split(',');
            return lines.map(line => {
                const cols = line.split(',');
                const row = {};
                headers.forEach((h, idx) => {
                    row[h] = cols[idx] || '';
                });
                return row;
            });
        }

        function drawMiniTrend(rows) {
            if (!miniChart) return;
            miniChart.innerHTML = '';
            const width = 100;
            const height = 30;
            miniChart.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
            const values = rows.map(r => Number(r.totalViolations || 0));
            const minY = Math.min(...values, 0);
            const maxY = Math.max(...values, 1);
            const span = Math.max(maxY - minY, 1);
            const path = rows.map((r, idx) => {
                const x = rows.length === 1 ? width / 2 : (idx / (rows.length - 1)) * width;
                const yVal = Number(r.totalViolations || 0);
                const y = height - ((yVal - minY) / span) * (height - 6) - 3;
                return (idx === 0 ? 'M' : 'L') + x.toFixed(2) + ' ' + y.toFixed(2);
            }).join(' ');

            const pathEl = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            pathEl.setAttribute('d', path || 'M0 15 L100 15');
            pathEl.setAttribute('class', 'mini-line');
            miniChart.appendChild(pathEl);

            rows.forEach((r, idx) => {
                const x = rows.length === 1 ? width / 2 : (idx / (rows.length - 1)) * width;
                const yVal = Number(r.totalViolations || 0);
                const y = height - ((yVal - minY) / span) * (height - 6) - 3;
                const dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                dot.setAttribute('cx', x.toFixed(2));
                dot.setAttribute('cy', y.toFixed(2));
                dot.setAttribute('r', '1.8');
                dot.setAttribute('class', 'mini-dot');
                const titleEl = document.createElementNS('http://www.w3.org/2000/svg', 'title');
                titleEl.textContent = 'Run ' + r.runId + ' total ' + yVal;
                dot.appendChild(titleEl);
                miniChart.appendChild(dot);
            });

            const latest = rows[rows.length - 1];
            const latestValue = Number(latest.totalViolations || 0);
            const latestPages = latest.pagesScanned || 'n/a';
            if (miniStatus) {
                miniStatus.textContent = 'Latest: ' + latestValue + ' occurrences across ' + latestPages + ' pages';
            }
        }

        function rootPathForAggregate() {
            const parts = window.location.pathname.split('/');
            const runsIdx = parts.indexOf('runs');
            if (runsIdx > 0) {
                return parts.slice(0, runsIdx).join('/') || '/';
            }
            return '/';
        }

        function loadMiniTrend() {
            if (!miniContainer || !miniChart || !miniStatus) return;
            miniStatus.textContent = 'Loading trend…';
            const target = miniContainer.dataset.target || '';
            const viewport = miniContainer.dataset.viewport || '';
            const color = miniContainer.dataset.color || '';
            const browser = miniContainer.dataset.browser || '';
            // Note: This duplicates server-side extractDomain logic intentionally.
            // Client-side code runs in browser and can't import server functions.
            const extractDomainFromUrl = (urlString) => {
                if (!urlString) return '';
                try {
                    const url = new URL(urlString);
                    return url.hostname;
                } catch {
                    // Fallback for relative URLs or non-URLs (already normalized strings)
                    return urlString.replace(/\/$/, '');
                }
            };
            const targetDomain = extractDomainFromUrl(target);
            const loadingTimeout = setTimeout(() => {
                if (miniStatus && miniStatus.textContent === 'Loading trend…') {
                    miniStatus.textContent = 'Trend unavailable.';
                }
            }, 4000);

            const aggUrl = rootPathForAggregate().replace(/\/$/, '') + '/aggregate.csv';
            fetch(aggUrl, { cache: 'no-store' }).then(res => {
                if (!res.ok) throw new Error('Missing aggregate.csv');
                return res.text();
            }).then(text => {
                const rows = parseAggregateCsv(text).filter(r => {
                    return r.metricType === 'summary'
                        && r.target === targetDomain
                        && (!viewport || r.viewport === viewport)
                        && (!color || r.colorScheme === color)
                        && (!browser || r.browser === browser);
                }).sort((a, b) => new Date(a.startedAt) - new Date(b.startedAt)).slice(-20);

                if (!rows.length) {
                    miniStatus.textContent = 'No trend data yet for this target.';
                    miniChart.innerHTML = '';
                    return;
                }
                clearTimeout(loadingTimeout);
                drawMiniTrend(rows);
            }).catch(() => {
                clearTimeout(loadingTimeout);
                if (miniStatus) miniStatus.textContent = 'Trend unavailable.';
            });
        }

        loadMiniTrend();

        function buildIssueCopyLines(issue) {
            const id = issue.querySelector('.violation-id')?.textContent?.trim() || 'unknown';
            const help = issue.querySelector('.violation-help')?.textContent?.trim() || 'No description';
            const helpUrl = issue.querySelector('.learn-more')?.href || '';
            const selector = issue.querySelector('.node-selector')?.textContent?.replace('Selector: ', '').trim() || 'N/A';
            const htmlSnippets = issue.querySelectorAll('.node-html');
            const htmlSnippet = htmlSnippets?.[0]?.textContent?.trim() || 'N/A';
            const fixText = issue.querySelector('.node-fix')?.textContent?.trim() || '';
            const pageLink = issue.querySelector('.node-url a[href]');
            const modal = issue.closest('.modal');
            const modalHeader = modal?.querySelector('.modal-header h2')?.textContent?.replace('Issues on ', '').trim();
            const modalPageUrl = modal?.closest('.page-row')?.querySelector('a[href]')?.href || '';
            const pageUrl = pageLink?.href || modalPageUrl || '';
            const pageTitle = pageLink?.textContent?.trim() || modalHeader || pageUrl || 'Unknown page';
            const environment = navigator.userAgent || 'Unknown environment';

            const lines = [];
            lines.push('Title: WCAG ' + id + ': ' + help + ' (' + selector + ')');
            lines.push('Tags: Accessibility, WCAG, ' + id);
            lines.push('');
            lines.push('Issue: ' + help + ' (' + id + (helpUrl ? ' - ' + helpUrl : '') + ')');
            lines.push('');
            lines.push('Target application: ' + pageTitle + (pageUrl ? ' - ' + pageUrl : ''));
            lines.push('');
            lines.push('Element path: ' + selector);
            lines.push('');
            lines.push('Snippet: ' + htmlSnippet);
            lines.push('');
            lines.push('How to fix:');
            if (fixText) {
                lines.push(fixText);
            } else {
                lines.push('See Learn more for guidance.');
            }
            lines.push('');
            lines.push('Environment: ' + environment);
            return lines;
        }

        function buildIssueCopyText(issue) {
            const lines = buildIssueCopyLines(issue);
            lines.push('');
            lines.push('====');
            lines.push('');
            lines.push('This accessibility issue was found using O-Hat Scanner (axe-core).');
            lines.push('https://github.com/civicactions/o-hat-scanner');
            return lines.join('\n');
        }

        function copyTextToClipboard(text) {
            if (navigator.clipboard && window.isSecureContext) {
                return navigator.clipboard.writeText(text);
            }
            const textarea = document.createElement('textarea');
            textarea.value = text;
            textarea.setAttribute('readonly', '');
            textarea.style.position = 'absolute';
            textarea.style.left = '-9999px';
            document.body.appendChild(textarea);
            textarea.select();
            try {
                document.execCommand('copy');
                return Promise.resolve();
            } catch (err) {
                return Promise.reject(err);
            } finally {
                document.body.removeChild(textarea);
            }
        }

        // Copy single violation details from existing DOM content
        document.addEventListener('click', (e) => {
            if (e.target.matches('[data-copy-violation]')) {
                const btn = e.target;
                const issue = btn.closest('.violation-item, .page-violation-item');
                if (!issue) return;
                copyTextToClipboard(buildIssueCopyText(issue)).then(() => {
                    const oldText = btn.textContent;
                    btn.textContent = 'Copied';
                    btn.classList.add('copied');
                    setTimeout(() => { btn.textContent = oldText; btn.classList.remove('copied'); }, 2000);
                }).catch(() => {
                    btn.textContent = 'Copy failed';
                    setTimeout(() => { btn.textContent = 'Copy failure details'; }, 2000);
                });
            }
        });

        // Copy all issues on a page from existing DOM content
        document.addEventListener('click', (e) => {
            if (e.target.matches('[data-copy-page-violations]')) {
                const btn = e.target;
                const modal = btn.closest('.modal');
                const issues = modal?.querySelectorAll('.page-violation-item') || [];
                if (!issues.length) return;
                const header = modal.querySelector('.modal-header h2')?.textContent || 'Page issues';
                const lines = [header, ''];
                issues.forEach((issue, idx) => {
                    lines.push('Issue ' + (idx + 1));
                    lines.push(...buildIssueCopyLines(issue));
                    lines.push('');
                });
                lines.push('====');
                lines.push('');
                lines.push('This accessibility issue was found using O-Hat Scanner (axe-core).');
                lines.push('https://github.com/civicactions/o-hat-scanner');
                copyTextToClipboard(lines.join('\n')).then(() => {
                    const oldText = btn.textContent;
                    btn.textContent = 'Copied all';
                    btn.classList.add('copied');
                    setTimeout(() => { btn.textContent = oldText; btn.classList.remove('copied'); }, 2000);
                }).catch(() => {
                    btn.textContent = 'Copy failed';
                    setTimeout(() => { btn.textContent = 'Copy all issues'; }, 2000);
                });
            }
        });

        // Modal close on outside click
        document.querySelectorAll('.modal').forEach(modal => {
            modal.addEventListener('click', (e) => {
                if (e.target === modal) {
                    modal.classList.remove('open');
                }
            });
        });

        // Escape key closes modal
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                document.querySelectorAll('.modal.open').forEach(modal => {
                    modal.classList.remove('open');
                });
            }
        });

        // ---- Insights panel ----
        // NOTE ON ESCAPING: This block is inside a Node.js template literal.
        // '\\n' in source (4 chars) → '\n' in generated HTML → newline in browser JS.
        // '\x0a' in source → '\x0a' in generated HTML → newline character in browser JS
        // (hex escape sequence, equivalent to \n at runtime).
        (function() {
            const dataEl = document.getElementById('reportData');
            if (!dataEl) return;
            let PAYLOAD;
            try { PAYLOAD = JSON.parse(dataEl.textContent); } catch (e) { return; }
            if (!PAYLOAD) return;

            // runId is embedded at build time (not available as a JS variable in the browser)
            const _runId = "www-regeringen-se--2026-04-23T07-41-03-322Z--sweden-weekly-desktop-light-chromium";

            const scan = PAYLOAD.scan;
            const trends = PAYLOAD.trends;
            const aiStatusEl = document.getElementById('ai-status');
            const btnExec = document.getElementById('btn-exec');
            const btnDev = document.getElementById('btn-dev');
            const btnJira = document.getElementById('btn-jira');
            const btnClear = document.getElementById('btn-clear');
            const outputEl = document.getElementById('insights-output');
            const fallbackEl = document.getElementById('insights-fallback');
            const trendsSection = document.getElementById('insightsTrends');
            const regressionAlertsEl = document.getElementById('regressionAlerts');

            // Show the section (hidden by default for no-JS environments)
            const insightsSection = document.getElementById('insights-section');
            if (insightsSection) insightsSection.removeAttribute('hidden');

            // ---- Trend charts ----
            function drawInsightTrendSvg(svgId, series, valueKey, lineColor) {
                const svg = document.getElementById(svgId);
                if (!svg || series.length < 2) return;
                svg.innerHTML = '';
                const W = 400, H = 100;
                svg.setAttribute('viewBox', '0 0 ' + W + ' ' + H);
                const vals = series.map(s => Number(s[valueKey] || 0));
                const minV = Math.min(...vals, 0);
                const maxV = Math.max(...vals, 1);
                const span = Math.max(maxV - minV, 1);
                const pad = 6;
                const pts = series.map((s, i) => {
                    const x = (i / (series.length - 1)) * (W - pad * 2) + pad;
                    const y = H - pad - ((Number(s[valueKey] || 0) - minV) / span) * (H - pad * 2);
                    return { x, y, val: Number(s[valueKey] || 0), date: s.date };
                });
                // Draw gridlines (3 horizontal)
                for (let g = 0; g <= 2; g++) {
                    const y = pad + (g / 2) * (H - pad * 2);
                    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                    line.setAttribute('x1', pad); line.setAttribute('x2', W - pad);
                    line.setAttribute('y1', y); line.setAttribute('y2', y);
                    line.setAttribute('stroke', 'var(--panel-border)');
                    line.setAttribute('stroke-width', '0.5');
                    svg.appendChild(line);
                }
                // Draw path
                const pathD = pts.map((p, i) => (i === 0 ? 'M' : 'L') + p.x.toFixed(1) + ' ' + p.y.toFixed(1)).join(' ');
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', pathD);
                path.setAttribute('fill', 'none');
                path.setAttribute('stroke', lineColor);
                path.setAttribute('stroke-width', '2');
                svg.appendChild(path);
                // Draw dots with titles
                pts.forEach(p => {
                    const c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                    c.setAttribute('cx', p.x.toFixed(1));
                    c.setAttribute('cy', p.y.toFixed(1));
                    c.setAttribute('r', '3');
                    c.setAttribute('fill', lineColor);
                    const t = document.createElementNS('http://www.w3.org/2000/svg', 'title');
                    t.textContent = p.date + ': ' + p.val;
                    c.appendChild(t);
                    svg.appendChild(c);
                });
                // Max/min labels
                function addLabel(text, x, y) {
                    const tEl = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                    tEl.setAttribute('x', x);
                    tEl.setAttribute('y', y);
                    tEl.setAttribute('fill', 'var(--muted)');
                    tEl.setAttribute('font-size', '8');
                    tEl.textContent = text;
                    svg.appendChild(tEl);
                }
                addLabel(String(maxV), pad + 2, pad + 8);
                addLabel(String(minV), pad + 2, H - pad - 2);
            }

            if (trends.series.length >= 2) {
                drawInsightTrendSvg('insightTrendTotal', trends.series, 'violations_total', 'var(--pill-info)');
                const critSeries = trends.series.map(s => ({ ...s, crit_serious: (s.critical || 0) + (s.serious || 0) }));
                drawInsightTrendSvg('insightTrendCritical', critSeries, 'crit_serious', 'var(--pill-critical)');
                if (trendsSection) trendsSection.removeAttribute('hidden');
            }

            // ---- Regression alerts ----
            if (regressionAlertsEl) {
                const alerts = [];
                if (trends.new_rules && trends.new_rules.length > 0) {
                    alerts.push({ cls: 'new', msg: '⚠ New rule IDs in this scan (not seen previously): ' + trends.new_rules.join(', ') });
                }
                if (trends.delta_vs_last) {
                    const d = trends.delta_vs_last;
                    const critChange = (d.critical || 0) + (d.serious || 0);
                    if (critChange > 0) {
                        alerts.push({ cls: 'spike', msg: '↑ Critical + Serious violations increased by ' + critChange + ' vs last scan.' });
                    } else if (critChange < 0) {
                        alerts.push({ cls: 'improved', msg: '↓ Critical + Serious violations decreased by ' + Math.abs(critChange) + ' vs last scan.' });
                    }
                    if (d.violations_total > 0) {
                        alerts.push({ cls: 'spike', msg: '↑ Total violations increased by ' + d.violations_total + ' vs last scan.' });
                    } else if (d.violations_total < 0) {
                        alerts.push({ cls: 'improved', msg: '↓ Total violations decreased by ' + Math.abs(d.violations_total) + ' vs last scan.' });
                    }
                }
                if (trends.top_movers && trends.top_movers.length > 0) {
                    const risers = trends.top_movers.filter(m => m.change > 0).slice(0, 3);
                    const fallers = trends.top_movers.filter(m => m.change < 0).slice(0, 3);
                    if (risers.length) alerts.push({ cls: 'spike', msg: 'Biggest risers: ' + risers.map(m => m.rule_id + ' (+' + m.change + ')').join(', ') });
                    if (fallers.length) alerts.push({ cls: 'improved', msg: 'Biggest improvements: ' + fallers.map(m => m.rule_id + ' (' + m.change + ')').join(', ') });
                }
                regressionAlertsEl.innerHTML = alerts.map(a => '<div class="regression-alert ' + a.cls + '">' + escHtml(a.msg) + '</div>').join('');
            }

            // ---- Safe escaping for JS-generated HTML ----
            function escHtml(s) {
                return String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
            }

            // ---- Safe markdown renderer (never trusts model output as HTML) ----
            function safeMarkdown(text) {
                // First escape HTML, then apply limited formatting
                let s = String(text || '')
                    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                // Headings
                s = s.replace(/^### (.+)$/gm, '<h5>$1</h5>');
                s = s.replace(/^## (.+)$/gm, '<h4>$1</h4>');
                s = s.replace(/^# (.+)$/gm, '<h3>$1</h3>');
                // Bold / italic
                s = s.replace(/**(.+?)**/g, '<strong>$1</strong>');
                s = s.replace(/*(.+?)*/g, '<em>$1</em>');
                // Unordered lists - first convert "- item" lines to <li>, then group into <ul> blocks
                s = s.replace(/^- (.+)$/gm, '<li>$1</li>');
                const _lines = s.split('\n');
                const _out = [];
                let _inList = false;
                for (const _line of _lines) {
                    if (_line.startsWith('<li>')) {
                        if (!_inList) { _out.push('<ul>'); _inList = true; }
                        _out.push(_line);
                    } else {
                        if (_inList) { _out.push('</ul>'); _inList = false; }
                        _out.push(_line);
                    }
                }
                if (_inList) _out.push('</ul>');
                s = _out.join('\n');
                // Paragraphs (double newline) and line breaks
                s = s.replace(/\n\n/g, '</p><p>');
                s = s.replace(/\n/g, '<br>');
                return '<p>' + s + '</p>';
            }

            // ---- Number validation ----
            function validateNumbers(text) {
                // Extract the set of known numbers from the payload
                const known = new Set([
                    scan.pages_scanned,
                    scan.violations_total,
                    scan.by_impact.critical,
                    scan.by_impact.serious,
                    scan.by_impact.moderate,
                    scan.by_impact.minor
                ].map(String));
                scan.top_rules.forEach(r => { known.add(String(r.count)); known.add(String(r.pages_affected)); });
                if (trends.series.length >= 2) {
                    const prev = trends.series[trends.series.length - 2];
                    known.add(String(prev.violations_total));
                }

                // Find all numeric tokens with 2+ digits in the output and verify they are known.
                // Single-digit numbers (0-9) are intentionally skipped to avoid false positives
                // from common context words like "top 5" or narrative language.
                const found = [...text.matchAll(/(d{2,})/g)].map(m => m[1]);
                const unknown = found.filter(n => !known.has(n));
                return unknown.length === 0;
            }

            // ---- Render output ----
            function renderOutput(text, validated, fromCache) {
                outputEl.innerHTML = '';
                if (!validated) {
                    const warn = document.createElement('div');
                    warn.className = 'ai-warning';
                    warn.textContent = '⚠ Some numbers in this output may not match the scan data exactly. Verify before sharing.';
                    outputEl.appendChild(warn);
                }
                const content = document.createElement('div');
                content.innerHTML = safeMarkdown(text);
                outputEl.appendChild(content);
                if (fromCache) {
                    const note = document.createElement('div');
                    note.className = 'ai-cached-note';
                    note.textContent = 'ℹ Showing cached output. Clear to regenerate.';
                    outputEl.appendChild(note);
                }
                outputEl.classList.add('visible');
                if (btnClear) btnClear.hidden = false;
            }

            // ---- Prompt builders ----
            function buildExecPrompt() {
                const d = trends.delta_vs_last;
                const critSeriousDelta = d ? ((d.critical || 0) + (d.serious || 0)) : 0;
                const dStr = d ? ('vs last scan: total ' + (d.violations_total >= 0 ? '+' : '') + d.violations_total + ', critical+serious ' + (critSeriousDelta >= 0 ? '+' : '') + critSeriousDelta) : 'no prior scan data';
                const topRules = PAYLOAD.recommended_priorities.map(r => r.rule_id + ' (' + r.count + ' occurrences, ' + r.pages_affected + ' pages)').join('; ');
                return [
                    'You are writing an executive accessibility summary. Use ONLY the numbers provided. Do not invent or compute new numbers.',
                    '',
                    'Scan date: ' + scan.date,
                    'Pages scanned: ' + scan.pages_scanned,
                    'Total violations: ' + scan.violations_total,
                    'Critical: ' + scan.by_impact.critical + ', Serious: ' + scan.by_impact.serious + ', Moderate: ' + scan.by_impact.moderate + ', Minor: ' + scan.by_impact.minor,
                    'Trend (' + dStr + ')',
                    'Top issues: ' + topRules,
                    '',
                    'Write a 3-paragraph executive summary. Include: (1) topline trend (serious+critical up/down), (2) what got better/worse and business risk, (3) top 3 recommended actions framed as outcomes (e.g. "reduce form abandonment"). No WCAG jargon. No invented numbers.',
                ].join('\n');
            }

            function buildDevPrompt() {
                const topRules = PAYLOAD.recommended_priorities.map((r, i) =>
                    (i+1) + '. ' + r.rule_id + ' — impact: ' + r.impact + ', ' + r.count + ' occurrences on ' + r.pages_affected + ' pages (score: ' + r.score + ')'
                ).join('\n');
                const movers = (trends.top_movers || []).map(m => m.rule_id + ' ' + (m.change >= 0 ? '+' : '') + m.change).join(', ') || 'none';
                const newR = (trends.new_rules || []).join(', ') || 'none';
                return [
                    'You are writing a dev-team accessibility summary. Use ONLY the numbers provided.',
                    '',
                    'Scan date: ' + scan.date,
                    'Pages: ' + scan.pages_scanned + ', Total violations: ' + scan.violations_total,
                    'By impact — Critical: ' + scan.by_impact.critical + ', Serious: ' + scan.by_impact.serious + ', Moderate: ' + scan.by_impact.moderate + ', Minor: ' + scan.by_impact.minor,
                    '',
                    'Prioritised fix list (computed by severity × pages × count):',
                    topRules,
                    '',
                    'Top movers vs last scan: ' + movers,
                    'New rule IDs not seen before: ' + newR,
                    '',
                    'Write a dev-team summary with: (1) top 5 fix themes with rule IDs, (2) "fix once remove many" component candidates, (3) regression list, (4) notes on manual verification areas. Include rule IDs.',
                ].join('\n');
            }

            function buildJiraPrompt() {
                const epics = PAYLOAD.recommended_priorities.map((r, i) =>
                    '\n### Story ' + (i+1) + ': Fix ' + r.rule_id +
                    '\nSeverity: ' + r.impact + ' | Occurrences: ' + r.count + ' | Affected pages: ' + r.pages_affected +
                    '\nDescription: Remediate ' + r.rule_id + ' violations found in the ' + scan.date + ' accessibility scan.' +
                    '\nAcceptance criteria: Zero ' + r.rule_id + ' violations reported by axe-core on affected pages.' +
                    '\nEvidence: ' + r.count + ' occurrences across ' + r.pages_affected + ' pages.'
                ).join('\n');
                return [
                    'You are creating a Jira-ready accessibility ticket list. Use ONLY the data provided. Do not invent URLs or anchors.',
                    '',
                    'Epic: Accessibility remediation sprint — ' + scan.date,
                    epics,
                    '',
                    'Format each story as a Jira ticket with: Title, Description, Acceptance Criteria, Evidence, Suggested owner (leave blank), Priority (map critical→Highest, serious→High, moderate→Medium, minor→Low).',
                    'Do not invent page URLs. Do not add external links.',
                ].join('\n');
            }

            // ---- Fallback prompt UI (when AI not available) ----
            function showFallbackPrompts() {
                if (!fallbackEl) return;
                const prompts = [
                    { id: 'exec', label: 'Executive summary prompt', fn: buildExecPrompt },
                    { id: 'dev', label: 'Dev team summary prompt', fn: buildDevPrompt },
                    { id: 'jira', label: 'Jira checklist prompt', fn: buildJiraPrompt }
                ];
                fallbackEl.innerHTML = '<p style="font-size:13px; color:var(--muted); margin:0 0 0.5rem 0;">Copy a prompt below and paste it into any AI assistant (ChatGPT, Claude, Gemini, etc.):</p>' +
                    prompts.map(p => {
                        const promptText = p.fn().replace(/\n/g, '\x0a');
                        return '<div class="fallback-prompt-wrap">' +
                            '<div class="fallback-prompt-label">' + escHtml(p.label) + '</div>' +
                            '<div class="fallback-prompt-text" id="fallback-' + p.id + '" tabindex="0" role="region" aria-label="' + escHtml(p.label) + '">' + escHtml(promptText) + '</div>' +
                            '<button class="copy-prompt-btn" type="button" data-fallback-copy="' + p.id + '" aria-label="Copy ' + escHtml(p.label) + '">Copy prompt</button>' +
                        '</div>';
                    }).join('');
                fallbackEl.hidden = false;

                fallbackEl.addEventListener('click', function(e) {
                    const btn = e.target.closest('[data-fallback-copy]');
                    if (!btn) return;
                    const id = btn.dataset.fallbackCopy;
                    const text = document.getElementById('fallback-' + id)?.textContent || '';
                    copyTextToClipboard(text).then(() => {
                        const old = btn.textContent;
                        btn.textContent = 'Copied!';
                        btn.classList.add('copied');
                        setTimeout(() => { btn.textContent = old; btn.classList.remove('copied'); }, 2000);
                    });
                });
            }

            // ---- AI session management ----
            let activeSession = null;

            async function runAI(type, promptFn) {
                const cacheKey = 'insights-' + type + '-' + scan.date + '-' + _runId.slice(-12);
                const cached = localStorage.getItem(cacheKey);
                if (cached) {
                    renderOutput(cached, validateNumbers(cached), true);
                    return;
                }

                if (!window.ai || !window.ai.languageModel) {
                    aiStatusEl.textContent = 'AI not available. Use the copy prompts below.';
                    showFallbackPrompts();
                    return;
                }

                [btnExec, btnDev, btnJira].forEach(b => { b.disabled = true; });
                outputEl.innerHTML = '<p style="color:var(--muted)">Generating…</p>';
                outputEl.classList.add('visible');
                aiStatusEl.textContent = 'Generating summary…';

                try {
                    if (activeSession) { try { activeSession.destroy(); } catch(e) {} activeSession = null; }
                    activeSession = await window.ai.languageModel.create({
                        systemPrompt: 'You are an accessibility expert assistant. Always use only the numbers and data provided. Never invent statistics, URLs, or rule IDs not in the prompt. Output in markdown.'
                    });
                    const promptText = promptFn();
                    const result = await activeSession.prompt(promptText);
                    activeSession.destroy(); activeSession = null;
                    localStorage.setItem(cacheKey, result);
                    renderOutput(result, validateNumbers(result), false);
                    aiStatusEl.textContent = 'Summary generated.';
                } catch (err) {
                    outputEl.innerHTML = '<p style="color:var(--pill-critical)">Error: ' + escHtml(String(err.message || err)) + '</p>';
                    outputEl.classList.add('visible');
                    aiStatusEl.textContent = 'Generation failed.';
                } finally {
                    [btnExec, btnDev, btnJira].forEach(b => { b.disabled = false; });
                }
            }

            btnExec?.addEventListener('click', () => runAI('exec', buildExecPrompt));
            btnDev?.addEventListener('click', () => runAI('dev', buildDevPrompt));
            btnJira?.addEventListener('click', () => runAI('jira', buildJiraPrompt));
            btnClear?.addEventListener('click', () => {
                outputEl.innerHTML = '';
                outputEl.classList.remove('visible');
                if (btnClear) btnClear.hidden = true;
                // Remove cached entries for this run
                ['exec', 'dev', 'jira'].forEach(t => {
                    localStorage.removeItem('insights-' + t + '-' + scan.date + '-' + _runId.slice(-12));
                });
            });

            // ---- AI availability check ----
            async function initAI() {
                if (typeof window === 'undefined' || !window.ai || !window.ai.languageModel) {
                    aiStatusEl.textContent = 'In-browser AI not available. Copy a prompt below to use with any AI tool.';
                    showFallbackPrompts();
                    return;
                }
                try {
                    const caps = await window.ai.languageModel.capabilities();
                    if (caps.available === 'no') {
                        aiStatusEl.textContent = 'AI model not available on this device.';
                        showFallbackPrompts();
                        return;
                    }
                    const readyMsg = caps.available === 'readily'
                        ? 'In-browser AI ready. Click a button to generate a summary.'
                        : 'AI model downloading… generation will start once ready.';
                    aiStatusEl.textContent = readyMsg;
                    [btnExec, btnDev, btnJira].forEach(b => { if (b) b.disabled = false; });
                } catch (e) {
                    aiStatusEl.textContent = 'AI not available. Use the copy prompts below.';
                    showFallbackPrompts();
                }
            }

            initAI();
        })();
    </script>

    <script>
        // ---- Dedupe and Patterns ----
        // NOTE: dedupe-utils functions are inlined below for browser execution.
        (function() {
            // === Inlined dedupe utility functions ===
            /**
 * Pure utility functions for finding deduplication.
 * Used by server-side unit tests (via import) and inlined into the generated report HTML.
 *
 * IMPORTANT: This file must NOT use template literals (backtick characters).
 * It is read at build time by `getDedupeUtilsInline()` in generate-report.js and
 * embedded verbatim inside a Node.js template literal. Any backtick character would
 * terminate that outer template literal and cause a build-time syntax error.
 * Use regular string literals ('single' or "double") throughout this file.
 */

/**
 * Normalize a CSS selector to remove fragile parts.
 * - Removes :nth-child(n) and :nth-of-type(n)
 * - Replaces long numeric suffix IDs (#foo-12345) with #foo-*
 * - Collapses whitespace
 */
function normalizeSelector(selector) {
    if (!selector) return '';
    return String(selector)
        .replace(/:nth-child\(\d+\)/g, '')
        .replace(/:nth-of-type\(\d+\)/g, '')
        .replace(/#([a-zA-Z][a-zA-Z0-9_-]*)-\d{4,}/g, '#$1-*')
        .replace(/\s+/g, ' ')
        .trim();
}

/**
 * Create a stable fingerprint from a finding message.
 * - Lowercases the string
 * - Replaces URLs with *
 * - Replaces numeric sequences with *
 * - Trims whitespace
 */
function fingerprintMessage(msg) {
    if (!msg) return '';
    return String(msg)
        .toLowerCase()
        .replace(/https?:\/\/[^\s]+/g, '*')
        .replace(/\b\d+\b/g, '*')
        .replace(/\s+/g, ' ')
        .trim();
}

/**
 * Create a stable fingerprint for a finding node.
 * Uses normalized selector + first 80 chars of html_snippet.
 */
function nodeFingerprint(finding) {
    var sel = normalizeSelector(finding.selector || '');
    var snippet = String(finding.html_snippet || '').substring(0, 80);
    return sel + '||' + snippet;
}

/**
 * Build a stable signature string for a finding.
 * Signature = rule_id|impact|nodeFingerprint|messageFingerprint
 */
function buildSignature(finding) {
    var impact = String(finding.impact || '').toLowerCase();
    var fp = nodeFingerprint(finding);
    var msgFp = fingerprintMessage(finding.message || '');
    return String(finding.rule_id || '') + '|' + impact + '|' + fp + '|' + msgFp;
}

/**
 * Fast djb2-style hash producing an 8-character hex string.
 * Stable across runs for the same input.
 */
function simpleHash(str) {
    var h = 5381;
    for (var i = 0; i < str.length; i++) {
        h = ((h << 5) + h) ^ str.charCodeAt(i);
        h = h >>> 0;
    }
    return h.toString(16).padStart(8, '0');
}

/**
 * Compute a component hint from example selectors.
 * Returns the most common CSS class that appears in more than one example, or null.
 */
function computeComponentHint(examples) {
    if (!examples || examples.length < 2) return null;
    var classCount = Object.create(null);
    for (var i = 0; i < examples.length; i++) {
        var matches = (examples[i].selector || '').match(/\.([a-zA-Z][a-zA-Z0-9_-]*)/g) || [];
        for (var j = 0; j < matches.length; j++) {
            var cls = matches[j];
            classCount[cls] = (classCount[cls] || 0) + 1;
        }
    }
    var best = null;
    var bestCount = 1;
    var keys = Object.keys(classCount);
    for (var k = 0; k < keys.length; k++) {
        if (classCount[keys[k]] > bestCount) {
            bestCount = classCount[keys[k]];
            best = keys[k];
        }
    }
    return best;
}

/**
 * Group an array of normalized findings by signature.
 * Returns DedupedGroup[] sorted by count descending.
 * Each DedupedGroup: { group_id, rule_id, impact, message, count, pages_affected, examples, component_hint }
 */
function groupFindings(findings) {
    var map = Object.create(null);
    for (var i = 0; i < findings.length; i++) {
        var f = findings[i];
        var sig = buildSignature(f);
        if (!map[sig]) {
            map[sig] = {
                group_id: simpleHash(sig),
                rule_id: f.rule_id || '',
                impact: f.impact || null,
                message: f.message || '',
                count: 0,
                examples: [],
                _pages: Object.create(null)
            };
        }
        var g = map[sig];
        g.count++;
        g._pages[f.page || ''] = true;
        if (g.examples.length < 5) {
            g.examples.push({
                page: f.page || '',
                selector: f.selector || '',
                html_snippet: String(f.html_snippet || '').substring(0, 150)
            });
        }
    }
    var groups = [];
    var sigs = Object.keys(map);
    for (var s = 0; s < sigs.length; s++) {
        var g2 = map[sigs[s]];
        var pagesAffected = Object.keys(g2._pages).length;
        groups.push({
            group_id: g2.group_id,
            rule_id: g2.rule_id,
            impact: g2.impact,
            message: g2.message,
            count: g2.count,
            pages_affected: pagesAffected,
            examples: g2.examples,
            component_hint: computeComponentHint(g2.examples)
        });
    }
    groups.sort(function(a, b) { return b.count - a.count; });
    return groups;
}

            // === Data loading ===
            var findingsEl = document.getElementById('findingsData');
            if (!findingsEl) return;
            var FINDINGS;
            try { FINDINGS = JSON.parse(findingsEl.textContent); } catch(e) { return; }
            if (!Array.isArray(FINDINGS)) return;

            var _runId = "www-regeringen-se--2026-04-23T07-41-03-322Z--sweden-weekly-desktop-light-chromium";
            var _findingsCapped = false;
            var CACHE_PREFIX = 'dedupe-cluster-' + _runId;

            var dedupeSection = document.getElementById('dedupe-section');
            var summaryEl = document.getElementById('dedupe-summary');
            var aiStatusEl = document.getElementById('dedupe-ai-status');
            var clusterBtn = document.getElementById('btn-run-cluster');
            var clearDedupeBtn = document.getElementById('btn-clear-dedupe');
            var progressEl = document.getElementById('dedupe-progress');
            var groupsSection = document.getElementById('dedupe-groups-section');
            var groupsList = document.getElementById('dedupe-groups-list');
            var groupsCountEl = document.getElementById('dedupe-groups-count');
            var clustersSection = document.getElementById('dedupe-clusters-section');
            var clustersList = document.getElementById('dedupe-clusters-list');
            var clustersCountEl = document.getElementById('dedupe-clusters-count');
            var actionsSection = document.getElementById('dedupe-actions-section');
            var actionsList = document.getElementById('dedupe-actions-list');

            if (dedupeSection) dedupeSection.removeAttribute('hidden');

            // Safe HTML escape for inline use
            function escDedupe(s) {
                return String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
            }

            // === Phase A: Deterministic dedupe (always runs) ===
            var groups = groupFindings(FINDINGS);

            // Summary cards
            if (summaryEl) {
                var totalFindings = FINDINGS.length;
                var cards = [
                    { label: 'Total findings', value: totalFindings, sub: _findingsCapped ? 'capped at 5000' : 'all findings' },
                    { label: 'Unique groups', value: groups.length, sub: 'after deduplication' },
                    { label: 'Pages affected', value: (function() {
                        var pages = Object.create(null);
                        for (var i = 0; i < FINDINGS.length; i++) { pages[FINDINGS[i].page || ''] = true; }
                        return Object.keys(pages).length;
                    }()), sub: 'with findings' }
                ];
                cards.forEach(function(c) {
                    var card = document.createElement('div');
                    card.className = 'card';
                    var h = document.createElement('h2');
                    h.textContent = c.label;
                    var v = document.createElement('div');
                    v.className = 'value';
                    v.textContent = String(c.value);
                    var s = document.createElement('div');
                    s.className = 'subtext';
                    s.textContent = c.sub;
                    card.appendChild(h);
                    card.appendChild(v);
                    card.appendChild(s);
                    summaryEl.appendChild(card);
                });
                if (_findingsCapped) {
                    var capNote = document.createElement('p');
                    capNote.className = 'dedupe-cap-note';
                    capNote.textContent = 'Note: Analysis is based on the first 5,000 findings. All findings are shown in the violations list above.';
                    summaryEl.appendChild(capNote);
                }
                summaryEl.removeAttribute('hidden');
            }

            // Render deduped groups list
            if (groupsList && groupsSection) {
                if (groupsCountEl) groupsCountEl.textContent = groups.length;
                var INITIAL_SHOW = 50;
                var shown = groups.slice(0, INITIAL_SHOW);
                shown.forEach(function(g) { groupsList.appendChild(createGroupCard(g)); });
                if (groups.length > INITIAL_SHOW) {
                    var moreBtn = document.createElement('button');
                    moreBtn.className = 'see-more-btn';
                    moreBtn.type = 'button';
                    moreBtn.textContent = 'Show ' + (groups.length - INITIAL_SHOW) + ' more groups';
                    moreBtn.addEventListener('click', function() {
                        groups.slice(INITIAL_SHOW).forEach(function(g) { groupsList.appendChild(createGroupCard(g)); });
                        moreBtn.remove();
                    });
                    groupsList.appendChild(moreBtn);
                }
                groupsSection.removeAttribute('hidden');
            }

            function createGroupCard(group) {
                var div = document.createElement('div');
                div.className = 'dedupe-group-card';
                div.setAttribute('data-group-id', group.group_id);

                var header = document.createElement('div');
                header.className = 'dg-header';
                var ruleEl = document.createElement('span');
                ruleEl.className = 'dg-rule';
                ruleEl.textContent = group.rule_id;
                var countEl = document.createElement('span');
                countEl.className = 'dg-count';
                countEl.textContent = group.count + (group.count !== 1 ? ' occurrences' : ' occurrence');
                header.appendChild(ruleEl);
                header.appendChild(countEl);
                div.appendChild(header);

                var msgEl = document.createElement('div');
                msgEl.className = 'dg-message';
                msgEl.textContent = group.message;
                div.appendChild(msgEl);

                var metaEl = document.createElement('div');
                metaEl.className = 'dg-meta';
                var metaParts = ['Impact: ' + (group.impact || 'unknown'), 'Pages: ' + group.pages_affected];
                if (group.component_hint) metaParts.push('Component hint: ' + group.component_hint);
                metaEl.textContent = metaParts.join(' · ');
                div.appendChild(metaEl);

                if (group.examples.length) {
                    var examplesEl = document.createElement('div');
                    examplesEl.className = 'dg-examples';
                    group.examples.slice(0, 3).forEach(function(ex) {
                        var exDiv = document.createElement('div');
                        exDiv.className = 'dg-example';
                        var pageEl = document.createElement('div');
                        pageEl.className = 'dg-ex-page';
                        pageEl.textContent = ex.page;
                        var selEl = document.createElement('div');
                        selEl.className = 'dg-ex-selector';
                        selEl.textContent = 'Selector: ' + ex.selector;
                        exDiv.appendChild(pageEl);
                        exDiv.appendChild(selEl);
                        examplesEl.appendChild(exDiv);
                    });
                    div.appendChild(examplesEl);
                }
                return div;
            }

            // === Phase B: AI Clustering ===

            // Rule-family mapping for pre-bucketing
            var RULE_FAMILIES = {
                'color-contrast': 'contrast', 'color-contrast-enhanced': 'contrast',
                'image-alt': 'images', 'image-redundant-alt': 'images', 'image-svg-alt': 'images',
                'button-name': 'naming', 'link-name': 'naming', 'input-button-name': 'naming',
                'aria-label': 'naming', 'aria-labelledby': 'naming',
                'heading-order': 'headings', 'empty-heading': 'headings', 'p-as-heading': 'headings',
                'label': 'forms', 'aria-required-attr': 'forms', 'aria-valid-attr': 'forms',
                'select-name': 'forms', 'aria-required-children': 'forms',
                'focus-order-semantics': 'focus', 'tabindex': 'focus', 'focus-trap': 'focus',
                'landmark-one-main': 'landmarks', 'region': 'landmarks', 'bypass': 'landmarks',
                'landmark-no-duplicate-main': 'landmarks', 'landmark-complementary-is-top-level': 'landmarks',
                'td-headers-attr': 'tables', 'th-has-data-cells': 'tables', 'scope-attr-valid': 'tables',
                'frame-title': 'frames', 'frame-tested': 'frames'
            };

            function getFamily(ruleId) {
                if (RULE_FAMILIES[ruleId]) return RULE_FAMILIES[ruleId];
                var keys = Object.keys(RULE_FAMILIES);
                for (var i = 0; i < keys.length; i++) {
                    if (String(ruleId).indexOf(keys[i]) === 0) return RULE_FAMILIES[keys[i]];
                }
                return 'other';
            }

            function bucketGroups(allGroups) {
                var buckets = Object.create(null);
                for (var i = 0; i < allGroups.length; i++) {
                    var family = getFamily(allGroups[i].rule_id);
                    if (!buckets[family]) buckets[family] = [];
                    buckets[family].push(allGroups[i]);
                }
                return buckets;
            }

            function buildBucketPrompt(bucketName, bucketItems) {
                var lines = [
                    'You are an accessibility expert. Analyze these deduped finding groups and identify root-cause clusters.',
                    'Category: ' + bucketName,
                    'Groups (format: [group_id] rule_id | impact | message (count occurrences, N pages)):',
                    ''
                ];
                var MAX_GROUPS = 30;
                var items = bucketItems.slice(0, MAX_GROUPS);
                for (var i = 0; i < items.length; i++) {
                    var g = items[i];
                    lines.push('[' + g.group_id + '] ' + g.rule_id + ' | ' + (g.impact || 'unknown') + ' | ' + g.message + ' (' + g.count + ' occ., ' + g.pages_affected + ' pages)');
                    if (g.examples.length > 0) {
                        lines.push('  Example selector: ' + g.examples[0].selector);
                    }
                }
                lines.push('');
                lines.push('Output ONLY valid JSON with no other text, markdown, or code fences:');
                lines.push('{"clusters":[{"pattern_name":"str","root_cause":"str","primary_fix":["step1","step2"],"evidence":{"rules":["rule_id"],"count":0,"top_examples":[{"page":"url","selector":"sel"}]},"group_ids":["id"],"confidence":0.0}],"top_actions":[{"action":"str","why":"str","estimated_blast_radius":"low|medium|high","clusters_covered":[0]}]}');
                lines.push('');
                lines.push('RULES: Merge groups ONLY when root cause is identical. Do NOT invent pages/selectors not in the input. Keep pattern_name under 8 words. Group IDs must be from the input list. Output valid JSON only.');
                return lines.join('\n');
            }

            function parseClusterResponse(text) {
                // Build the markdown code-fence marker via charCode to avoid embedding backtick
                // characters in source – this JS lives inside a Node.js template literal, and
                // an unescaped backtick would terminate that outer literal at build time.
                var MARKDOWN_CODE_FENCE = String.fromCharCode(96, 96, 96);
                var re1 = new RegExp('^' + MARKDOWN_CODE_FENCE + '[a-z]*', 'm');
                var re2 = new RegExp(MARKDOWN_CODE_FENCE + '\s*$', 'm');
                var cleaned = text.replace(re1, '').replace(re2, '').trim();
                // Try to find JSON object
                var start = cleaned.indexOf('{');
                var end = cleaned.lastIndexOf('}');
                if (start === -1 || end === -1) throw new Error('No JSON object found in response');
                var jsonStr = cleaned.substring(start, end + 1);
                var parsed = JSON.parse(jsonStr);
                if (!Array.isArray(parsed.clusters)) throw new Error('Missing clusters array');
                return parsed;
            }

            function setProgress(msg) {
                if (progressEl) {
                    progressEl.textContent = msg;
                    progressEl.removeAttribute('hidden');
                }
            }

            async function runClustering() {
                if (!window.ai || !window.ai.languageModel) return;

                // Cap AI input to top 200 groups by count
                var AI_MAX_GROUPS = 200;
                var aiGroups = groups.slice(0, AI_MAX_GROUPS);
                var buckets = bucketGroups(aiGroups);
                var bucketNames = Object.keys(buckets);
                var allClusters = [];
                var allActions = [];
                var clusterIdCounter = 0;

                clusterBtn.disabled = true;
                setProgress('Starting clustering…');

                try {
                    var session = await window.ai.languageModel.create({
                        systemPrompt: 'You are an accessibility expert. Output only valid JSON as instructed. Do not include any text outside the JSON.'
                    });

                    for (var bi = 0; bi < bucketNames.length; bi++) {
                        var bucketName = bucketNames[bi];
                        var bucketItems = buckets[bucketName];
                        if (!bucketItems.length) continue;

                        setProgress('Processing bucket ' + (bi + 1) + ' of ' + bucketNames.length + ': ' + bucketName + ' (' + bucketItems.length + ' groups)…');

                        var prompt = buildBucketPrompt(bucketName, bucketItems);
                        var responseText;
                        try {
                            responseText = await session.prompt(prompt);
                        } catch(promptErr) {
                            continue;
                        }

                        try {
                            var parsed = parseClusterResponse(responseText);
                            var bucketClusters = parsed.clusters || [];
                            // Assign stable cluster IDs
                            for (var ci = 0; ci < bucketClusters.length; ci++) {
                                bucketClusters[ci]._cluster_index = clusterIdCounter++;
                            }
                            allClusters = allClusters.concat(bucketClusters);
                            if (parsed.top_actions) {
                                allActions = allActions.concat(parsed.top_actions);
                            }
                        } catch(parseErr) {
                            var errDiv = document.createElement('div');
                            errDiv.className = 'dedupe-error';
                            errDiv.textContent = 'Parse error for ' + bucketName + ' bucket: ' + String(parseErr.message || parseErr);
                            if (clustersSection) {
                                clustersSection.removeAttribute('hidden');
                                clustersList.appendChild(errDiv);
                            }
                        }
                    }

                    try { session.destroy(); } catch(e) {}

                    // Cap top_actions to 10
                    var topActions = allActions.slice(0, 10);

                    // Cache results
                    var cachePayload = JSON.stringify({ clusters: allClusters, top_actions: topActions });
                    try { localStorage.setItem(CACHE_PREFIX, cachePayload); } catch(e) {}

                    renderClusters(allClusters);
                    renderTopActions(topActions);

                    setProgress('Clustering complete. ' + allClusters.length + ' patterns found.');
                    if (clearDedupeBtn) clearDedupeBtn.hidden = false;

                } catch(err) {
                    setProgress('Clustering failed: ' + String(err.message || err));
                } finally {
                    clusterBtn.disabled = false;
                }
            }

            function renderClusters(clusters) {
                if (!clustersSection || !clustersList) return;
                if (clustersCountEl) clustersCountEl.textContent = clusters.length;
                clustersList.innerHTML = '';
                if (!clusters.length) {
                    var emptyMsg = document.createElement('p');
                    emptyMsg.textContent = 'No distinct patterns identified.';
                    emptyMsg.style.color = 'var(--muted)';
                    emptyMsg.style.fontSize = '13px';
                    clustersList.appendChild(emptyMsg);
                } else {
                    clusters.forEach(function(c) {
                        var card = document.createElement('div');
                        card.className = 'dedupe-cluster-card';

                        var nameEl = document.createElement('div');
                        nameEl.className = 'dc-name';
                        nameEl.textContent = String(c.pattern_name || 'Unnamed pattern');
                        card.appendChild(nameEl);

                        var rootEl = document.createElement('div');
                        rootEl.className = 'dc-root-cause';
                        rootEl.textContent = String(c.root_cause || '');
                        card.appendChild(rootEl);

                        var fixSteps = Array.isArray(c.primary_fix) ? c.primary_fix : [];
                        if (fixSteps.length) {
                            var fixTitleEl = document.createElement('div');
                            fixTitleEl.className = 'dc-fix-title';
                            fixTitleEl.textContent = 'How to fix:';
                            card.appendChild(fixTitleEl);
                            var ol = document.createElement('ol');
                            ol.className = 'dc-fix-steps';
                            fixSteps.forEach(function(step) {
                                var li = document.createElement('li');
                                li.textContent = String(step);
                                ol.appendChild(li);
                            });
                            card.appendChild(ol);
                        }

                        var ev = c.evidence || {};
                        var metaEl = document.createElement('div');
                        metaEl.className = 'dc-meta';
                        var rules = Array.isArray(ev.rules) ? ev.rules.join(', ') : '';
                        var metaParts = [];
                        if (rules) metaParts.push('Rules: ' + rules);
                        if (ev.count) metaParts.push(ev.count + ' occurrences');
                        if (c.confidence != null) metaParts.push('Confidence: ' + Math.round(Number(c.confidence) * 100) + '%');
                        metaEl.textContent = metaParts.join(' · ');
                        card.appendChild(metaEl);

                        clustersList.appendChild(card);
                    });
                }
                clustersSection.removeAttribute('hidden');
            }

            function renderTopActions(actions) {
                if (!actionsSection || !actionsList) return;
                actionsList.innerHTML = '';
                if (!actions.length) return;
                actions.forEach(function(a) {
                    var card = document.createElement('div');
                    card.className = 'dedupe-action-card';

                    var titleEl = document.createElement('div');
                    titleEl.className = 'da-title';
                    titleEl.textContent = String(a.action || '');
                    card.appendChild(titleEl);

                    var whyEl = document.createElement('div');
                    whyEl.className = 'da-why';
                    whyEl.textContent = String(a.why || '');
                    card.appendChild(whyEl);

                    var radius = String(a.estimated_blast_radius || 'medium').toLowerCase();
                    if (radius !== 'low' && radius !== 'medium' && radius !== 'high') radius = 'medium';
                    var blastEl = document.createElement('div');
                    blastEl.className = 'da-blast da-blast-' + radius;
                    blastEl.textContent = 'Blast radius: ' + radius;
                    card.appendChild(blastEl);

                    actionsList.appendChild(card);
                });
                actionsSection.removeAttribute('hidden');
            }

            // Check for cached results
            function loadCachedClustering() {
                try {
                    var cached = localStorage.getItem(CACHE_PREFIX);
                    if (!cached) return false;
                    var data = JSON.parse(cached);
                    if (!Array.isArray(data.clusters)) return false;
                    renderClusters(data.clusters);
                    renderTopActions(data.top_actions || []);
                    if (progressEl) {
                        progressEl.textContent = 'Showing cached clustering results.';
                        progressEl.removeAttribute('hidden');
                    }
                    if (clearDedupeBtn) clearDedupeBtn.hidden = false;
                    return true;
                } catch(e) {
                    return false;
                }
            }

            // AI availability check
            async function checkDedupeAI() {
                if (!window.ai || !window.ai.languageModel) {
                    if (aiStatusEl) aiStatusEl.textContent = 'Chrome Prompt API not available in this browser. Only deterministic deduplication is shown.';
                    if (clusterBtn) clusterBtn.hidden = true;
                    return;
                }
                try {
                    var caps = await window.ai.languageModel.capabilities();
                    if (caps.available === 'no') {
                        if (aiStatusEl) aiStatusEl.textContent = 'Chrome AI model not available on this device.';
                        if (clusterBtn) clusterBtn.hidden = true;
                        return;
                    }
                    var msg = caps.available === 'readily'
                        ? 'Chrome AI ready. Click “Run local clustering” to identify root-cause patterns.'
                        : 'Chrome AI model is downloading… try again once it is ready.';
                    if (aiStatusEl) aiStatusEl.textContent = msg;
                    if (clusterBtn) {
                        clusterBtn.hidden = false;
                        clusterBtn.disabled = caps.available !== 'readily';
                    }
                } catch(e) {
                    if (aiStatusEl) aiStatusEl.textContent = 'Chrome AI not available in this browser.';
                    if (clusterBtn) clusterBtn.hidden = true;
                }
            }

            if (clusterBtn) {
                clusterBtn.addEventListener('click', function() {
                    runClustering();
                });
            }

            if (clearDedupeBtn) {
                clearDedupeBtn.addEventListener('click', function() {
                    try { localStorage.removeItem(CACHE_PREFIX); } catch(e) {}
                    if (clustersSection) {
                        clustersSection.setAttribute('hidden', '');
                        if (clustersList) clustersList.innerHTML = '';
                    }
                    if (actionsSection) {
                        actionsSection.setAttribute('hidden', '');
                        if (actionsList) actionsList.innerHTML = '';
                    }
                    if (progressEl) {
                        progressEl.textContent = '';
                        progressEl.setAttribute('hidden', '');
                    }
                    clearDedupeBtn.hidden = true;
                });
            }

            // Load cached clustering results if available, then check AI
            if (!loadCachedClustering()) {
                checkDedupeAI();
            } else {
                // Still show AI status for re-running
                checkDedupeAI();
            }
        })();
    </script>
</body>
</html>