{"url":"https://play.ee/","date":"2026-07-15","siteName":"Perfectly formed web development team - gotoAndPlay","overall":75,"reasoning":"Site overall 75 is the mean of 7 pages. Scores range 72 (https://play.ee/web-development-in-estonia/) → 78 (https://play.ee/wordpress-support-service/). Weakest page: PSI mobile 93 (desktop 100) shows strong performance, but LCP 2.6 s and FCP 1.99 s are in warning zones. Security headers score 20/100 is a major drag — HTTP does not redirect to HTTPS, HSTS missing, CSP weak. Accessibility has 1 serious color-contrast violation affecting 21+ nodes plus missing main landmark. W3C validator reports 7 errors with parser recovery failure at line 100. Image dimensions missing on 69 images is a CLS risk despite current 0.000 CLS score.","confidence":"high","fixes":[{"priority":1,"title":"Force HTTPS Redirect and Add HSTS","impact":"Security, Transport Layer","problem":"Security Headers report shows 'http://play.ee/ does not redirect to HTTPS' and 'strict-transport-security missing'.","solution":"Configure the web server to redirect all HTTP traffic to HTTPS (301) and send the HSTS header:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\n```"},{"priority":1,"title":"Enforce HTTPS and add HSTS","impact":"Security, Transport Layer","problem":"Security Headers tool reports HTTP does not redirect to HTTPS and HSTS is missing (Score 20/100).","solution":"Configure server to redirect all HTTP traffic to HTTPS and send HSTS header:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n```"},{"priority":1,"title":"Enforce HTTPS redirect and add HSTS","impact":"Security, Trust, SEO","problem":"HTTP does not redirect to HTTPS and HSTS is missing (Security Headers grade 20/100).","solution":"Configure server to redirect all HTTP traffic to HTTPS immediately.\nAdd HSTS header:\n`Strict-Transport-Security: max-age=63072000; includeSubDomains; preload`"},{"priority":1,"title":"Fix W3C HTML Validation Errors","impact":"DOM Integrity, SEO, Rendering","problem":"7 validation errors including parser recovery failure at line 100 (iframe in noscript in head).","solution":"Move `<noscript><iframe>` out of `<head>` or ensure it is valid HTML5.\nRemove stray end tags (`</noscript>`, `</head>`).\nFix meta tag attributes (`name` not allowed in this context)."},{"priority":1,"title":"Fix Serious Accessibility Violations","impact":"WCAG 1.4.3 (Contrast), 2.4.4 (Link Purpose)","problem":"axe-core reports 2 serious violations: color-contrast on multiple text nodes and link-name on logo grid links.","solution":"- Increase contrast ratio for `.button--tertiary` and `.capabilities__heading` text to ≥4.5:1.\n- Add `aria-label` to logo grid links (e.g., `<a href=\"\" aria-label=\"Client Logo\">`)."},{"priority":1,"title":"Force HTTPS redirect for all HTTP requests","impact":"Transport security, SEO","problem":"http://play.ee/web-development-in-estonia/ does not redirect to HTTPS — critical security exposure.","solution":"Configure server to redirect all HTTP to HTTPS:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n```"},{"priority":1,"title":"Add HSTS and X-Content-Type-Options headers","impact":"Transport security, MIME sniffing","problem":"HSTS and X-Content-Type-Options missing — security headers score 20/100.","solution":"Add to server config:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\n```"},{"priority":1,"title":"Fix color contrast on headings and cards","impact":"WCAG 1.4.3 (Contrast), Accessibility","problem":"axe-core reports 1 serious violation for color-contrast on multiple nodes (h1, .card__title, etc.).","solution":"Increase contrast ratio to at least 4.5:1 for normal text. Adjust CSS for `.heading__main` and `.card__title`:\n```css\n.heading__main { color: #333333; } /* Ensure sufficient contrast against background */\n.card__title { color: #222222; }\n```"},{"priority":1,"title":"Fix color contrast violations","impact":"WCAG 1.4.3 (Accessibility)","problem":"axe-core reports 1 serious violation on `.heading--primary` and form labels failing contrast thresholds.","solution":"Increase contrast ratio to ≥4.5:1 for text. For `.heading--primary`, darken the text color or lighten the background. For form labels, ensure sufficient contrast against the input background."},{"priority":2,"title":"Fix W3C HTML Validation Errors","impact":"SEO, Rendering Stability","problem":"W3C Validator reports 7 errors including 'Parser recovery at line 100' and 'Bad start tag in iframe in noscript in head'.","solution":"Correct the HTML structure in the `<head>` section:\n- Move `<noscript><iframe>...</iframe></noscript>` out of `<head>` or ensure it is valid HTML5.\n- Remove invalid `name` attribute from `<meta>` tags.\n- Ensure `<body>` tag is not closed prematurely before content."},{"priority":2,"title":"Improve Accessibility Landmarks and Link Text","impact":"WCAG 2.4.1, 1.3.1","problem":"axe-core found 'landmark-unique' and 'region' violations; HTML Inventory notes missing 'main' landmark and 'skip-to-content' link.","solution":"- Add `<main id=\"main-content\">` to wrap primary content.\n- Add a skip link at the top: `<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>`.\n- Replace vague 'read more' links with descriptive text or `aria-label`."},{"priority":2,"title":"Fix Accessibility Contrast and Landmarks","impact":"WCAG 1.4.3, 1.3.1, 2.4.1","problem":"Axe found 1 serious color-contrast violation and PSI failed `landmark-one-main` (missing `<main>` element).","solution":"- Increase contrast ratio on `.heading__main` and card text to ≥4.5:1.\n- Wrap primary content in `<main>` tag.\n- Add a skip-to-content link at the top of the page."},{"priority":2,"title":"Resolve W3C HTML Validation Errors","impact":"Maintainability, Rendering Consistency","problem":"7 W3C errors including parser recovery failure at line 100 (bad iframe/noscript in head).","solution":"- Move `<noscript><iframe>...</iframe></noscript>` out of `<head>` (allowed in body only).\n- Remove invalid `name` attribute from `<meta>` tags.\n- Ensure `<body>` tag is not duplicated."},{"priority":2,"title":"Fix Accessibility Violations","impact":"WCAG Compliance, Usability","problem":"1 serious color-contrast violation (h1, p span) and missing main landmark/skip link.","solution":"Increase contrast ratio for `.heading__main` and `p > span` to ≥4.5:1.\nAdd `<main>` element wrapping primary content.\nAdd skip-to-content link at top of page."},{"priority":2,"title":"Add Explicit Image Dimensions","impact":"CLS, Layout Stability","problem":"53 images missing width/height attributes (HTML Inventory), risking layout shifts.","solution":"Add `width` and `height` attributes to all `<img>` tags.\nUse CSS `aspect-ratio` if dimensions vary dynamically."},{"priority":2,"title":"Improve HTML Document Structure","impact":"SEO, Screen Reader Navigation","problem":"HTML Inventory shows 2 `<h1>` elements, missing `<main>` landmark, and no skip-to-content link.","solution":"- Ensure only one `<h1>` exists per page.\n- Wrap primary content in `<main>`.\n- Add a skip link at the top: `<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>`."},{"priority":2,"title":"Fix color-contrast violations on headings","impact":"WCAG 1.4.3, accessibility","problem":"21+ nodes fail color-contrast (serious axe violation) including .focus__heading > h1 and .capabilities__heading elements.","solution":"Increase contrast ratio to ≥4.5:1 for text. Example:\n```css\n.heading__main { color: #333333; } /* adjust to meet contrast */\n```"},{"priority":2,"title":"Add main landmark and skip-to-content link","impact":"WCAG 1.3.1, 2.4.1, accessibility","problem":"Document missing main landmark and skip-to-content link — 2 moderate axe violations.","solution":"Add skip link and main landmark:\n```html\n<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>\n<main id=\"main-content\">\n  <!-- page content -->\n</main>\n```"},{"priority":2,"title":"Strengthen Content Security Policy (CSP)","impact":"XSS defense (User-generated content present)","problem":"CSP is weak (only `frame-ancestors` set). Site has a `<textarea>` form (UGC), increasing XSS risk per security rubric.","solution":"Implement a strict CSP with nonce/hash for scripts:\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nEnsure all inline scripts use the nonce."},{"priority":2,"title":"Fix HTML validation errors","impact":"Rendering consistency, SEO","problem":"W3C Validator reports 8 errors including parser recovery failure at line 103 and misplaced meta/iframe tags.","solution":"Move `<meta charset>` to the first 1024 bytes. Remove `<iframe>` from `<noscript>` inside `<head>`. Ensure `<head>` closes before `<body>` starts."},{"priority":3,"title":"Add Image Dimensions and Lazy Loading","impact":"CLS, Performance","problem":"HTML Inventory shows 52 images without width/height and 52 without loading=\"lazy\".","solution":"- Add `width` and `height` attributes to all `<img>` tags to reserve space.\n- Add `loading=\"lazy\"` to images below the fold:\n```html\n<img src=\"image.svg\" alt=\"...\" width=\"300\" height=\"200\" loading=\"lazy\">\n```"},{"priority":3,"title":"Add Explicit Dimensions to Images","impact":"CLS, Layout Stability","problem":"HTML Inventory reports 56 images without width/height attributes, risking layout shifts on load.","solution":"Add `width` and `height` attributes to all `<img>` tags:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"300\" height=\"200\">\n```"},{"priority":3,"title":"Implement Strict Content Security Policy","impact":"XSS Defense-in-Depth","problem":"CSP is weak (only `frame-ancestors` set); default-src and object-src missing.","solution":"Deploy a nonce-based CSP (since no auth/payments, P3 is acceptable):\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```"},{"priority":3,"title":"Strengthen Content Security Policy","impact":"XSS Defense-in-Depth","problem":"CSP is weak (only `frame-ancestors`), though site signals indicate low auth/payment risk.","solution":"Implement a nonce-based CSP for future-proofing:\n`Content-Security-Policy: script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`"},{"priority":3,"title":"Implement Content Security Policy (CSP)","impact":"XSS Defense-in-Depth","problem":"CSP is missing or weak (only `frame-ancestors`). Site signals indicate no auth/payments, so this is P3 per rubric.","solution":"Deploy a nonce-based CSP to mitigate XSS without breaking third-party scripts:\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nGenerate a unique nonce per request in PHP/WordPress."},{"priority":3,"title":"Add width/height attributes to all images","impact":"CLS, layout stability","problem":"69 images without explicit width/height — CLS risk despite current 0.000 score.","solution":"Add dimensions to all <img> tags:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"800\" height=\"600\">\n```"},{"priority":3,"title":"Improve CSP with nonce/strict-dynamic","impact":"XSS defense-in-depth","problem":"CSP only has frame-ancestors — missing default-src and object-src 'none'.","solution":"Deploy nonce-based CSP:\n```apache\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```"},{"priority":3,"title":"Add explicit width/height to images","impact":"CLS (Cumulative Layout Shift)","problem":"HTML inventory shows 16 images without explicit width/height attributes, risking layout shifts if CSS fails.","solution":"Add `width` and `height` attributes to all `<img>` tags to reserve space:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"320\" height=\"240\">\n```"},{"priority":3,"title":"Correct heading hierarchy","impact":"Screen reader navigation","problem":"Headings skip levels (h1 → h4, h2 → h4), violating WCAG 1.3.1.","solution":"Adjust CSS classes or HTML tags so headings descend sequentially (e.g., h1 → h2 → h3). Do not skip levels for styling purposes; use CSS for visual sizing."}],"coverage":{"pct":100,"missing":[]},"siteSummary":{"pagesAudited":7,"pagesAttempted":7,"urls":["https://play.ee/","https://play.ee/web-development-case-studies/","https://play.ee/software-development-work-index/","https://play.ee/wordpress-support-service/","https://play.ee/web-development-in-estonia/","https://play.ee/software-development-in-estonia/","https://play.ee/website-development-contact/"]},"psiSnapshot":{"rows":[{"pageUrl":"https://play.ee/","perfMobile":95,"perfDesktop":100,"lcpMobileMs":2507.5,"lcpDesktopMs":608,"clsMobile":0.002002927346531788,"clsDesktop":0.007792621099447469},{"pageUrl":"https://play.ee/web-development-case-studies/","perfMobile":97,"perfDesktop":100,"lcpMobileMs":2104.695484992959,"lcpDesktopMs":575.3517495763738,"clsMobile":0.0030260999840435497,"clsDesktop":0.0026357958450812895},{"pageUrl":"https://play.ee/software-development-work-index/","perfMobile":96,"perfDesktop":100,"lcpMobileMs":2326,"lcpDesktopMs":557.3473759089761,"clsMobile":0.04103362197089203,"clsDesktop":0.00281041673381916},{"pageUrl":"https://play.ee/wordpress-support-service/","perfMobile":97,"perfDesktop":100,"lcpMobileMs":2326,"lcpDesktopMs":545.5005177754348,"clsMobile":0.01679482402085737,"clsDesktop":0.00281041673381916},{"pageUrl":"https://play.ee/web-development-in-estonia/","perfMobile":93,"perfDesktop":100,"lcpMobileMs":2642.5,"lcpDesktopMs":531.6752341089177,"clsMobile":0,"clsDesktop":0.004827055629199457},{"pageUrl":"https://play.ee/software-development-in-estonia/","perfMobile":96,"perfDesktop":100,"lcpMobileMs":2476,"lcpDesktopMs":573.9632248735854,"clsMobile":0.003081202190670072,"clsDesktop":0.003659775477879521},{"pageUrl":"https://play.ee/website-development-contact/","perfMobile":93,"perfDesktop":94,"lcpMobileMs":2564,"lcpDesktopMs":763,"clsMobile":0,"clsDesktop":0.0027325965175314265}]},"optimizationChecklist":{"items":[{"id":"caching","title":"Page caching plugin / CDN active","status":"pass","detail":"Caching plugin detected (WP Rocket)","evidence":["HTML markers: WP Rocket","generator: WP Rocket 3.22.0.3"]},{"id":"lazyload","title":"Images lazy-loaded","status":"n/a","detail":"No raster <img> elements found (39 SVGs, 13 placeholders excluded).","evidence":[]},{"id":"heroEager","title":"Hero image eagerly loaded","status":"n/a","detail":"No raster <img> elements found (39 SVGs, 13 placeholders excluded).","evidence":[]},{"id":"heroBackground","title":"Hero is a real <img> (not a CSS background-image)","status":"n/a","detail":"No CSS background-images detected on raster-image-eligible elements.","evidence":[]},{"id":"responsive","title":"Responsive images (srcset / <picture>)","status":"n/a","detail":"Only 0 raster images on the page (39 SVGs, 13 placeholders excluded) — responsive-image rule does not apply.","evidence":[]},{"id":"imageSizes","title":"Reasonable number of image sizes","status":"n/a","detail":"Too few raster images to evaluate srcset width variety.","evidence":[]},{"id":"scriptsFooter","title":"JS scripts not blocking in <head>","status":"pass","detail":"No render-blocking scripts in <head>.","evidence":[]}],"summary":{"passed":2,"warned":0,"failed":0,"notApplicable":5},"priorities":[]},"perPageOverall":[{"url":"https://play.ee/","overall":78,"reasoning":"PSI mobile performance is excellent at 95 (LCP 2.5 s, TTFB 37 ms), but the security headers grade of 20/100 significantly drags the SEO/Security bucket. HTTP does not redirect to HTTPS and HSTS is missing, creating a baseline vulnerability despite the site being served over HTTPS. W3C validation shows 7 errors with parser recovery failure, risking rendering consistency and SEO indexing. Accessibility is mostly clean (0 critical axe violations) but lacks skip links and proper landmarks. Confidence is high as all audit tools returned complete data.","confidence":"high","fixes":[{"priority":1,"title":"Force HTTPS Redirect and Add HSTS","impact":"Security, Transport Layer","problem":"Security Headers report shows 'http://play.ee/ does not redirect to HTTPS' and 'strict-transport-security missing'.","solution":"Configure the web server to redirect all HTTP traffic to HTTPS (301) and send the HSTS header:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\n```"},{"priority":2,"title":"Fix W3C HTML Validation Errors","impact":"SEO, Rendering Stability","problem":"W3C Validator reports 7 errors including 'Parser recovery at line 100' and 'Bad start tag in iframe in noscript in head'.","solution":"Correct the HTML structure in the `<head>` section:\n- Move `<noscript><iframe>...</iframe></noscript>` out of `<head>` or ensure it is valid HTML5.\n- Remove invalid `name` attribute from `<meta>` tags.\n- Ensure `<body>` tag is not closed prematurely before content."},{"priority":2,"title":"Improve Accessibility Landmarks and Link Text","impact":"WCAG 2.4.1, 1.3.1","problem":"axe-core found 'landmark-unique' and 'region' violations; HTML Inventory notes missing 'main' landmark and 'skip-to-content' link.","solution":"- Add `<main id=\"main-content\">` to wrap primary content.\n- Add a skip link at the top: `<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>`.\n- Replace vague 'read more' links with descriptive text or `aria-label`."},{"priority":3,"title":"Add Image Dimensions and Lazy Loading","impact":"CLS, Performance","problem":"HTML Inventory shows 52 images without width/height and 52 without loading=\"lazy\".","solution":"- Add `width` and `height` attributes to all `<img>` tags to reserve space.\n- Add `loading=\"lazy\"` to images below the fold:\n```html\n<img src=\"image.svg\" alt=\"...\" width=\"300\" height=\"200\" loading=\"lazy\">\n```"}]},{"url":"https://play.ee/web-development-case-studies/","overall":76,"reasoning":"Performance is excellent (PSI Mobile 97, LCP 2.1s), but security and accessibility issues prevent a higher score. Security Headers grade is 20/100 with a critical HTTP redirect failure and missing HSTS, which heavily impacts the SEO/Security budget. Accessibility has a serious color-contrast violation and missing main landmark (PSI score 0.00 for landmark-one-main). W3C validation shows 7 errors with parser recovery, indicating structural HTML issues. Image dimensions are missing on 56 assets, posing a CLS risk despite current low scores.","confidence":"high","fixes":[{"priority":1,"title":"Enforce HTTPS and add HSTS","impact":"Security, Transport Layer","problem":"Security Headers tool reports HTTP does not redirect to HTTPS and HSTS is missing (Score 20/100).","solution":"Configure server to redirect all HTTP traffic to HTTPS and send HSTS header:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n```"},{"priority":2,"title":"Fix Accessibility Contrast and Landmarks","impact":"WCAG 1.4.3, 1.3.1, 2.4.1","problem":"Axe found 1 serious color-contrast violation and PSI failed `landmark-one-main` (missing `<main>` element).","solution":"- Increase contrast ratio on `.heading__main` and card text to ≥4.5:1.\n- Wrap primary content in `<main>` tag.\n- Add a skip-to-content link at the top of the page."},{"priority":2,"title":"Resolve W3C HTML Validation Errors","impact":"Maintainability, Rendering Consistency","problem":"7 W3C errors including parser recovery failure at line 100 (bad iframe/noscript in head).","solution":"- Move `<noscript><iframe>...</iframe></noscript>` out of `<head>` (allowed in body only).\n- Remove invalid `name` attribute from `<meta>` tags.\n- Ensure `<body>` tag is not duplicated."},{"priority":3,"title":"Add Explicit Dimensions to Images","impact":"CLS, Layout Stability","problem":"HTML Inventory reports 56 images without width/height attributes, risking layout shifts on load.","solution":"Add `width` and `height` attributes to all `<img>` tags:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"300\" height=\"200\">\n```"},{"priority":3,"title":"Implement Strict Content Security Policy","impact":"XSS Defense-in-Depth","problem":"CSP is weak (only `frame-ancestors` set); default-src and object-src missing.","solution":"Deploy a nonce-based CSP (since no auth/payments, P3 is acceptable):\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```"}]},{"url":"https://play.ee/software-development-work-index/","overall":74,"reasoning":"Mobile performance is excellent (PSI 96, LCP 2.3s), but the score is dragged down by critical security and structural issues. Security headers grade is 20/100 with HTTP not redirecting to HTTPS and HSTS missing, which is a foundational trust failure. W3C validation shows 7 errors including parser recovery failure, risking DOM integrity. Accessibility has 1 serious color-contrast violation and missing main landmark. Image assets lack width/height on 53 elements, creating CLS risk despite current low score.","confidence":"high","fixes":[{"priority":1,"title":"Enforce HTTPS redirect and add HSTS","impact":"Security, Trust, SEO","problem":"HTTP does not redirect to HTTPS and HSTS is missing (Security Headers grade 20/100).","solution":"Configure server to redirect all HTTP traffic to HTTPS immediately.\nAdd HSTS header:\n`Strict-Transport-Security: max-age=63072000; includeSubDomains; preload`"},{"priority":1,"title":"Fix W3C HTML Validation Errors","impact":"DOM Integrity, SEO, Rendering","problem":"7 validation errors including parser recovery failure at line 100 (iframe in noscript in head).","solution":"Move `<noscript><iframe>` out of `<head>` or ensure it is valid HTML5.\nRemove stray end tags (`</noscript>`, `</head>`).\nFix meta tag attributes (`name` not allowed in this context)."},{"priority":2,"title":"Fix Accessibility Violations","impact":"WCAG Compliance, Usability","problem":"1 serious color-contrast violation (h1, p span) and missing main landmark/skip link.","solution":"Increase contrast ratio for `.heading__main` and `p > span` to ≥4.5:1.\nAdd `<main>` element wrapping primary content.\nAdd skip-to-content link at top of page."},{"priority":2,"title":"Add Explicit Image Dimensions","impact":"CLS, Layout Stability","problem":"53 images missing width/height attributes (HTML Inventory), risking layout shifts.","solution":"Add `width` and `height` attributes to all `<img>` tags.\nUse CSS `aspect-ratio` if dimensions vary dynamically."},{"priority":3,"title":"Strengthen Content Security Policy","impact":"XSS Defense-in-Depth","problem":"CSP is weak (only `frame-ancestors`), though site signals indicate low auth/payment risk.","solution":"Implement a nonce-based CSP for future-proofing:\n`Content-Security-Policy: script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`"}]},{"url":"https://play.ee/wordpress-support-service/","overall":78,"reasoning":"Mobile performance is excellent (97) with strong Core Web Vitals (LCP 2.3 s, CLS 0.017), but security configuration is critically weak (Headers 20/100, HTTP does not redirect to HTTPS). Accessibility has two serious violations (contrast, link names) and the HTML structure contains 7 W3C errors including a parser recovery failure. The site is a service brochure with no auth or payments, which lowers the CSP priority but does not excuse the missing HSTS or HTTP redirect. Confidence is high as all audit tools returned complete data.","confidence":"high","fixes":[{"priority":1,"title":"Enforce HTTPS Redirect and Add HSTS","impact":"Security, Transport Layer","problem":"HTTP does not redirect to HTTPS (Security Headers) and HSTS is missing, leaving the site vulnerable to downgrade attacks.","solution":"Configure the web server (Apache/Nginx) to redirect all HTTP traffic to HTTPS:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n```\nAdd HSTS header:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\n```"},{"priority":1,"title":"Fix Serious Accessibility Violations","impact":"WCAG 1.4.3 (Contrast), 2.4.4 (Link Purpose)","problem":"axe-core reports 2 serious violations: color-contrast on multiple text nodes and link-name on logo grid links.","solution":"- Increase contrast ratio for `.button--tertiary` and `.capabilities__heading` text to ≥4.5:1.\n- Add `aria-label` to logo grid links (e.g., `<a href=\"\" aria-label=\"Client Logo\">`)."},{"priority":2,"title":"Resolve W3C HTML Validation Errors","impact":"DOM Integrity, Parser Recovery","problem":"7 W3C errors including 'Bad start tag in iframe in noscript in head' and parser recovery failure at line 107.","solution":"Move the Google Tag Manager `<noscript><iframe>...</iframe></noscript>` snippet from `<head>` to immediately after the opening `<body>` tag. Ensure `<meta>` tags in head do not use invalid attributes like `name` where `property` is expected."},{"priority":2,"title":"Improve HTML Document Structure","impact":"SEO, Screen Reader Navigation","problem":"HTML Inventory shows 2 `<h1>` elements, missing `<main>` landmark, and no skip-to-content link.","solution":"- Ensure only one `<h1>` exists per page.\n- Wrap primary content in `<main>`.\n- Add a skip link at the top: `<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>`."},{"priority":3,"title":"Implement Content Security Policy (CSP)","impact":"XSS Defense-in-Depth","problem":"CSP is missing or weak (only `frame-ancestors`). Site signals indicate no auth/payments, so this is P3 per rubric.","solution":"Deploy a nonce-based CSP to mitigate XSS without breaking third-party scripts:\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nGenerate a unique nonce per request in PHP/WordPress."}]},{"url":"https://play.ee/web-development-in-estonia/","overall":72,"reasoning":"PSI mobile 93 (desktop 100) shows strong performance, but LCP 2.6 s and FCP 1.99 s are in warning zones. Security headers score 20/100 is a major drag — HTTP does not redirect to HTTPS, HSTS missing, CSP weak. Accessibility has 1 serious color-contrast violation affecting 21+ nodes plus missing main landmark. W3C validator reports 7 errors with parser recovery failure at line 100. Image dimensions missing on 69 images is a CLS risk despite current 0.000 CLS score.","confidence":"high","fixes":[{"priority":1,"title":"Force HTTPS redirect for all HTTP requests","impact":"Transport security, SEO","problem":"http://play.ee/web-development-in-estonia/ does not redirect to HTTPS — critical security exposure.","solution":"Configure server to redirect all HTTP to HTTPS:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\n```"},{"priority":1,"title":"Add HSTS and X-Content-Type-Options headers","impact":"Transport security, MIME sniffing","problem":"HSTS and X-Content-Type-Options missing — security headers score 20/100.","solution":"Add to server config:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\n```"},{"priority":2,"title":"Fix color-contrast violations on headings","impact":"WCAG 1.4.3, accessibility","problem":"21+ nodes fail color-contrast (serious axe violation) including .focus__heading > h1 and .capabilities__heading elements.","solution":"Increase contrast ratio to ≥4.5:1 for text. Example:\n```css\n.heading__main { color: #333333; } /* adjust to meet contrast */\n```"},{"priority":2,"title":"Fix W3C HTML validation errors","impact":"SEO, rendering consistency","problem":"7 errors including bad iframe in noscript in head, stray end tags, meta tag issues at line 97-100.","solution":"Move GTM iframe out of <head> or wrap properly:\n```html\n<noscript><iframe src=\"https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ\" height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"></iframe></noscript>\n```"},{"priority":2,"title":"Add main landmark and skip-to-content link","impact":"WCAG 1.3.1, 2.4.1, accessibility","problem":"Document missing main landmark and skip-to-content link — 2 moderate axe violations.","solution":"Add skip link and main landmark:\n```html\n<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>\n<main id=\"main-content\">\n  <!-- page content -->\n</main>\n```"},{"priority":3,"title":"Add width/height attributes to all images","impact":"CLS, layout stability","problem":"69 images without explicit width/height — CLS risk despite current 0.000 score.","solution":"Add dimensions to all <img> tags:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"800\" height=\"600\">\n```"},{"priority":3,"title":"Improve CSP with nonce/strict-dynamic","impact":"XSS defense-in-depth","problem":"CSP only has frame-ancestors — missing default-src and object-src 'none'.","solution":"Deploy nonce-based CSP:\n```apache\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```"}]},{"url":"https://play.ee/software-development-in-estonia/","overall":77,"reasoning":"PSI mobile performance is excellent at 96 with a 7 ms TTFB, but security is a major weakness with a 20/100 header grade and missing HTTP-to-HTTPS redirect. Accessibility has a serious color-contrast violation and missing main landmark despite a 91 PSI score. W3C validation failed with 7 errors and parser recovery issues near the head. The overall score reflects strong speed but significant security and structural quality gaps.","confidence":"high","fixes":[{"priority":1,"title":"Enforce HTTPS redirect and add HSTS","impact":"Transport security, data integrity","problem":"HTTP does not redirect to HTTPS (http://play.ee/... accessible) and HSTS is missing, exposing traffic to MITM attacks.","solution":"Configure the web server (Apache/Nginx) to redirect all HTTP traffic to HTTPS and send the HSTS header:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\n```"},{"priority":1,"title":"Fix color contrast on headings and cards","impact":"WCAG 1.4.3 (Contrast), Accessibility","problem":"axe-core reports 1 serious violation for color-contrast on multiple nodes (h1, .card__title, etc.).","solution":"Increase contrast ratio to at least 4.5:1 for normal text. Adjust CSS for `.heading__main` and `.card__title`:\n```css\n.heading__main { color: #333333; } /* Ensure sufficient contrast against background */\n.card__title { color: #222222; }\n```"},{"priority":2,"title":"Add main landmark and skip-to-content link","impact":"WCAG 2.4.1 (Bypass Blocks), Navigation","problem":"HTML inventory shows missing `main` landmark and no skip-to-content link; axe reports `landmark-one-main` fail.","solution":"Wrap primary content in `<main>` and add a skip link at the top:\n```html\n<a href=\"#main-content\" class=\"skip-link\">Skip to content</a>\n<header>...</header>\n<main id=\"main-content\">...</main>\n```"},{"priority":2,"title":"Resolve W3C HTML validation errors","impact":"Parser compatibility, SEO","problem":"W3C validator reports 7 errors including parser recovery failure at line 107 (iframe/noscript in head).","solution":"Move the Google Tag Manager `noscript` iframe out of the `<head>` and into the `<body>` immediately after the opening tag:\n```html\n<body>\n  <noscript><iframe src=\"https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ\" ...></iframe></noscript>\n  <!-- rest of body -->\n</body>\n```"},{"priority":3,"title":"Add explicit width/height to images","impact":"CLS (Cumulative Layout Shift)","problem":"HTML inventory shows 16 images without explicit width/height attributes, risking layout shifts if CSS fails.","solution":"Add `width` and `height` attributes to all `<img>` tags to reserve space:\n```html\n<img src=\"image.jpg\" alt=\"...\" width=\"320\" height=\"240\">\n```"}]},{"url":"https://play.ee/website-development-contact/","overall":72,"reasoning":"Mobile performance is strong (93) but LCP (2.6 s) lags significantly behind desktop (0.8 s). Security posture is critically weak (20/100) with HTTP not redirecting to HTTPS and missing HSTS. Accessibility has a serious contrast violation despite a high Lighthouse score. HTML validation shows 8 errors including parser recovery failure. Overall score reflects high performance offset by security and structural code debt.","confidence":"high","fixes":[{"priority":1,"title":"Enforce HTTPS and add HSTS","impact":"Transport security, data integrity","problem":"HTTP does not redirect to HTTPS (http://play.ee/... does not redirect) and HSTS is missing, leaving users vulnerable to downgrade attacks.","solution":"Configure the web server (Apache) to force HTTPS redirects and send HSTS:\n```apache\nRewriteEngine On\nRewriteCond %{HTTPS} off\nRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\n```"},{"priority":1,"title":"Fix color contrast violations","impact":"WCAG 1.4.3 (Accessibility)","problem":"axe-core reports 1 serious violation on `.heading--primary` and form labels failing contrast thresholds.","solution":"Increase contrast ratio to ≥4.5:1 for text. For `.heading--primary`, darken the text color or lighten the background. For form labels, ensure sufficient contrast against the input background."},{"priority":2,"title":"Strengthen Content Security Policy (CSP)","impact":"XSS defense (User-generated content present)","problem":"CSP is weak (only `frame-ancestors` set). Site has a `<textarea>` form (UGC), increasing XSS risk per security rubric.","solution":"Implement a strict CSP with nonce/hash for scripts:\n```apache\nHeader set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nEnsure all inline scripts use the nonce."},{"priority":2,"title":"Fix HTML validation errors","impact":"Rendering consistency, SEO","problem":"W3C Validator reports 8 errors including parser recovery failure at line 103 and misplaced meta/iframe tags.","solution":"Move `<meta charset>` to the first 1024 bytes. Remove `<iframe>` from `<noscript>` inside `<head>`. Ensure `<head>` closes before `<body>` starts."},{"priority":3,"title":"Correct heading hierarchy","impact":"Screen reader navigation","problem":"Headings skip levels (h1 → h4, h2 → h4), violating WCAG 1.3.1.","solution":"Adjust CSS classes or HTML tags so headings descend sequentially (e.g., h1 → h2 → h3). Do not skip levels for styling purposes; use CSS for visual sizing."}]}]}