{
  "url": "https://fr.pornhub.com",
  "auditedAt": "2026-07-18T22:10:00.000Z",
  "mode": "report",
  "status": "completed",
  "statusDetail": "Coverage-complete audit of the mandatory age gate plus representative underlying homepage, listing/search/category DOM, video detail, and failure route. Explicit-content screenshots after entry were intentionally not retained; structural probes covered those templates.",
  "page": {
    "appType": "mpa",
    "framework": "server-rendered legacy multi-page application with extensive jQuery-style scripting",
    "notes": "French regional adult-media site. The mandatory age gate overlays content already present in the DOM."
  },
  "evidenceUsed": [
    "screenshot",
    "dom",
    "layout-metrics",
    "evaluate-probe",
    "forced-colors emulation",
    "reduced-motion emulation",
    "trace",
    "har",
    "lighthouse",
    "axe-core",
    "discoverability/raw-html",
    "headers",
    "cookies",
    "trackers",
    "secrets",
    "images",
    "heap-summary",
    "curl robots/sitemap"
  ],
  "guidanceConsulted": [
    "dark-mode",
    "component-specific-light-dark-theme",
    "accessibility",
    "adapt-scrollbar-to-contrast-preferences",
    "same-document-transitions",
    "cross-document-transitions",
    "group-element-transitions",
    "faster-spa-view-transitions",
    "scrollytelling",
    "parallax-scroll-effects",
    "scroll-entry-exit-effects",
    "carousel-slide-effects",
    "physics-based-easing",
    "individual-transform-properties",
    "animate-element-entry-exit",
    "animate-to-from-top-layer",
    "animate-to-intrinsic-sizes",
    "dynamic-sibling-animations",
    "interactive-content-reveal",
    "pull-to-reveal",
    "swipe-to-remove",
    "shrinking-header-on-scroll",
    "scroll-progress-indicator",
    "scroll-position-aware-elements",
    "scroll-snap-realtime-feedback",
    "scroll-snap-state-sync",
    "scroll-target-on-load",
    "soft-edge-content-fade",
    "scrollability-affordance-hints",
    "anchor-positioning-tab-underline",
    "position-aware-tooltips",
    "interest-triggered-tooltips",
    "interest-triggered-action-previews",
    "directional-navigation-transitions",
    "carousel-snap-highlights",
    "navigation-drawer",
    "stack-drill-down",
    "persistent-app-tours",
    "persistent-toast-notifications",
    "light-dismiss-a-dialog",
    "platform-controls-dismiss-dialog",
    "declarative-dialog-popover-control",
    "animated-select-picker",
    "branded-select-styling",
    "brand-consistent-forms",
    "custom-select-picker-layouts",
    "rich-media-picker",
    "complex-shapes",
    "shaped-cutouts",
    "overflow-clipping-control",
    "visually-texture-content",
    "apply-webgl-shaders",
    "interactive-content-in-3d-scenes",
    "highlight-text-ranges",
    "prevent-text-wrapping",
    "customize-scrollbar-color-and-thickness",
    "export-html-media-from-canvas",
    "fluid-scaling",
    "calculate-with-intrinsic-sizes",
    "css-layout",
    "size-aware-styling",
    "content-based-styling",
    "child-state-based-styling",
    "design-token-reactivity",
    "dynamic-sibling-styling",
    "form-fields-automatically-fit-contents",
    "improve-text-layout-and-legibility",
    "forms",
    "accessible-error-announcement",
    "required-field-feedback",
    "validate-input-after-interaction",
    "identify-inp-causes",
    "schedule-tasks-by-priority",
    "optimize-preload-priority",
    "improve-next-page-load-performance",
    "interactions-in-complex-layouts",
    "performance",
    "visually-stable-font-fallbacks",
    "break-up-long-tasks",
    "identify-heavy-scripts",
    "optimize-script-priority",
    "defer-rendering-heavy-content",
    "defer-work-until-scroll-ends",
    "optimize-image-priority",
    "conditional-async-dependencies",
    "expose-canvas-content-to-browser-features",
    "move-dom-element-without-losing-state",
    "precise-text-alignment",
    "visually-stable-mixed-fonts",
    "css",
    "html",
    "reduce-style-repetition",
    "security",
    "privacy",
    "batch-analytics-events",
    "full-session-analytics",
    "calculate-total-foreground-time",
    "passkeys",
    "passkey-registration",
    "passkey-authentication",
    "passkey-reauthentication",
    "passkey-conditional-create",
    "passkey-management",
    "flicker-free-client-side-ab-testing",
    "consistent-cross-document-transitions",
    "stabilize-reactive-state",
    "resilient-context-menus-and-nested-dropdowns",
    "persistent-top-layer-ui",
    "detect-initial-visibility-state",
    "sequence-distributed-events",
    "translator",
    "language-detection",
    "support-global-calendar-systems",
    "capture-location-agnostic-data",
    "format-human-readable-durations",
    "manage-recurring-intervals",
    "calculate-event-differentials",
    "coordinate-global-events",
    "model-partial-time-concepts",
    "search-hidden-content",
    "select-menu-interaction",
    "style-parent-with-has",
    "autofill-address-form",
    "autofill-payment-form",
    "autofill-sign-in-form",
    "autofill-sign-up-form",
    "autofill-highlight-inputs",
    "deliver-optimized-decorative-images",
    "resolution-optimized-pseudo-elements",
    "deprioritize-background-fetches",
    "efficient-background-processing",
    "webmcp",
    "agentic-forms",
    "agentic-javascript-tools",
    "language-model",
    "summarizer"
  ],
  "artifacts": [
    {
      "type": "screenshot",
      "path": "evidence/home-desktop.png",
      "caption": "Desktop initial age gate",
      "condition": "viewport 1440x1000"
    },
    {
      "type": "screenshot",
      "path": "evidence/home-mobile.png",
      "caption": "Mobile age gate showing clipped fixed-width content",
      "condition": "viewport 360x800",
      "findingIds": [
        "F05",
        "F26"
      ]
    },
    {
      "type": "screenshot",
      "path": "evidence/home-dark.png",
      "caption": "Age gate under dark preference",
      "condition": "prefers-color-scheme: dark"
    },
    {
      "type": "screenshot",
      "path": "evidence/home-forced-colors.png",
      "caption": "Age gate under forced colors",
      "condition": "forced-colors: active, prefers-contrast: more"
    },
    {
      "type": "dom",
      "path": "evidence/home-dom.json",
      "caption": "Rendered DOM and computed-style evidence",
      "findingIds": [
        "F04"
      ]
    },
    {
      "type": "layout",
      "path": "evidence/layout-mobile.json",
      "caption": "Mobile CLS and viewport metrics",
      "condition": "viewport 360x800",
      "findingIds": [
        "F11"
      ]
    },
    {
      "type": "layout",
      "path": "evidence/layout-desktop.json",
      "caption": "Desktop CLS and viewport metrics",
      "condition": "viewport 1440x1000"
    },
    {
      "type": "trace",
      "path": "evidence/home-trace.json",
      "caption": "DevTools load trace"
    },
    {
      "type": "trace-summary",
      "path": "evidence/home-trace-summary.json",
      "caption": "Compact trace timing and blocking summary"
    },
    {
      "type": "har",
      "path": "evidence/home.har",
      "caption": "HAR 1.2 network capture"
    },
    {
      "type": "har-summary",
      "path": "evidence/home-summary.json",
      "caption": "Compact request, byte, third-party, and blocking summary",
      "findingIds": [
        "F09",
        "F23",
        "F29",
        "F30"
      ]
    },
    {
      "type": "lighthouse",
      "path": "evidence/lighthouse.json",
      "caption": "Lighthouse performance, accessibility, best-practices, SEO, and agentic audit",
      "findingIds": [
        "F08",
        "F10",
        "F14",
        "F15",
        "F17",
        "F19"
      ]
    },
    {
      "type": "discoverability",
      "path": "evidence/home-discoverability.json",
      "caption": "Raw HTML versus rendered discoverability analysis"
    },
    {
      "type": "screenshot",
      "path": "evidence/home-discoverability-rendered.png",
      "caption": "Rendered browser view"
    },
    {
      "type": "screenshot",
      "path": "evidence/home-discoverability-crawler.png",
      "caption": "JavaScript-disabled crawler view",
      "findingIds": [
        "F25"
      ]
    },
    {
      "type": "heap",
      "path": "evidence/heap-baseline.heapsnapshot",
      "caption": "Baseline readable heap summary"
    },
    {
      "type": "heap",
      "path": "evidence/heap-post.heapsnapshot",
      "caption": "Post-interaction readable heap summary after ten toggles"
    },
    {
      "type": "other",
      "path": "evidence/axe.json",
      "caption": "axe-core accessibility results",
      "findingIds": [
        "F12",
        "F13"
      ]
    },
    {
      "type": "other",
      "path": "evidence/headers.json",
      "caption": "Security response-header audit",
      "findingIds": [
        "F22",
        "F24"
      ]
    },
    {
      "type": "other",
      "path": "evidence/cookies.json",
      "caption": "Cookie flag audit"
    },
    {
      "type": "other",
      "path": "evidence/trackers.json",
      "caption": "Third-party tracker inventory"
    },
    {
      "type": "other",
      "path": "evidence/secrets.json",
      "caption": "Client-side secret scan"
    },
    {
      "type": "other",
      "path": "evidence/images.json",
      "caption": "Image markup and delivery audit",
      "findingIds": [
        "F16",
        "F28"
      ]
    },
    {
      "type": "other",
      "path": "evidence/preferences-features.json",
      "caption": "Preference and modern CSS feature probe",
      "findingIds": [
        "F02",
        "F03",
        "F06"
      ]
    },
    {
      "type": "other",
      "path": "evidence/home-recon.json",
      "caption": "Route, action, language, and metadata recon"
    },
    {
      "type": "other",
      "path": "evidence/home-content-probe.json",
      "caption": "Homepage structural probe"
    },
    {
      "type": "other",
      "path": "evidence/video-detail-probe.json",
      "caption": "Video-detail structural and media probe",
      "findingIds": [
        "F18",
        "F20"
      ]
    },
    {
      "type": "other",
      "path": "evidence/404-probe.json",
      "caption": "Invalid-route behavior probe",
      "findingIds": [
        "F27"
      ]
    },
    {
      "type": "other",
      "path": "evidence/metadata-dialog.json",
      "caption": "Metadata and dialog geometry probe",
      "findingIds": [
        "F21"
      ]
    },
    {
      "type": "other",
      "path": "evidence/memory-targets.json",
      "caption": "Heap-use, DOM-size, focus-target and touch-target probe",
      "findingIds": [
        "F07"
      ]
    },
    {
      "type": "other",
      "path": "evidence/robots.txt",
      "caption": "Observed /robots.txt response body"
    },
    {
      "type": "other",
      "path": "evidence/sitemap.xml",
      "caption": "Observed /sitemap.xml 404 response"
    }
  ],
  "config": {
    "loaded": false
  },
  "coverage": {
    "catalogVersion": "modern-web-guidance@0.0.172",
    "catalogChecksum": "sha256:78ccfdb2d483f4c57d9dafed80fd86c6265585a56457c8dcfddc254b80fb44d7",
    "expected": 58,
    "recorded": 58,
    "judged": 58,
    "blocked": 0,
    "notRun": 0,
    "missing": 0,
    "unknown": 0,
    "duplicates": 0,
    "complete": true
  },
  "checkOutcomes": [
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-color-scheme",
      "status": "pass",
      "confidence": "high",
      "method": "Dark-condition screenshot comparison",
      "evidence": "The age gate is already dark, remains legible under prefers-color-scheme: dark, and does not flash a light surface.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-dark.png"
      ]
    },
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-reduced-motion",
      "status": "pass",
      "confidence": "high",
      "method": "Emulated reduced-motion animation probe",
      "evidence": "With prefers-reduced-motion: reduce active, document.getAnimations() returned zero running animations.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/preferences-features.json"
      ]
    },
    {
      "principleId": "respect-user-preferences",
      "checkId": "respects-contrast",
      "status": "pass",
      "confidence": "high",
      "method": "Forced-colors screenshot inspection",
      "evidence": "Under forced-colors: active and prefers-contrast: more, text, links, borders, and both age-choice buttons remain clearly visible.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-forced-colors.png"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "view-transitions",
      "status": "issues",
      "confidence": "high",
      "method": "CSS and runtime feature-use probe",
      "evidence": "No view-transition rules were found on the age-gate state or representative page templates; state changes use legacy immediate swaps.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/preferences-features.json"
      ],
      "findingIds": [
        "F02"
      ]
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "scroll-driven-animations",
      "status": "not-applicable",
      "confidence": "high",
      "method": "CSS and interaction inventory",
      "evidence": "No scroll-linked animation or scrollytelling surface was observed, so there is no scroll-linked behavior to implement declaratively.",
      "reason": "No scroll-linked animation or scrollytelling surface was observed, so there is no scroll-linked behavior to implement declaratively."
    },
    {
      "principleId": "implement-natural-interactions",
      "checkId": "physical-gestures",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Interaction inventory across representative paths",
      "evidence": "The tested browse, search, category, age-gate, and detail journeys expose no custom swipe, pull, or gesture-driven interaction.",
      "reason": "The tested browse, search, category, age-gate, and detail journeys expose no custom swipe, pull, or gesture-driven interaction."
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "scroll-state-aware-chrome",
      "status": "issues",
      "confidence": "medium",
      "method": "CSS feature probe and long-page DOM review",
      "evidence": "The long listing surface has no scroll-state queries or progress/scroll affordance; chrome remains static.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/preferences-features.json"
      ],
      "findingIds": [
        "F03"
      ]
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "anchored-positioning",
      "status": "not-applicable",
      "confidence": "medium",
      "method": "Overlay inventory and CSS feature probe",
      "evidence": "No tooltip or edge-attached popover requiring anchor positioning was available in the tested unauthenticated journey.",
      "reason": "No tooltip or edge-attached popover requiring anchor positioning was available in the tested unauthenticated journey."
    },
    {
      "principleId": "provide-guided-navigation",
      "checkId": "directs-attention",
      "status": "pass",
      "confidence": "medium",
      "method": "Age-gate screenshot and navigation-label review",
      "evidence": "The mandatory gate uses a central heading, explanatory copy, and two clearly ordered choices; global navigation labels are explicit.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "no-intrusive-interruptions",
      "status": "pass",
      "confidence": "high",
      "method": "Initial-load screenshot and intent review",
      "evidence": "The full-screen age gate is legally and contextually necessary for an adult service, clearly explains its purpose, and offers enter and exit actions.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "semantic-dismissible-primitives",
      "status": "issues",
      "confidence": "high",
      "method": "Rendered DOM primitive inspection",
      "evidence": "The mandatory modal is an ad-hoc DIV with role=dialog rather than a native <dialog>; no native dialog element is present.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-dom.json"
      ],
      "findingIds": [
        "F04"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "checkId": "reduced-chrome",
      "status": "pass",
      "confidence": "high",
      "method": "Desktop screenshot inspection",
      "evidence": "The gate is visually spare: one message, two primary choices, and supporting legal links without competing decoration.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "responsive-no-horizontal-scroll",
      "status": "issues",
      "confidence": "high",
      "method": "360x800 screenshot plus geometry probe",
      "evidence": "The mobile screenshot visibly clips the 780px fixed dialog and the second age-choice button; content extends beyond the viewport even though root overflow is suppressed.",
      "pathIds": [
        "age-gate-mobile"
      ],
      "artifacts": [
        "evidence/home-mobile.png"
      ],
      "findingIds": [
        "F05"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "component-level-responsiveness",
      "status": "issues",
      "confidence": "medium",
      "method": "CSS feature and card-template probe",
      "evidence": "No @container rules were found across reused listing/card templates; responsiveness is viewport-only.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/preferences-features.json"
      ],
      "findingIds": [
        "F06"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "checkId": "input-modality-aware",
      "status": "issues",
      "confidence": "high",
      "method": "Programmatic focus and target-size probe",
      "evidence": "Focusing the first reachable control produced outline:none and box-shadow:none; numerous text controls are only 15–22px high.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/memory-targets.json"
      ],
      "findingIds": [
        "F07"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "clear-purpose-and-primary-action",
      "status": "pass",
      "confidence": "high",
      "method": "First-viewport screenshot and heading review",
      "evidence": "The gate states that this is an adults-only site and presents explicit enter and exit choices.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "primary-flow-completion",
      "status": "issues",
      "confidence": "high",
      "method": "Mobile age-gate walkthrough",
      "evidence": "At 360px the required entry flow is clipped horizontally and the under-18 exit action is largely off-screen, obstructing the first mandatory step.",
      "pathIds": [
        "age-gate-mobile"
      ],
      "artifacts": [
        "evidence/home-mobile.png"
      ],
      "findingIds": [
        "F05"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "checkId": "clear-system-state-and-recovery",
      "status": "pass",
      "confidence": "medium",
      "method": "Gate and invalid-route probe",
      "evidence": "The access state is explicit and reversible through enter/exit actions; an invalid path returns users to the guarded homepage rather than a blank shell.",
      "pathIds": [
        "error-route"
      ],
      "artifacts": [
        "evidence/404-probe.json"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "good-core-web-vitals",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse and trace",
      "evidence": "Lighthouse measured LCP 4.4s (poor) and TTI 7.8s; trace corroborated a 2.30s LCP on a faster run.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F08"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "visual-stability",
      "status": "issues",
      "confidence": "high",
      "method": "Mobile and desktop layout observers",
      "evidence": "Mobile layout CLS was 0.102, just outside the good <=0.1 range; desktop measured 0.062 and Lighthouse 0.095.",
      "pathIds": [
        "age-gate-mobile"
      ],
      "artifacts": [
        "evidence/layout-mobile.json"
      ],
      "findingIds": [
        "F11"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "efficient-main-thread",
      "status": "pass",
      "confidence": "high",
      "method": "Trace and Lighthouse blocking-time review",
      "evidence": "The trace recorded zero long tasks and 0ms TBT; Lighthouse measured 42ms TBT, comfortably good despite 2.4s aggregate main-thread work.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-trace-summary.json"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "efficient-resource-delivery",
      "status": "issues",
      "confidence": "high",
      "method": "HAR summary confirmed against live script attributes",
      "evidence": "The load transfers 6.4MB across 172 requests with seven parser-blocking stylesheets and multiple synchronous head scripts; Lighthouse estimates 450ms render-blocking savings.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-summary.json"
      ],
      "findingIds": [
        "F09"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "checkId": "trim-unused-and-duplicate-code",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse code diagnostics and HAR",
      "evidence": "Lighthouse estimates 286KiB unused JavaScript, 74KiB unused CSS, and 54KiB avoidable legacy JavaScript.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F10"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "names-roles-labels",
      "status": "issues",
      "confidence": "high",
      "method": "axe-core and Lighthouse accessibility audit",
      "evidence": "axe found 30 untitled iframes; the detail probe found 12/12 iframes untitled and one image without alt.",
      "pathIds": [
        "video-detail"
      ],
      "artifacts": [
        "evidence/axe.json"
      ],
      "findingIds": [
        "F12"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "sufficient-contrast",
      "status": "pass",
      "confidence": "medium",
      "method": "Forced-colors visual test plus Lighthouse/axe review",
      "evidence": "Forced-colors preserved all gate controls and text; Lighthouse raised no scored color-contrast failure (axe marked contrast for manual review only).",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-forced-colors.png"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "structure-and-focus",
      "status": "issues",
      "confidence": "high",
      "method": "axe landmark audit and programmatic focus probe",
      "evidence": "axe found 116 regions outside landmarks, and focus can move to a background Cookie Notice link with no visible outline while the modal is active.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/axe.json"
      ],
      "findingIds": [
        "F13"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "legible-text",
      "status": "issues",
      "confidence": "high",
      "method": "360x800 screenshot inspection",
      "evidence": "Large text and legal copy are clipped at the right edge on mobile, requiring unavailable horizontal access and harming comprehension.",
      "pathIds": [
        "age-gate-mobile"
      ],
      "artifacts": [
        "evidence/home-mobile.png"
      ],
      "findingIds": [
        "F05"
      ]
    },
    {
      "principleId": "be-inclusive",
      "checkId": "zoom-reflow-targets-and-media",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse viewport audit, 360px screenshot, media inspection",
      "evidence": "Lighthouse reports a viewport zoom restriction in the audited render; the 360px gate fails reflow, and the tested detail video exposes no caption/subtitle track.",
      "pathIds": [
        "video-detail"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F14"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "no-console-errors",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse runtime log audit",
      "evidence": "Lighthouse scored errors-in-console at 0, confirming browser errors during load.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F15"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "sound-document-and-assets",
      "status": "issues",
      "confidence": "high",
      "method": "DOM/images primitive and Lighthouse",
      "evidence": "Doctype and UTF-8 are valid, but three images lack dimensions and Lighthouse flags unsized images; 33/37 images lack responsive srcset.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/images.json"
      ],
      "findingIds": [
        "F16"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "checkId": "browser-platform-hygiene",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse best-practices diagnostics",
      "evidence": "Lighthouse found two deprecated-API warnings, inspector issues, legacy JS, and four BFCache failure reasons.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F17"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "title-and-description",
      "status": "issues",
      "confidence": "high",
      "method": "DOM metadata probe across entry and detail",
      "evidence": "Both entry and video detail use the generic title “Pornhub”; no meta description is present.",
      "pathIds": [
        "video-detail"
      ],
      "artifacts": [
        "evidence/video-detail-probe.json"
      ],
      "findingIds": [
        "F18"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "crawlable-and-mobile-friendly",
      "status": "issues",
      "confidence": "high",
      "method": "Lighthouse SEO and anchor probe",
      "evidence": "Lighthouse found non-crawlable links and an invalid robots.txt; 30 homepage anchors have empty or javascript: href values.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/lighthouse.json"
      ],
      "findingIds": [
        "F19"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "canonical-and-indexing-signals",
      "status": "issues",
      "confidence": "high",
      "method": "Metadata, HTTP, robots, and sitemap probes",
      "evidence": "Pages ship noindex,nofollow, the detail canonical points to the homepage, /robots.txt redirects to HTML, and /sitemap.xml is a 404.",
      "pathIds": [
        "video-detail"
      ],
      "artifacts": [
        "evidence/video-detail-probe.json"
      ],
      "findingIds": [
        "F20"
      ]
    },
    {
      "principleId": "be-discoverable",
      "checkId": "structured-and-shareable-metadata",
      "status": "issues",
      "confidence": "high",
      "method": "JSON-LD/Open Graph probe",
      "evidence": "No Open Graph tags or JSON-LD were present, including on a concrete video detail page.",
      "pathIds": [
        "video-detail"
      ],
      "artifacts": [
        "evidence/metadata-dialog.json"
      ],
      "findingIds": [
        "F21"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "secure-transport-and-headers",
      "status": "issues",
      "confidence": "high",
      "method": "Headers and cookies primitives",
      "evidence": "HTTPS and HSTS are present, but CSP and nosniff are missing; cookie rp is not Secure and all seven cookies use SameSite=None.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/headers.json"
      ],
      "findingIds": [
        "F22"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "data-minimisation-and-third-parties",
      "status": "issues",
      "confidence": "high",
      "method": "HAR and tracker primitives",
      "evidence": "101/172 requests and 2.39MB are third-party; active Google Tag Manager/DoubleClick tracking and TrafficJunky advertising are present on the age gate.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-summary.json"
      ],
      "findingIds": [
        "F23"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "in-context-permissions-and-modern-auth",
      "status": "pass",
      "confidence": "medium",
      "method": "DOM/script inventory and initial-load behavior",
      "evidence": "No permission prompt appeared on load; the delivered UI includes passkey continuation and passkey.js support for sign-in.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-recon.json"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "checkId": "defensive-browser-policies",
      "status": "issues",
      "confidence": "high",
      "method": "Security-header primitive",
      "evidence": "HSTS and SAMEORIGIN are configured, but CSP/frame-ancestors, Referrer-Policy, Permissions-Policy, and nosniff are absent.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/headers.json"
      ],
      "findingIds": [
        "F24"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "progressive-enhancement",
      "status": "issues",
      "confidence": "high",
      "method": "Raw-HTML discoverability comparison with JS-disabled crawler screenshot",
      "evidence": "Only 29% of rendered content tokens survive in raw HTML and the crawler screenshot is entirely blank, so core guarded content is not usable without JavaScript.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-discoverability.json"
      ],
      "findingIds": [
        "F25"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "resilient-runtime-behaviour",
      "status": "issues",
      "confidence": "high",
      "method": "Narrow-viewport runtime screenshot",
      "evidence": "The mandatory dialog is fixed at 780px and cut off in the 360px runtime, including a primary exit control.",
      "pathIds": [
        "age-gate-mobile"
      ],
      "artifacts": [
        "evidence/home-mobile.png"
      ],
      "findingIds": [
        "F26"
      ]
    },
    {
      "principleId": "be-resilient",
      "checkId": "offline-and-installable",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Manifest/service-worker probe and site-purpose judgement",
      "evidence": "This streaming media service is intrinsically online; no offline/installable intent is declared, so PWA installability is not required.",
      "reason": "This streaming media service is intrinsically online; no offline/installable intent is declared, so PWA installability is not required."
    },
    {
      "principleId": "be-resilient",
      "checkId": "network-and-http-failure-states",
      "status": "issues",
      "confidence": "medium",
      "method": "Invalid-route navigation probe",
      "evidence": "A deliberately invalid path silently redirects to the guarded homepage instead of presenting a clear 404 explanation or recovery choices.",
      "pathIds": [
        "error-route"
      ],
      "artifacts": [
        "evidence/404-probe.json"
      ],
      "findingIds": [
        "F27"
      ]
    },
    {
      "principleId": "be-internationalised",
      "checkId": "lang-dir-and-logical-properties",
      "status": "pass",
      "confidence": "high",
      "method": "DOM language and language-selector inspection",
      "evidence": "The French host declares html lang=fr and the gate offers an accessible language selector with many localized choices; default LTR is appropriate.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-recon.json"
      ]
    },
    {
      "principleId": "be-internationalised",
      "checkId": "locale-aware-data",
      "status": "not-applicable",
      "confidence": "medium",
      "method": "Representative-content inventory",
      "evidence": "The tested guarded entry and browsing metadata exposed no dates, currencies, or locale-sensitive numeric inputs requiring formatting judgement.",
      "reason": "The tested guarded entry and browsing metadata exposed no dates, currencies, or locale-sensitive numeric inputs requiring formatting judgement."
    },
    {
      "principleId": "be-internationalised",
      "checkId": "time-zone-correctness",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Representative-content inventory",
      "evidence": "No scheduling, event, deadline, or user-entered time-zone surface appears in the tested journey.",
      "reason": "No scheduling, event, deadline, or user-entered time-zone surface appears in the tested journey."
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "no-dark-patterns",
      "status": "pass",
      "confidence": "high",
      "method": "Age and cookie gate review",
      "evidence": "The age gate states its purpose plainly and offers symmetric enter/exit choices; cookie controls include an essential-only option without confirmshaming.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-desktop.png"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "humane-error-handling",
      "status": "not-applicable",
      "confidence": "medium",
      "method": "Form inventory",
      "evidence": "The representative unauthenticated browse flow has only a search field and no required data-entry form with validation/error states to exercise.",
      "reason": "The representative unauthenticated browse flow has only a search field and no required data-entry form with validation/error states to exercise."
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "trustworthy-input-assistance",
      "status": "pass",
      "confidence": "medium",
      "method": "Form DOM probe",
      "evidence": "The search input has an accessible name, sensible text type, and no obstruction to native input; account/payment forms were not part of the public browse flow.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-content-probe.json"
      ]
    },
    {
      "principleId": "be-trustworthy",
      "checkId": "safe-commercial-and-account-flows",
      "status": "not-applicable",
      "confidence": "medium",
      "method": "Scope and flow inventory",
      "evidence": "No checkout, subscription purchase, consent change, or authenticated account-management flow was entered; the representative task was public age-gated browsing.",
      "reason": "No checkout, subscription purchase, consent change, or authenticated account-management flow was entered; the representative task was public age-gated browsing."
    },
    {
      "principleId": "be-sustainable",
      "checkId": "optimised-assets",
      "status": "issues",
      "confidence": "high",
      "method": "Images primitive and Lighthouse delivery insight",
      "evidence": "22/37 images use legacy formats, 33 lack srcset, and Lighthouse estimates 510KiB image savings.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/images.json"
      ],
      "findingIds": [
        "F28"
      ]
    },
    {
      "principleId": "be-sustainable",
      "checkId": "no-wasteful-work",
      "status": "issues",
      "confidence": "high",
      "method": "HAR/trace idle-load review",
      "evidence": "The guarded first view still makes 172 requests, including 38 fetch/XHR requests, before the user enters; this is disproportionate background work for a blocking gate.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-summary.json"
      ],
      "findingIds": [
        "F29"
      ]
    },
    {
      "principleId": "be-sustainable",
      "checkId": "third-party-and-media-budget",
      "status": "issues",
      "confidence": "high",
      "method": "HAR and tracker budget review",
      "evidence": "Third parties account for 101 requests and 2.39MB, including 1.17MB from TrafficJunky advertising before age confirmation.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/home-summary.json"
      ],
      "findingIds": [
        "F30"
      ]
    },
    {
      "principleId": "be-agent-ready",
      "checkId": "structured-agent-capabilities",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Agent-capability and intent probe",
      "evidence": "No configuration or site signal declares an agent-facing capability; this emerging check is not required for the guarded adult-media browse experience.",
      "reason": "No configuration or site signal declares an agent-facing capability; this emerging check is not required for the guarded adult-media browse experience."
    },
    {
      "principleId": "be-agent-ready",
      "checkId": "on-device-inference",
      "status": "not-applicable",
      "confidence": "high",
      "method": "Feature inventory and applicability judgement",
      "evidence": "No user task in the audited flow calls for on-device inference, summarisation, or a built-in language model.",
      "reason": "No user task in the audited flow calls for on-device inference, summarisation, or a built-in language model."
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "no-leak-under-repeated-interaction",
      "status": "pass",
      "confidence": "medium",
      "method": "Baseline/post heap snapshots around ten language-control toggles",
      "evidence": "After ten representative gate-control toggles, heap self size fell from 38.53MB to 37.73MB; node count changed by only 0.22%, with no unbounded retained growth signal.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/heap-post.heapsnapshot"
      ]
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "bounded-footprint",
      "status": "pass",
      "confidence": "medium",
      "method": "Heap summary and Performance.memory/DOM probe",
      "evidence": "The loaded gate and underlying listing used about 28MB live JS heap, 38.5MB snapshot self-size, and 1,426 DOM elements, proportionate for this media listing.",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/heap-baseline.heapsnapshot"
      ]
    },
    {
      "principleId": "be-memory-efficient",
      "checkId": "no-detached-dom-or-unbounded-listeners",
      "status": "pass",
      "confidence": "medium",
      "method": "Before/after constructor and node-population comparison",
      "evidence": "No Detached* constructor appears in either top-constructor summary; total heap shrank and closure count was effectively flat (52,365 to 52,374).",
      "pathIds": [
        "home"
      ],
      "artifacts": [
        "evidence/heap-post.heapsnapshot"
      ]
    }
  ],
  "principleOutcomes": [
    {
      "principleId": "respect-user-preferences",
      "expectation": "default",
      "status": "pass"
    },
    {
      "principleId": "implement-natural-interactions",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F02"
      ]
    },
    {
      "principleId": "provide-guided-navigation",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F03"
      ]
    },
    {
      "principleId": "maximize-content-reduce-noise",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F04"
      ]
    },
    {
      "principleId": "adapt-to-the-form-factor",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F05",
        "F06",
        "F07"
      ]
    },
    {
      "principleId": "support-core-task-success",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F05"
      ]
    },
    {
      "principleId": "be-fast-and-stable",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F08",
        "F11",
        "F09",
        "F10"
      ]
    },
    {
      "principleId": "be-inclusive",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F12",
        "F13",
        "F05",
        "F14"
      ]
    },
    {
      "principleId": "follow-best-practices",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F15",
        "F16",
        "F17"
      ]
    },
    {
      "principleId": "be-discoverable",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F18",
        "F19",
        "F20",
        "F21"
      ]
    },
    {
      "principleId": "be-private-and-secure",
      "expectation": "default",
      "status": "issues",
      "findingIds": [
        "F22",
        "F23",
        "F24"
      ]
    },
    {
      "principleId": "be-resilient",
      "expectation": "contextual",
      "status": "issues",
      "findingIds": [
        "F25",
        "F26",
        "F27"
      ]
    },
    {
      "principleId": "be-internationalised",
      "expectation": "contextual",
      "status": "pass"
    },
    {
      "principleId": "be-trustworthy",
      "expectation": "default",
      "status": "pass"
    },
    {
      "principleId": "be-sustainable",
      "expectation": "contextual",
      "status": "issues",
      "findingIds": [
        "F28",
        "F29",
        "F30"
      ]
    },
    {
      "principleId": "be-agent-ready",
      "expectation": "contextual",
      "status": "not-applicable",
      "reason": "No configuration or site signal declares an agent-facing capability; this emerging check is not required for the guarded adult-media browse experience. No user task in the audited flow calls for on-device inference, summarisation, or a built-in language model."
    },
    {
      "principleId": "be-memory-efficient",
      "expectation": "default",
      "status": "pass"
    }
  ],
  "paths": [
    {
      "id": "home",
      "description": "Homepage and mandatory age gate; global template, consent, navigation, metadata, security, performance and privacy.",
      "url": "https://fr.pornhub.com/",
      "conditions": [
        "1440x1000",
        "prefers-color-scheme: dark",
        "forced-colors: active",
        "prefers-reduced-motion: reduce",
        "keyboard focus"
      ],
      "result": "issues"
    },
    {
      "id": "age-gate-mobile",
      "description": "Mandatory first-step age gate at a narrow mobile viewport; core entry/exit journey and reflow.",
      "url": "https://fr.pornhub.com/",
      "conditions": [
        "360x800",
        "touch-sized viewport"
      ],
      "result": "issues"
    },
    {
      "id": "video-listing",
      "description": "Video listing archetype represented by /video; regional routing returned the guarded homepage while underlying listing DOM was structurally probed.",
      "url": "https://fr.pornhub.com/video",
      "conditions": [
        "360x800",
        "age gate present"
      ],
      "result": "issues"
    },
    {
      "id": "categories",
      "description": "Category/index archetype; regional routing returned the guarded homepage, recorded as representative of listing navigation.",
      "url": "https://fr.pornhub.com/categories",
      "conditions": [
        "360x800",
        "age gate present"
      ],
      "result": "issues"
    },
    {
      "id": "search-results",
      "description": "Search-results journey for a benign query; regional routing returned the guarded homepage, while the search form itself was inspected.",
      "url": "https://fr.pornhub.com/video/search?search=podcast",
      "conditions": [
        "360x800",
        "age gate present"
      ],
      "result": "issues"
    },
    {
      "id": "video-detail",
      "description": "Concrete video-detail archetype; DOM, media, headings, canonical, forms, frames and script delivery inspected without retaining explicit post-entry screenshots.",
      "url": "https://fr.pornhub.com/view_video.php?viewkey=ph62bec24b2b75e",
      "conditions": [
        "360x800",
        "age gate present"
      ],
      "result": "issues"
    },
    {
      "id": "error-route",
      "description": "Invalid-route recovery behavior.",
      "url": "https://fr.pornhub.com/this-path-does-not-exist-web-uplift",
      "conditions": [
        "default viewport"
      ],
      "result": "issues"
    }
  ],
  "findings": [
    {
      "id": "F02",
      "severity": "low",
      "confidence": "high",
      "principleId": "implement-natural-interactions",
      "principleCheckId": "view-transitions",
      "guidanceId": "same-document-transitions",
      "guidanceCategory": "web-quality",
      "summary": "State changes do not use View Transitions",
      "evidence": "Runtime/CSS probe found no view-transition usage on the mandatory gate or representative pages.",
      "suggestedFix": "Use same-document View Transitions for gate and major state changes, while honoring reduced motion.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/preferences-features.json"
      ]
    },
    {
      "id": "F03",
      "severity": "low",
      "confidence": "high",
      "principleId": "provide-guided-navigation",
      "principleCheckId": "scroll-state-aware-chrome",
      "guidanceId": "shrinking-header-on-scroll",
      "guidanceCategory": "web-quality",
      "summary": "Long listings lack scroll-state-aware navigation",
      "evidence": "No scroll-state query, progress indicator, or scroll-aware chrome was detected.",
      "suggestedFix": "Add a lightweight scroll-state-aware header or progress/return affordance on long listings.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/preferences-features.json"
      ]
    },
    {
      "id": "F04",
      "severity": "medium",
      "confidence": "high",
      "principleId": "maximize-content-reduce-noise",
      "principleCheckId": "semantic-dismissible-primitives",
      "guidanceId": "declarative-dialog-popover-control",
      "guidanceCategory": "web-quality",
      "summary": "Mandatory modal uses a custom DIV",
      "evidence": "DOM evidence shows role=dialog on a DIV and no native dialog element.",
      "suggestedFix": "Implement the gate with <dialog>, a programmatic accessible name, focus trapping, and native close semantics where appropriate.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/home-dom.json"
      ]
    },
    {
      "id": "F05",
      "severity": "critical",
      "confidence": "high",
      "principleId": "adapt-to-the-form-factor",
      "principleCheckId": "responsive-no-horizontal-scroll",
      "guidanceId": "fluid-scaling",
      "guidanceCategory": "web-quality",
      "summary": "Age gate is clipped on mobile",
      "evidence": "At 360x800 the fixed 780px dialog clips legal copy and the second mandatory choice off-screen.",
      "suggestedFix": "Replace the fixed width with max-inline-size: min(100% - 2rem, 780px), use logical padding, wrap actions, and test 320–400px reflow.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/home-mobile.png"
      ]
    },
    {
      "id": "F06",
      "severity": "low",
      "confidence": "high",
      "principleId": "adapt-to-the-form-factor",
      "principleCheckId": "component-level-responsiveness",
      "guidanceId": "size-aware-styling",
      "guidanceCategory": "web-quality",
      "summary": "Reusable cards do not use component-level responsiveness",
      "evidence": "CSS probe found no @container use across reused listing/card surfaces.",
      "suggestedFix": "Give reusable card/list components containment and adapt their layout with container queries.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/preferences-features.json"
      ]
    },
    {
      "id": "F07",
      "severity": "high",
      "confidence": "high",
      "principleId": "adapt-to-the-form-factor",
      "principleCheckId": "input-modality-aware",
      "guidanceId": "accessibility",
      "guidanceCategory": "web-quality",
      "summary": "Keyboard focus is invisible and targets are cramped",
      "evidence": "Focused controls report outline:none/box-shadow:none; many link-like controls are only 15–22px high.",
      "suggestedFix": "Add :focus-visible rings and enlarge interactive target boxes to at least 24px, preferably 44px for primary touch actions.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/memory-targets.json"
      ]
    },
    {
      "id": "F08",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "good-core-web-vitals",
      "guidanceId": "performance",
      "guidanceCategory": "web-quality",
      "summary": "LCP and interactivity miss the performance bar",
      "evidence": "Lighthouse measured 4.4s LCP and 7.8s TTI.",
      "suggestedFix": "Prioritize the LCP resource, reduce initial document/script work, and defer non-gate content until after consent/entry.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F09",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "efficient-resource-delivery",
      "guidanceId": "optimize-script-priority",
      "guidanceCategory": "web-quality",
      "summary": "Critical path is oversized and render-blocked",
      "evidence": "HAR records 6.4MB/172 requests with parser-blocking CSS/scripts; Lighthouse estimates 450ms render-blocking savings.",
      "suggestedFix": "Inline only gate-critical CSS, defer or module-load scripts, and delay listings/ads/analytics until needed.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/home-summary.json"
      ]
    },
    {
      "id": "F10",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "trim-unused-and-duplicate-code",
      "guidanceId": "identify-heavy-scripts",
      "guidanceCategory": "web-quality",
      "summary": "Large unused and legacy bundles ship on the gate",
      "evidence": "Lighthouse estimates 286KiB unused JS, 74KiB unused CSS, and 54KiB legacy JS savings.",
      "suggestedFix": "Code-split the age gate from the content application and ship a modern, minimal gate bundle.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F11",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-fast-and-stable",
      "principleCheckId": "visual-stability",
      "guidanceId": "visually-stable-font-fallbacks",
      "guidanceCategory": "web-quality",
      "summary": "Mobile CLS is just outside the good range",
      "evidence": "The mobile layout observer measured CLS 0.102.",
      "suggestedFix": "Reserve dimensions for late content and fonts and remove the late gate/layout adjustment causing the shift.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/layout-mobile.json"
      ]
    },
    {
      "id": "F12",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-inclusive",
      "principleCheckId": "names-roles-labels",
      "guidanceId": "accessibility",
      "guidanceCategory": "web-quality",
      "summary": "Advertising/media frames lack accessible names",
      "evidence": "axe found 30 untitled iframes; the detail page had 12/12 untitled.",
      "suggestedFix": "Give every meaningful iframe a concise title and hide non-semantic ad frames from assistive technology when appropriate.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/axe.json"
      ]
    },
    {
      "id": "F13",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-inclusive",
      "principleCheckId": "structure-and-focus",
      "guidanceId": "accessibility",
      "guidanceCategory": "web-quality",
      "summary": "Modal focus and landmark structure are broken",
      "evidence": "Focus reaches a background Cookie Notice link with no visible outline; axe found 116 regions outside landmarks.",
      "suggestedFix": "Use native dialog focus management, inert the background, add visible focus styles, and place content in named landmarks.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/axe.json"
      ]
    },
    {
      "id": "F14",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-inclusive",
      "principleCheckId": "zoom-reflow-targets-and-media",
      "guidanceId": "fluid-scaling",
      "guidanceCategory": "web-quality",
      "summary": "Reflow, zoom, and media alternatives are incomplete",
      "evidence": "Lighthouse flags viewport zoom restrictions, the gate clips at 360px, and the tested video exposes no caption track.",
      "suggestedFix": "Preserve unrestricted zoom, fix 320px reflow, and expose captions/subtitles or an equivalent transcript for media.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F15",
      "severity": "medium",
      "confidence": "high",
      "principleId": "follow-best-practices",
      "principleCheckId": "no-console-errors",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Console errors occur during normal load",
      "evidence": "Lighthouse errors-in-console audit scored 0.",
      "suggestedFix": "Resolve runtime/network errors and add release monitoring that fails on new uncaught errors.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F16",
      "severity": "medium",
      "confidence": "high",
      "principleId": "follow-best-practices",
      "principleCheckId": "sound-document-and-assets",
      "guidanceId": "optimize-image-priority",
      "guidanceCategory": "web-quality",
      "summary": "Image markup is incompletely sized and responsive",
      "evidence": "Three images lack dimensions and 33/37 lack srcset.",
      "suggestedFix": "Declare intrinsic width/height and responsive srcset/sizes for thumbnails and logos.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/images.json"
      ]
    },
    {
      "id": "F17",
      "severity": "medium",
      "confidence": "high",
      "principleId": "follow-best-practices",
      "principleCheckId": "browser-platform-hygiene",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Deprecated APIs and BFCache blockers remain",
      "evidence": "Lighthouse found two deprecations, inspector issues, legacy JS, and four BFCache blockers.",
      "suggestedFix": "Remove deprecated APIs and unload-related BFCache blockers; resolve DevTools Issues and modernize delivery.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F18",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-discoverable",
      "principleCheckId": "title-and-description",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Page titles are generic and descriptions missing",
      "evidence": "Entry and detail pages both use “Pornhub”; no meta description is present.",
      "suggestedFix": "Generate unique localized titles and concise descriptions for each public archetype.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/video-detail-probe.json"
      ]
    },
    {
      "id": "F19",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-discoverable",
      "principleCheckId": "crawlable-and-mobile-friendly",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Links and robots endpoint are not crawler-safe",
      "evidence": "Lighthouse found non-crawlable anchors and 4,073 robots.txt errors; many anchors are empty/javascript links.",
      "suggestedFix": "Use real href destinations and serve a valid text/plain robots.txt without redirecting to HTML.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/lighthouse.json"
      ]
    },
    {
      "id": "F20",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-discoverable",
      "principleCheckId": "canonical-and-indexing-signals",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Indexing signals contradict public detail pages",
      "evidence": "Detail pages use homepage canonical, noindex/nofollow, robots redirects, and sitemap is 404.",
      "suggestedFix": "Choose an explicit regional indexing policy; if pages are public, self-canonicalize, remove accidental noindex, and publish consistent robots/sitemaps.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/video-detail-probe.json"
      ]
    },
    {
      "id": "F21",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-discoverable",
      "principleCheckId": "structured-and-shareable-metadata",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "Detail pages lack structured and social metadata",
      "evidence": "No JSON-LD or Open Graph tags were found on the tested video detail.",
      "suggestedFix": "Add accurate VideoObject JSON-LD and Open Graph metadata matching visible content and regional policy.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/metadata-dialog.json"
      ]
    },
    {
      "id": "F22",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-private-and-secure",
      "principleCheckId": "secure-transport-and-headers",
      "guidanceId": "security",
      "guidanceCategory": "web-quality",
      "summary": "Transport is HTTPS but key protections and cookie flags are weak",
      "evidence": "CSP and nosniff are missing; one cookie lacks Secure and every cookie uses SameSite=None.",
      "suggestedFix": "Deploy a restrictive CSP and nosniff; mark all cookies Secure and use Lax/Strict unless cross-site use is essential.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/headers.json"
      ]
    },
    {
      "id": "F23",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-private-and-secure",
      "principleCheckId": "data-minimisation-and-third-parties",
      "guidanceId": "privacy",
      "guidanceCategory": "web-quality",
      "summary": "Tracking starts before the user enters",
      "evidence": "The gate loads 101 third-party requests/2.39MB, including GTM, DoubleClick, and TrafficJunky.",
      "suggestedFix": "Defer non-essential analytics and advertising until explicit consent and age entry; minimize events and third-party origins.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/home-summary.json"
      ]
    },
    {
      "id": "F24",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-private-and-secure",
      "principleCheckId": "defensive-browser-policies",
      "guidanceId": "security",
      "guidanceCategory": "web-quality",
      "summary": "Defensive browser policies are incomplete",
      "evidence": "Referrer-Policy, Permissions-Policy, CSP/frame-ancestors, and nosniff are absent.",
      "suggestedFix": "Add least-privilege Referrer-Policy and Permissions-Policy plus CSP frame-ancestors and Trusted Types where feasible.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/headers.json"
      ]
    },
    {
      "id": "F25",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-resilient",
      "principleCheckId": "progressive-enhancement",
      "guidanceId": "html",
      "guidanceCategory": "web-quality",
      "summary": "No-JavaScript crawler view is blank",
      "evidence": "Discoverability captured a blank crawler screenshot and only 29% raw/rendered token coverage.",
      "suggestedFix": "Server-render the age notice and essential navigation/actions, using JavaScript only to enhance behavior.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/home-discoverability-crawler.png"
      ]
    },
    {
      "id": "F26",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-resilient",
      "principleCheckId": "resilient-runtime-behaviour",
      "guidanceId": "fluid-scaling",
      "guidanceCategory": "web-quality",
      "summary": "Mandatory runtime UI is cut off at narrow widths",
      "evidence": "The 780px fixed modal exceeds a 360px viewport and clips actions.",
      "suggestedFix": "Use intrinsic sizing and wrapped actions so the modal survives narrow and zoomed conditions.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/home-mobile.png"
      ]
    },
    {
      "id": "F27",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-resilient",
      "principleCheckId": "network-and-http-failure-states",
      "guidanceId": "persistent-toast-notifications",
      "guidanceCategory": "web-quality",
      "summary": "Invalid routes fail silently",
      "evidence": "A deliberately invalid path redirected to the homepage without a 404 explanation.",
      "suggestedFix": "Return a correct 404 status and a localized recovery page with search, home, and back actions.",
      "effort": "small",
      "pathId": "home",
      "artifacts": [
        "evidence/404-probe.json"
      ]
    },
    {
      "id": "F28",
      "severity": "medium",
      "confidence": "high",
      "principleId": "be-sustainable",
      "principleCheckId": "optimised-assets",
      "guidanceId": "deliver-optimized-decorative-images",
      "guidanceCategory": "web-quality",
      "summary": "Images miss modern responsive delivery",
      "evidence": "22/37 images are legacy formats, 33 lack srcset, and Lighthouse estimates 510KiB savings.",
      "suggestedFix": "Negotiate AVIF/WebP, provide responsive sources, and retain explicit dimensions.",
      "effort": "medium",
      "pathId": "home",
      "artifacts": [
        "evidence/images.json"
      ]
    },
    {
      "id": "F29",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-sustainable",
      "principleCheckId": "no-wasteful-work",
      "guidanceId": "deprioritize-background-fetches",
      "guidanceCategory": "web-quality",
      "summary": "The blocking age gate still loads the full application",
      "evidence": "Before entry the page performs 172 requests, including 38 fetch/XHR operations.",
      "suggestedFix": "Serve a minimal gate and defer listing data, recommendations, ad auctions, and secondary scripts until entry/consent.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/home-summary.json"
      ]
    },
    {
      "id": "F30",
      "severity": "high",
      "confidence": "high",
      "principleId": "be-sustainable",
      "principleCheckId": "third-party-and-media-budget",
      "guidanceId": "efficient-background-processing",
      "guidanceCategory": "web-quality",
      "summary": "Third-party budget is disproportionate on first view",
      "evidence": "Third parties contribute 101 requests and 2.39MB; TrafficJunky alone transfers 1.17MB.",
      "suggestedFix": "Set and enforce a third-party byte/request budget and load advertising only after the guarded flow completes.",
      "effort": "large",
      "pathId": "home",
      "artifacts": [
        "evidence/home-summary.json"
      ]
    }
  ],
  "taskList": [
    {
      "id": "T01",
      "title": "Replace the fixed width with max-inline-size: min(100% - 2rem, 780px), use logical padding, wrap actions, and test 320–400px reflow.",
      "priority": 1,
      "findingIds": [
        "F05"
      ],
      "guidanceId": "fluid-scaling",
      "status": "open"
    },
    {
      "id": "T02",
      "title": "Add :focus-visible rings and enlarge interactive target boxes to at least 24px, preferably 44px for primary touch actions.",
      "priority": 2,
      "findingIds": [
        "F07"
      ],
      "guidanceId": "accessibility",
      "status": "open"
    },
    {
      "id": "T03",
      "title": "Prioritize the LCP resource, reduce initial document/script work, and defer non-gate content until after consent/entry.",
      "priority": 3,
      "findingIds": [
        "F08"
      ],
      "guidanceId": "performance",
      "status": "open"
    },
    {
      "id": "T04",
      "title": "Inline only gate-critical CSS, defer or module-load scripts, and delay listings/ads/analytics until needed.",
      "priority": 4,
      "findingIds": [
        "F09"
      ],
      "guidanceId": "optimize-script-priority",
      "status": "open"
    },
    {
      "id": "T05",
      "title": "Give every meaningful iframe a concise title and hide non-semantic ad frames from assistive technology when appropriate.",
      "priority": 5,
      "findingIds": [
        "F12"
      ],
      "guidanceId": "accessibility",
      "status": "open"
    },
    {
      "id": "T06",
      "title": "Use native dialog focus management, inert the background, add visible focus styles, and place content in named landmarks.",
      "priority": 6,
      "findingIds": [
        "F13"
      ],
      "guidanceId": "accessibility",
      "status": "open"
    },
    {
      "id": "T07",
      "title": "Preserve unrestricted zoom, fix 320px reflow, and expose captions/subtitles or an equivalent transcript for media.",
      "priority": 7,
      "findingIds": [
        "F14"
      ],
      "guidanceId": "fluid-scaling",
      "status": "open"
    },
    {
      "id": "T08",
      "title": "Generate unique localized titles and concise descriptions for each public archetype.",
      "priority": 8,
      "findingIds": [
        "F18"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T09",
      "title": "Use real href destinations and serve a valid text/plain robots.txt without redirecting to HTML.",
      "priority": 9,
      "findingIds": [
        "F19"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T10",
      "title": "Choose an explicit regional indexing policy; if pages are public, self-canonicalize, remove accidental noindex, and publish consistent robots/sitemaps.",
      "priority": 10,
      "findingIds": [
        "F20"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T11",
      "title": "Deploy a restrictive CSP and nosniff; mark all cookies Secure and use Lax/Strict unless cross-site use is essential.",
      "priority": 11,
      "findingIds": [
        "F22"
      ],
      "guidanceId": "security",
      "status": "open"
    },
    {
      "id": "T12",
      "title": "Defer non-essential analytics and advertising until explicit consent and age entry; minimize events and third-party origins.",
      "priority": 12,
      "findingIds": [
        "F23"
      ],
      "guidanceId": "privacy",
      "status": "open"
    },
    {
      "id": "T13",
      "title": "Server-render the age notice and essential navigation/actions, using JavaScript only to enhance behavior.",
      "priority": 13,
      "findingIds": [
        "F25"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T14",
      "title": "Use intrinsic sizing and wrapped actions so the modal survives narrow and zoomed conditions.",
      "priority": 14,
      "findingIds": [
        "F26"
      ],
      "guidanceId": "fluid-scaling",
      "status": "open"
    },
    {
      "id": "T15",
      "title": "Serve a minimal gate and defer listing data, recommendations, ad auctions, and secondary scripts until entry/consent.",
      "priority": 15,
      "findingIds": [
        "F29"
      ],
      "guidanceId": "deprioritize-background-fetches",
      "status": "open"
    },
    {
      "id": "T16",
      "title": "Set and enforce a third-party byte/request budget and load advertising only after the guarded flow completes.",
      "priority": 16,
      "findingIds": [
        "F30"
      ],
      "guidanceId": "efficient-background-processing",
      "status": "open"
    },
    {
      "id": "T17",
      "title": "Implement the gate with <dialog>, a programmatic accessible name, focus trapping, and native close semantics where appropriate.",
      "priority": 17,
      "findingIds": [
        "F04"
      ],
      "guidanceId": "declarative-dialog-popover-control",
      "status": "open"
    },
    {
      "id": "T18",
      "title": "Code-split the age gate from the content application and ship a modern, minimal gate bundle.",
      "priority": 18,
      "findingIds": [
        "F10"
      ],
      "guidanceId": "identify-heavy-scripts",
      "status": "open"
    },
    {
      "id": "T19",
      "title": "Reserve dimensions for late content and fonts and remove the late gate/layout adjustment causing the shift.",
      "priority": 19,
      "findingIds": [
        "F11"
      ],
      "guidanceId": "visually-stable-font-fallbacks",
      "status": "open"
    },
    {
      "id": "T20",
      "title": "Resolve runtime/network errors and add release monitoring that fails on new uncaught errors.",
      "priority": 20,
      "findingIds": [
        "F15"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T21",
      "title": "Declare intrinsic width/height and responsive srcset/sizes for thumbnails and logos.",
      "priority": 21,
      "findingIds": [
        "F16"
      ],
      "guidanceId": "optimize-image-priority",
      "status": "open"
    },
    {
      "id": "T22",
      "title": "Remove deprecated APIs and unload-related BFCache blockers; resolve DevTools Issues and modernize delivery.",
      "priority": 22,
      "findingIds": [
        "F17"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T23",
      "title": "Add accurate VideoObject JSON-LD and Open Graph metadata matching visible content and regional policy.",
      "priority": 23,
      "findingIds": [
        "F21"
      ],
      "guidanceId": "html",
      "status": "open"
    },
    {
      "id": "T24",
      "title": "Add least-privilege Referrer-Policy and Permissions-Policy plus CSP frame-ancestors and Trusted Types where feasible.",
      "priority": 24,
      "findingIds": [
        "F24"
      ],
      "guidanceId": "security",
      "status": "open"
    },
    {
      "id": "T25",
      "title": "Return a correct 404 status and a localized recovery page with search, home, and back actions.",
      "priority": 25,
      "findingIds": [
        "F27"
      ],
      "guidanceId": "persistent-toast-notifications",
      "status": "open"
    },
    {
      "id": "T26",
      "title": "Negotiate AVIF/WebP, provide responsive sources, and retain explicit dimensions.",
      "priority": 26,
      "findingIds": [
        "F28"
      ],
      "guidanceId": "deliver-optimized-decorative-images",
      "status": "open"
    },
    {
      "id": "T27",
      "title": "Use same-document View Transitions for gate and major state changes, while honoring reduced motion.",
      "priority": 27,
      "findingIds": [
        "F02"
      ],
      "guidanceId": "same-document-transitions",
      "status": "open"
    },
    {
      "id": "T28",
      "title": "Add a lightweight scroll-state-aware header or progress/return affordance on long listings.",
      "priority": 28,
      "findingIds": [
        "F03"
      ],
      "guidanceId": "shrinking-header-on-scroll",
      "status": "open"
    },
    {
      "id": "T29",
      "title": "Give reusable card/list components containment and adapt their layout with container queries.",
      "priority": 29,
      "findingIds": [
        "F06"
      ],
      "guidanceId": "size-aware-styling",
      "status": "open"
    }
  ],
  "budget": {
    "wallClockSeconds": 900,
    "pathCount": 7,
    "auditPasses": 1
  },
  "agent": "pi",
  "runId": "2026-07-18T21-57-10-231Z"
}
