{"url":"https://kodud.embach.ee/","date":"2026-07-20","siteName":"Kodud","overall":74,"reasoning":"Site overall 74 is the mean of 5 pages. Scores range 72 (https://kodud.embach.ee/hello-world) → 78 (https://kodud.embach.ee/sample-page). Weakest page: Mobile performance (77) is dragged down by LCP 3.7 s and CLS 0.208, while desktop is excellent (99). Security headers are completely absent (0/100), which is critical given the inferred user-generated content signal. Accessibility is strong (94) but fails on the missing H1 heading structure. SEO metadata is missing (description, structured data). Confidence is high due to complete data coverage.","confidence":"high","fixes":[{"priority":1,"title":"Fix Cumulative Layout Shift (CLS) on Carousel","impact":"Core Web Vitals, User Experience","problem":"CLS is 0.287 (mobile) and 0.571 (desktop), exceeding the 0.25 threshold. The shift source is identified as 'div.projects-carousel__slider'.","solution":"Reserve space for the carousel container using `min-height` or `aspect-ratio` in CSS to prevent layout shifts during image loading.\n```css\n.projects-carousel__slider {\n  min-height: 400px; /* Adjust to actual content height */\n  aspect-ratio: 16 / 9;\n}\n```"},{"priority":1,"title":"Implement Missing Security Headers","impact":"Security, Transport Integrity","problem":"Security Headers grade is 0/100. HSTS, X-Frame-Options, X-Content-Type-Options, and CSP are all missing. UGC signal is 'yes', elevating CSP to Priority 1.","solution":"Add the following headers to the server response (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":1,"title":"Optimize Largest Contentful Paint (LCP)","impact":"Performance, LCP Metric","problem":"LCP is 3.3 s on mobile, exceeding the 2.5 s good threshold. 6 render-blocking scripts and 109 KB unused JS contribute to delay.","solution":"1. Defer non-critical scripts (add `defer` or `async` to 6 render-blocking scripts).\n2. Preload the hero image resource.\n3. Remove or tree-shake the 109 KB unused JavaScript (`global.04cbabbf7670bc75.js`).\n```html\n<link rel=\"preload\" as=\"image\" href=\"/path/to/hero.jpg\">\n<script src=\"...\" defer></script>\n```"},{"priority":1,"title":"Add a single H1 heading to the page","impact":"SEO, Accessibility (WCAG 1.3.1)","problem":"HTML Inventory reports 0 H1 elements; axe-core flags 'page-has-heading-one' as a moderate violation.","solution":"Ensure the main title of the post/page is wrapped in a single `<h1>` tag.\n```html\n<h1>Hello world!</h1>\n```"},{"priority":1,"title":"Implement baseline security headers (HSTS, CSP, X-Frame-Options)","impact":"Transport security, XSS defense, Clickjacking","problem":"Security Headers grade is 0/100; HSTS and CSP are missing despite UGC signal (yes) increasing XSS risk.","solution":"Add to server config (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":1,"title":"Implement Critical Security Headers (HSTS, CSP)","impact":"Security, XSS protection, Clickjacking","problem":"Security Headers grade is 0/100; HSTS and CSP are missing. Site signals indicate user-generated content (UGC), elevating XSS risk.","solution":"Add the following headers to your server configuration (e.g., Apache .htaccess or Nginx):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nEnsure CSP uses nonces/hashes for scripts rather than a permissive allowlist."},{"priority":1,"title":"Fix Hero Image Loading for LCP","impact":"LCP, FCP, Performance Score","problem":"LCP is 5.2 s on mobile; checklist confirms hero image has loading='lazy' which delays rendering.","solution":"Remove `loading=\"lazy\"` from the hero image and add `fetchpriority=\"high\"`:\n```html\n<img src=\"hero.jpg\" alt=\"...\" fetchpriority=\"high\" width=\"...\" height=\"...\">\n```"},{"priority":1,"title":"Implement HSTS and CSP Headers","impact":"Security Headers Grade, XSS/Clickjacking Defense","problem":"Security grade is 0/100; HSTS and CSP are missing. UGC signal is 'yes', raising CSP priority per rubric.","solution":"Add HSTS and a strict CSP (nonce-based) to server config:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":1,"title":"Implement Baseline Security Headers","impact":"Security, Transport Integrity","problem":"Security Headers grade is 0/100; HSTS, X-Frame-Options, and X-Content-Type-Options are missing.","solution":"Add these headers via server config (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set X-Content-Type-Options \"nosniff\"\n```"},{"priority":1,"title":"Add Content-Security-Policy (CSP)","impact":"XSS Defense","problem":"CSP is missing and Site Signals infer User-Generated Content (anchor href contains \"post\"), elevating XSS risk.","solution":"Deploy a strict CSP with nonces rather than a flat allowlist:\n```apache\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":2,"title":"Add Meta Description and Structured Data","impact":"SEO, Search Visibility","problem":"PSI SEO audit fails on `metaDescription` and `structuredData`. HTML inventory confirms no meta description or JSON-LD present.","solution":"Add a unique meta description (150-160 chars) and relevant JSON-LD (e.g., `RealEstateAgent` or `LocalBusiness`).\n```html\n<meta name=\"description\" content=\"Embach kodud: kaasaegne kinnisvaraarendus Tartu piiril.\">\n<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"RealEstateAgent\",\n  \"name\": \"Embach\"\n}\n</script>\n```"},{"priority":2,"title":"Reduce Cumulative Layout Shift (CLS) caused by footer","impact":"Core Web Vitals (CLS), User Experience","problem":"CLS is 0.208 (warning zone); PSI identifies footer div as the primary shift source (0.197).","solution":"Reserve space for dynamic footer content or ensure footer elements have explicit dimensions.\n```css\nfooter.footer {\n  min-height: 200px; /* Reserve space */\n}\n```"},{"priority":2,"title":"Defer non-critical render-blocking scripts","impact":"LCP, FCP, Performance Score","problem":"6 render-blocking scripts detected; 117 KB unused JS identified in global.js.","solution":"Add `defer` or `async` to script tags in `<head>` unless they are critical for initial render.\n```html\n<script src=\"...\" defer></script>\n```"},{"priority":2,"title":"Defer Render-Blocking Scripts","impact":"LCP, FCP, Performance Score","problem":"6 render-blocking scripts identified in PSI and HTML Inventory; LCP is 3.7 s and FCP is 3.23 s on mobile.","solution":"Move non-critical scripts to the footer or add `defer`/`async` attributes. For WordPress, use a plugin like WP Rocket (already detected) to delay JS execution or minify/combine scripts.\n```html\n<!-- Change from -->\n<script src=\"...\"></script>\n<!-- To -->\n<script src=\"...\" defer></script>\n```"},{"priority":2,"title":"Remove Unused JavaScript","impact":"Page Weight, TBT, Performance Score","problem":"117 KB of unused JavaScript detected in `global.04cbabbf7670bc75.js`.","solution":"Audit `global.js` and `core.js` for unused functions. Use code splitting or tree-shaking in your build process. If using WordPress, disable unused theme/plugin scripts via a performance plugin."},{"priority":2,"title":"Add H1 Heading Element","impact":"Accessibility (Axe), SEO (W3C)","problem":"W3C warns no H1; Axe reports 'page-has-heading-one' violation. Page uses H2s for main titles.","solution":"Ensure the primary page title is wrapped in `<h1>`:\n```html\n<h1>Kõik arendused</h1>\n```"},{"priority":2,"title":"Add Meta Description","impact":"SEO (PSI Score 0)","problem":"PSI SEO audit fails 'metaDescription'; HTML inventory confirms description is not set.","solution":"Add a unique description tag in `<head>`:\n```html\n<meta name=\"description\" content=\"Vaadake kõiki meie arendusi ja koduvalikuid Eestis.\">\n```"},{"priority":2,"title":"Fix Accessibility Violations","impact":"WCAG 2.4.4, 2.5.8","problem":"PSI flags `button-name` and `target-size` with 0.00 scores; touch targets are too small and buttons lack accessible names.","solution":"- Ensure all buttons have visible text or `aria-label`.\n- Increase touch target padding to at least 44×44 px per WCAG 2.5.8."},{"priority":2,"title":"Defer Render-Blocking JavaScript","impact":"FCP, TBT, Performance","problem":"6 render-blocking scripts detected; 117 KB unused JS contributes to long tasks.","solution":"Add `defer` or `async` to non-critical scripts in `<head>`:\n```html\n<script src=\"/js/core.js\" defer></script>\n```"},{"priority":3,"title":"Ensure Lazy Loading on All Below-Fold Images","impact":"Page Weight, Load Time","problem":"HTML inventory shows 1 image missing `loading=\"lazy\"` despite being below the fold. Total page weight is 795.5 KB.","solution":"Audit all images below the fold and add `loading=\"lazy\"` attribute. Ensure hero images remain `eager` or `fetchpriority=\"high\"`.\n```html\n<img src=\"image.jpg\" loading=\"lazy\" alt=\"Description\" width=\"300\" height=\"200\">\n```"},{"priority":3,"title":"Add meta description and structured data","impact":"SEO (Search Appearance)","problem":"PSI SEO audit fails on `metaDescription` and `structuredData`; HTML Inventory confirms 0 Open Graph/Twitter tags.","solution":"Add meta description and JSON-LD schema to the `<head>`:\n```html\n<meta name=\"description\" content=\"Brief summary of the page content for search engines.\">\n<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"BlogPosting\",\n  \"headline\": \"Hello world!\"\n}\n</script>\n```"},{"priority":3,"title":"Verify Button Accessibility Names","impact":"Accessibility, WCAG 2.4.4","problem":"PSI reports `button-name` failure (score 0.00) despite axe-core showing 0 violations; manual check needed.","solution":"Inspect all `<button>` and icon links. Ensure they have visible text or `aria-label` attributes.\n```html\n<button aria-label=\"Close modal\">&times;</button>\n```"},{"priority":3,"title":"Add Meta Description and Open Graph Tags","impact":"SEO, Social Sharing","problem":"SEO audit fails `metaDescription`; no Open Graph or Twitter tags present.","solution":"Add to `<head>`:\n```html\n<meta name=\"description\" content=\"Contact details for real estate services.\">\n<meta property=\"og:title\" content=\"Kontakt\">\n<meta property=\"og:image\" content=\"/path/to/og-image.jpg\">\n```"},{"priority":3,"title":"Fix W3C HTML Validation Errors","impact":"Maintainability, Rendering Consistency","problem":"2 errors found: `srcset` missing width specification and stray `</p>` end tag.","solution":"- Update `srcset` to include width descriptors (e.g., `image.jpg 400w`).\n- Remove the extra `</p>` tag at line 538."}],"coverage":{"pct":100,"missing":[]},"siteSummary":{"pagesAudited":5,"pagesAttempted":5,"urls":["https://kodud.embach.ee/","https://kodud.embach.ee/hello-world","https://kodud.embach.ee/sample-page","https://kodud.embach.ee/koik-arendused","https://kodud.embach.ee/kontakt"]},"psiSnapshot":{"rows":[{"pageUrl":"https://kodud.embach.ee/","perfMobile":76,"perfDesktop":77,"lcpMobileMs":3347.101934616846,"lcpDesktopMs":1009.0825620629317,"clsMobile":0.2867557715674362,"clsDesktop":0.5708238974885622},{"pageUrl":"https://kodud.embach.ee/hello-world","perfMobile":77,"perfDesktop":99,"lcpMobileMs":3742.1921605243797,"lcpDesktopMs":857.6137892896757,"clsMobile":0.20771017481903178,"clsDesktop":0.007349129390318044},{"pageUrl":"https://kodud.embach.ee/sample-page","perfMobile":82,"perfDesktop":99,"lcpMobileMs":3708.573787016172,"lcpDesktopMs":925.5292571367498,"clsMobile":0,"clsDesktop":0.007421515076629949},{"pageUrl":"https://kodud.embach.ee/koik-arendused","perfMobile":76,"perfDesktop":97,"lcpMobileMs":5182.979626675126,"lcpDesktopMs":1211.4501119396894,"clsMobile":0,"clsDesktop":0.00001308667775130477},{"pageUrl":"https://kodud.embach.ee/kontakt","perfMobile":82,"perfDesktop":99,"lcpMobileMs":4502.382375944967,"lcpDesktopMs":914.5418761654694,"clsMobile":0,"clsDesktop":0.00001308667775130477}]},"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.23"]},{"id":"lazyload","title":"Images lazy-loaded","status":"n/a","detail":"No raster <img> elements found.","evidence":[]},{"id":"heroEager","title":"Hero image eagerly loaded","status":"fail","detail":"Hero image has loading=\"lazy\", which delays LCP (inferred from DOM order/size — Lighthouse LCP element unavailable). Use loading=\"eager\" (or omit loading) and add fetchpriority=\"high\".","evidence":["hero: …bach.ee/wp-content/uploads/sites/3/2026/05/parna_kesk_rgb_0020001-320x180.jpg","loading: lazy","fetchpriority: (not set)"]},{"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 — 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":"warn","detail":"2 render-blocking scripts in <head>. Move to footer or add defer/async.","evidence":["https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js","…//cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js"]}],"summary":{"passed":1,"warned":1,"failed":1,"notApplicable":4},"priorities":[{"title":"JS scripts not blocking in <head>","severity":"medium","detail":"2 render-blocking scripts in <head>. Move to footer or add defer/async."},{"title":"Hero image eagerly loaded","severity":"high","detail":"Hero image has loading=\"lazy\", which delays LCP (inferred from DOM order/size — Lighthouse LCP element unavailable). Use loading=\"eager\" (or omit loading) and add fetchpriority=\"high\"."}]},"perPageOverall":[{"url":"https://kodud.embach.ee/","overall":74,"reasoning":"Mobile performance (76) is dragged down by CLS (0.287) and LCP (3.3 s), both exceeding Core Web Vital thresholds. Security headers score 0/100, missing HSTS, CSP, and X-Frame-Options, which is a critical baseline failure despite low auth signals. Accessibility (95) and SEO (92) are strong, but the missing meta description and structured data prevent full credit. The 6 render-blocking scripts contribute to the LCP delay and unused JavaScript waste. Confidence is high as all audit tools returned complete data.","confidence":"high","fixes":[{"priority":1,"title":"Fix Cumulative Layout Shift (CLS) on Carousel","impact":"Core Web Vitals, User Experience","problem":"CLS is 0.287 (mobile) and 0.571 (desktop), exceeding the 0.25 threshold. The shift source is identified as 'div.projects-carousel__slider'.","solution":"Reserve space for the carousel container using `min-height` or `aspect-ratio` in CSS to prevent layout shifts during image loading.\n```css\n.projects-carousel__slider {\n  min-height: 400px; /* Adjust to actual content height */\n  aspect-ratio: 16 / 9;\n}\n```"},{"priority":1,"title":"Implement Missing Security Headers","impact":"Security, Transport Integrity","problem":"Security Headers grade is 0/100. HSTS, X-Frame-Options, X-Content-Type-Options, and CSP are all missing. UGC signal is 'yes', elevating CSP to Priority 1.","solution":"Add the following headers to the server response (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":1,"title":"Optimize Largest Contentful Paint (LCP)","impact":"Performance, LCP Metric","problem":"LCP is 3.3 s on mobile, exceeding the 2.5 s good threshold. 6 render-blocking scripts and 109 KB unused JS contribute to delay.","solution":"1. Defer non-critical scripts (add `defer` or `async` to 6 render-blocking scripts).\n2. Preload the hero image resource.\n3. Remove or tree-shake the 109 KB unused JavaScript (`global.04cbabbf7670bc75.js`).\n```html\n<link rel=\"preload\" as=\"image\" href=\"/path/to/hero.jpg\">\n<script src=\"...\" defer></script>\n```"},{"priority":2,"title":"Add Meta Description and Structured Data","impact":"SEO, Search Visibility","problem":"PSI SEO audit fails on `metaDescription` and `structuredData`. HTML inventory confirms no meta description or JSON-LD present.","solution":"Add a unique meta description (150-160 chars) and relevant JSON-LD (e.g., `RealEstateAgent` or `LocalBusiness`).\n```html\n<meta name=\"description\" content=\"Embach kodud: kaasaegne kinnisvaraarendus Tartu piiril.\">\n<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"RealEstateAgent\",\n  \"name\": \"Embach\"\n}\n</script>\n```"},{"priority":3,"title":"Ensure Lazy Loading on All Below-Fold Images","impact":"Page Weight, Load Time","problem":"HTML inventory shows 1 image missing `loading=\"lazy\"` despite being below the fold. Total page weight is 795.5 KB.","solution":"Audit all images below the fold and add `loading=\"lazy\"` attribute. Ensure hero images remain `eager` or `fetchpriority=\"high\"`.\n```html\n<img src=\"image.jpg\" loading=\"lazy\" alt=\"Description\" width=\"300\" height=\"200\">\n```"}]},{"url":"https://kodud.embach.ee/hello-world","overall":72,"reasoning":"Mobile performance (77) is dragged down by LCP 3.7 s and CLS 0.208, while desktop is excellent (99). Security headers are completely absent (0/100), which is critical given the inferred user-generated content signal. Accessibility is strong (94) but fails on the missing H1 heading structure. SEO metadata is missing (description, structured data). Confidence is high due to complete data coverage.","confidence":"high","fixes":[{"priority":1,"title":"Add a single H1 heading to the page","impact":"SEO, Accessibility (WCAG 1.3.1)","problem":"HTML Inventory reports 0 H1 elements; axe-core flags 'page-has-heading-one' as a moderate violation.","solution":"Ensure the main title of the post/page is wrapped in a single `<h1>` tag.\n```html\n<h1>Hello world!</h1>\n```"},{"priority":1,"title":"Implement baseline security headers (HSTS, CSP, X-Frame-Options)","impact":"Transport security, XSS defense, Clickjacking","problem":"Security Headers grade is 0/100; HSTS and CSP are missing despite UGC signal (yes) increasing XSS risk.","solution":"Add to server config (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":2,"title":"Reduce Cumulative Layout Shift (CLS) caused by footer","impact":"Core Web Vitals (CLS), User Experience","problem":"CLS is 0.208 (warning zone); PSI identifies footer div as the primary shift source (0.197).","solution":"Reserve space for dynamic footer content or ensure footer elements have explicit dimensions.\n```css\nfooter.footer {\n  min-height: 200px; /* Reserve space */\n}\n```"},{"priority":2,"title":"Defer non-critical render-blocking scripts","impact":"LCP, FCP, Performance Score","problem":"6 render-blocking scripts detected; 117 KB unused JS identified in global.js.","solution":"Add `defer` or `async` to script tags in `<head>` unless they are critical for initial render.\n```html\n<script src=\"...\" defer></script>\n```"},{"priority":3,"title":"Add meta description and structured data","impact":"SEO (Search Appearance)","problem":"PSI SEO audit fails on `metaDescription` and `structuredData`; HTML Inventory confirms 0 Open Graph/Twitter tags.","solution":"Add meta description and JSON-LD schema to the `<head>`:\n```html\n<meta name=\"description\" content=\"Brief summary of the page content for search engines.\">\n<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"BlogPosting\",\n  \"headline\": \"Hello world!\"\n}\n</script>\n```"}]},{"url":"https://kodud.embach.ee/sample-page","overall":78,"reasoning":"Mobile performance (82) and accessibility (94) are strong, but LCP (3.7 s) and FCP (3.23 s) lag due to render-blocking scripts and unused JavaScript. Security headers score 0/100, which is critical given the inferred user-generated content signal. SEO is solid (92) but lacks meta descriptions and structured data. The discrepancy between axe-core (0 violations) and PSI (button-name fail) requires manual verification. Overall score reflects high technical quality offset by significant security debt.","confidence":"high","fixes":[{"priority":1,"title":"Implement Critical Security Headers (HSTS, CSP)","impact":"Security, XSS protection, Clickjacking","problem":"Security Headers grade is 0/100; HSTS and CSP are missing. Site signals indicate user-generated content (UGC), elevating XSS risk.","solution":"Add the following headers to your server configuration (e.g., Apache .htaccess or Nginx):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set X-Content-Type-Options \"nosniff\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';\"\n```\nEnsure CSP uses nonces/hashes for scripts rather than a permissive allowlist."},{"priority":2,"title":"Defer Render-Blocking Scripts","impact":"LCP, FCP, Performance Score","problem":"6 render-blocking scripts identified in PSI and HTML Inventory; LCP is 3.7 s and FCP is 3.23 s on mobile.","solution":"Move non-critical scripts to the footer or add `defer`/`async` attributes. For WordPress, use a plugin like WP Rocket (already detected) to delay JS execution or minify/combine scripts.\n```html\n<!-- Change from -->\n<script src=\"...\"></script>\n<!-- To -->\n<script src=\"...\" defer></script>\n```"},{"priority":2,"title":"Remove Unused JavaScript","impact":"Page Weight, TBT, Performance Score","problem":"117 KB of unused JavaScript detected in `global.04cbabbf7670bc75.js`.","solution":"Audit `global.js` and `core.js` for unused functions. Use code splitting or tree-shaking in your build process. If using WordPress, disable unused theme/plugin scripts via a performance plugin."},{"priority":3,"title":"Add Meta Description and Structured Data","impact":"SEO, Search Appearance","problem":"PSI SEO audit fails `metaDescription` and `structuredData`; HTML Inventory confirms 0 Open Graph/Twitter tags.","solution":"Add a unique meta description (150-160 chars) in `<head>`.\n```html\n<meta name=\"description\" content=\"Brief summary of the page content for search engines.\">\n```\nImplement JSON-LD for `Article` or `WebPage` schema."},{"priority":3,"title":"Verify Button Accessibility Names","impact":"Accessibility, WCAG 2.4.4","problem":"PSI reports `button-name` failure (score 0.00) despite axe-core showing 0 violations; manual check needed.","solution":"Inspect all `<button>` and icon links. Ensure they have visible text or `aria-label` attributes.\n```html\n<button aria-label=\"Close modal\">&times;</button>\n```"}]},{"url":"https://kodud.embach.ee/koik-arendused","overall":72,"reasoning":"Mobile performance (76) is dragged down by a critical LCP of 5.2 s (>4 s threshold) caused by the hero image being lazy-loaded. Security headers score 0/100 (missing HSTS, CSP), which is a significant quality gap despite low auth risk; the UGC signal elevates CSP to Priority 1. Accessibility is strong (95) but fails on structure (missing H1). SEO is hindered by missing meta description and structured data. Desktop performance (97) contrasts sharply with mobile, highlighting mobile-specific bottlenecks.","confidence":"high","fixes":[{"priority":1,"title":"Fix Hero Image Loading for LCP","impact":"LCP, FCP, Performance Score","problem":"LCP is 5.2 s on mobile; checklist confirms hero image has loading='lazy' which delays rendering.","solution":"Remove `loading=\"lazy\"` from the hero image and add `fetchpriority=\"high\"`:\n```html\n<img src=\"hero.jpg\" alt=\"...\" fetchpriority=\"high\" width=\"...\" height=\"...\">\n```"},{"priority":1,"title":"Implement HSTS and CSP Headers","impact":"Security Headers Grade, XSS/Clickjacking Defense","problem":"Security grade is 0/100; HSTS and CSP are missing. UGC signal is 'yes', raising CSP priority per rubric.","solution":"Add HSTS and a strict CSP (nonce-based) to server config:\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\"\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":2,"title":"Add H1 Heading Element","impact":"Accessibility (Axe), SEO (W3C)","problem":"W3C warns no H1; Axe reports 'page-has-heading-one' violation. Page uses H2s for main titles.","solution":"Ensure the primary page title is wrapped in `<h1>`:\n```html\n<h1>Kõik arendused</h1>\n```"},{"priority":2,"title":"Add Meta Description","impact":"SEO (PSI Score 0)","problem":"PSI SEO audit fails 'metaDescription'; HTML inventory confirms description is not set.","solution":"Add a unique description tag in `<head>`:\n```html\n<meta name=\"description\" content=\"Vaadake kõiki meie arendusi ja koduvalikuid Eestis.\">\n```"},{"priority":2,"title":"Defer Render-Blocking Scripts","impact":"FCP, TBT, Performance Score","problem":"6 render-blocking scripts detected; 117 KB unused JS identified in PSI findings.","solution":"Add `defer` or `async` to non-critical scripts in `<head>`:\n```html\n<script src=\"script.js\" defer></script>\n```"}]},{"url":"https://kodud.embach.ee/kontakt","overall":72,"reasoning":"Mobile performance (82) is dragged into the 'Needs Improvement' band by a critical LCP of 4.5 s, exceeding the 4 s heavy penalty threshold. Security headers are completely missing (0/100), which is a significant risk given the inferred user-content signal. Accessibility shows specific failures in touch targets and button names despite a 91 score, indicating usability gaps. SEO lacks a meta description and Open Graph tags. Confidence is high as all audit tools returned complete data.","confidence":"high","fixes":[{"priority":1,"title":"Fix Hero Image Loading for LCP","impact":"LCP, FCP, Performance Score","problem":"LCP is 4.5 s on mobile; the hero image uses loading=\"lazy\" which delays rendering of the largest contentful element.","solution":"Remove `loading=\"lazy\"` from the hero image and add `fetchpriority=\"high\"`:\n```html\n<img src=\"/path/to/hero.jpg\" alt=\"...\" fetchpriority=\"high\">\n```"},{"priority":1,"title":"Implement Baseline Security Headers","impact":"Security, Transport Integrity","problem":"Security Headers grade is 0/100; HSTS, X-Frame-Options, and X-Content-Type-Options are missing.","solution":"Add these headers via server config (Apache example):\n```apache\nHeader always set Strict-Transport-Security \"max-age=63072000; includeSubDomains\"\nHeader always set X-Frame-Options \"SAMEORIGIN\"\nHeader always set X-Content-Type-Options \"nosniff\"\n```"},{"priority":1,"title":"Add Content-Security-Policy (CSP)","impact":"XSS Defense","problem":"CSP is missing and Site Signals infer User-Generated Content (anchor href contains \"post\"), elevating XSS risk.","solution":"Deploy a strict CSP with nonces rather than a flat allowlist:\n```apache\nHeader always set Content-Security-Policy \"default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';\"\n```"},{"priority":2,"title":"Fix Accessibility Violations","impact":"WCAG 2.4.4, 2.5.8","problem":"PSI flags `button-name` and `target-size` with 0.00 scores; touch targets are too small and buttons lack accessible names.","solution":"- Ensure all buttons have visible text or `aria-label`.\n- Increase touch target padding to at least 44×44 px per WCAG 2.5.8."},{"priority":2,"title":"Defer Render-Blocking JavaScript","impact":"FCP, TBT, Performance","problem":"6 render-blocking scripts detected; 117 KB unused JS contributes to long tasks.","solution":"Add `defer` or `async` to non-critical scripts in `<head>`:\n```html\n<script src=\"/js/core.js\" defer></script>\n```"},{"priority":3,"title":"Add Meta Description and Open Graph Tags","impact":"SEO, Social Sharing","problem":"SEO audit fails `metaDescription`; no Open Graph or Twitter tags present.","solution":"Add to `<head>`:\n```html\n<meta name=\"description\" content=\"Contact details for real estate services.\">\n<meta property=\"og:title\" content=\"Kontakt\">\n<meta property=\"og:image\" content=\"/path/to/og-image.jpg\">\n```"},{"priority":3,"title":"Fix W3C HTML Validation Errors","impact":"Maintainability, Rendering Consistency","problem":"2 errors found: `srcset` missing width specification and stray `</p>` end tag.","solution":"- Update `srcset` to include width descriptors (e.g., `image.jpg 400w`).\n- Remove the extra `</p>` tag at line 538."}]}]}