Audit

20260610T080447Z-a117

← Back to larsenee
Audited URL
https://larsen.ee/
Timestamp
2026-06-10T08:10:20.400Z
Kind
site
Pages
5
Audit summary
https://larsen.ee/
5 of 5 pages audited
Pagespeed scores
Other checks
LLM Report

Weighted audit summary

47
Overall site quality
Poorhigh confidence

Site overall 47 is the mean of 5 pages. Scores range 42 (https://larsen.ee/) → 52 (https://larsen.ee/terms-of-service). Weakest page: Mobile PSI performance is critically low at 35 with an 18.9 s LCP, despite decent field data, indicating severe lab bottlenecks. The 69 MB total page weight (55 MB media) is unsustainable for mobile users and directly drives the TBT and LCP failures. Accessibility is blocked by 2 critical axe violations and 11 W3C errors including buttons inside anchors. Security headers are weak (HSTS/CSP) though no auth/payments exist, and image optimization is missing entirely (no srcset).

Per-page scores
42
Home
high
52
/about
high
45
/faq
high
52
/terms-of-service
high
45
/et
high

Audit Report: Larsen - The Coolest Accommodation in Tallinn

URL: https://larsen.ee/ Date: 2026-06-10 Audit Coverage: 100% — all sources returned data Pages Audited: 5 of 5 discovered

Overall Score: 47 / 100 Overall Status: 🟠 Poor Confidence: high

Summary

Site overall 47 is the mean of 5 pages. Scores range 42 (https://larsen.ee/) → 52 (https://larsen.ee/terms-of-service). Weakest page: Mobile PSI performance is critically low at 35 with an 18.9 s LCP, despite decent field data, indicating severe lab bottlenecks. The 69 MB total page weight (55 MB media) is unsustainable for mobile users and directly drives the TBT and LCP failures. Accessibility is blocked by 2 critical axe violations and 11 W3C errors including buttons inside anchors. Security headers are weak (HSTS/CSP) though no auth/payments exist, and image optimization is missing entirely (no srcset).

Per-Page Scores

Page Score Status Confidence
https://larsen.ee/ 42 🟠 Poor high
https://larsen.ee/about 52 🟠 Poor high
https://larsen.ee/faq 45 🟠 Poor high
https://larsen.ee/terms-of-service 52 🟠 Poor high
https://larsen.ee/et 45 🟠 Poor high

PageSpeed Insights — Mobile vs Desktop

Lower is worse for Performance; higher is worse for LCP and CLS. Worse value is bolded.

URL Performance (M / D) LCP (M / D) CLS (M / D)
https://larsen.ee/ 35 / 54 18.90 s / 4.71 s 0.003 / 0.000
https://larsen.ee/about 53 / 54 6.93 s / 3.92 s 0.137 / 0.000
https://larsen.ee/faq 42 / 51 20.62 s / 3.13 s 0.000 / 0.000
https://larsen.ee/terms-of-service 60 / 57 4.20 s / 2.76 s 0.001 / 0.063
https://larsen.ee/et 43 / 55 18.91 s / 4.71 s 0.001 / 0.001

Optimization Checklist

1 of 7 pass — 1 pass · 1 warn · 5 fail

Item Status Detail
Page caching plugin / CDN active ✗ fail No WordPress cache plugin marker or CDN edge cache detected on the document response.
Images lazy-loaded ✗ fail 5 of 7 non-hero raster images are not lazy-loaded (threshold: 2).
Hero image eagerly loaded ✗ fail 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".
Hero is a real <img> (not a CSS background-image) ! warn Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file.
Responsive images (srcset / <picture>) ✗ fail 16/16 raster images lack srcset and are not inside <picture>.
Reasonable number of image sizes ✗ fail No raster images use srcset; browsers cannot pick an optimally sized variant.
JS scripts not blocking in <head> ✓ pass No render-blocking scripts in <head>.

Fixes

Priority 1: Critical

Immediate action — impacts user experience, search rankings, or site safety.

1A. Reduce page weight from 69 MB to under 5 MB

  • Impact: LCP, TBT, Mobile Performance
  • Problem: Total page weight is 69 MB with 55 MB media and 1.3 MB unused JS (app-8897...), causing 18.9 s LCP and 1.03 s TBT on mobile.
  • Solution:
    • Remove unused JavaScript bundles (1.3 MB).
    • Compress and resize media assets (55 MB) to WebP/AVIF.
    • Implement lazy loading for off-screen media.
    • Use a CDN with edge caching to reduce TTFB.

1B. Fix critical accessibility violations

  • Impact: WCAG Compliance, SEO
  • Problem: axe-core reports 2 critical violations: button-name (slider dots) and image-alt (Co-Liv image). W3C reports 5 errors of button inside a.
  • Solution:
    • Add aria-label to slider dot buttons.
    • Add descriptive alt text to the Co-Liv image.
    • Refactor HTML to remove button elements nested inside a tags (use button alone or a alone).

1C. Optimize images to reduce page weight and LCP

  • Impact: LCP, Page Weight, CLS
  • Problem: Images consume 3.75 MB (82% of 4.6 MB total weight); LCP is 6.9 s on mobile. 8 images lack srcset/width/height, and 5 are not lazy-loaded.
  • Solution:
    1. Convert all raster images to WebP/AVIF.
    2. Add srcset and sizes attributes for responsive loading.
    3. Add width and height attributes to prevent CLS.
    4. Add loading="lazy" to non-hero images.
    5. Use fetchpriority="high" on the LCP hero image.

1D. Strengthen Security Headers (CSP & HSTS)

  • Impact: XSS Defense, Transport Security
  • Problem: Security grade is 40/100. HSTS max-age is too short (15552000s) and missing includeSubDomains. CSP only sets frame-ancestors (missing default-src). Site signals indicate User-Generated Content is present, elevating XSS risk.
  • Solution:
    1. Update HSTS: max-age=31536000; includeSubDomains; preload.
    2. Implement strict CSP with nonce/hash: Content-Security-Policy: default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';.
    3. Add X-Frame-Options: SAMEORIGIN as fallback.

1E. Fix Core Web Vitals (LCP/FCP) and Reduce JavaScript

  • Impact: Performance, LCP, FCP, TBT
  • Problem: Mobile LCP is 20.6 s and FCP is 10.65 s; 1.4 MB of unused JavaScript identified (e.g., app-889782a39d4314ef1bf6.js).
  • Solution:
    1. Defer/Remove Unused JS: Audit and remove the 1.4 MB app-*.js bundle or split it. Use defer for non-critical scripts.
    2. Fix Hero Image: Ensure the LCP image (likely the hero) uses loading="eager" (or omit) and fetchpriority="high".
    3. Preload Critical Resources: Add <link rel="preload"> for the hero image and critical CSS.

1F. Resolve Critical Accessibility Violations

  • Impact: WCAG 2.1, Screen Reader Usability
  • Problem: axe-core reports 1 critical (image-alt) and 3 serious violations (html-has-lang, color-contrast, link-name).
  • Solution:
    1. Add lang attribute: <html lang="en">.
    2. Fix Image Alt: Add descriptive alt text to all content images (e.g., Co-Liv.png).
    3. Fix Contrast: Ensure text/background contrast ratio ≥ 4.5:1.
    4. Label Links: Add aria-label to icon links (e.g., Facebook, Instagram) that lack visible text.

1G. Reduce JavaScript bundle size and eliminate unused code

  • Impact: LCP, TBT, FCP, Performance Score
  • Problem: 1398 KB wasted JavaScript (app-889782a39d4314ef1bf6.js) contributes to 756 ms TBT and 4.2 s LCP on mobile.
  • Solution:
    • Implement code splitting to load only necessary JS for the Terms page.
    • Tree-shake unused dependencies.
    • Defer non-critical third-party scripts (GTM, PostHog) until after interaction.

1H. Fix critical accessibility violations and document structure

  • Impact: WCAG 2.1 A/AA Compliance, Screen Reader Usability
  • Problem: 1 critical image-alt violation, 2 serious violations (html-has-lang, link-name), and missing <h1> heading.
  • Solution:
    • Add lang="en" to <html> tag.
    • Add descriptive alt text to all images (e.g., alt="Larsen Hotel Logo").
    • Add a single <h1> element describing the page (e.g., <h1>Terms of Service</h1>).
    • Ensure all links have discernible text or aria-label.

1I. Strengthen Security Headers (HSTS and CSP)

  • Impact: Transport Security, XSS Defense
  • Problem: HSTS max-age is too short (15552000s) and missing directives; CSP lacks default-src despite UGC signals.
  • Solution:
    • Update HSTS: max-age=31536000; includeSubDomains; preload.
    • Implement strict CSP with nonce/hash: default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none';.
    • Add X-Frame-Options: SAMEORIGIN as fallback.

1J. Reduce page weight and fix LCP

  • Impact: Performance, LCP, FCP, TBT
  • Problem: Mobile Performance is 43/100; LCP is 18.9s; total page weight is 69MB (56MB media, 12MB images).
  • Solution:
    • Compress and resize media assets (videos/images) aggressively.
    • Implement lazy loading for below-fold content.
    • Remove unused JavaScript (1.37MB wasted in app-889782a39d4314ef1bf6.js).
    • Enable HTTP/2 or HTTP/3 server push for critical resources.

1K. Strengthen Content Security Policy (CSP)

  • Impact: XSS protection, Data integrity
  • Problem: CSP is present but weak (only frame-ancestors set); site has user-generated content (reviews), elevating XSS risk per the rubric.
  • Solution:
    • Implement a strict CSP with default-src 'self'.
    • Use nonces or hashes for inline scripts.
    • Add object-src 'none' and base-uri 'none'.
    • Example: Content-Security-Policy: default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none';

Priority 2: Important

Essential for compliance, user reach, and search visibility.

2A. Strengthen security headers (HSTS, CSP)

  • Impact: Transport security, XSS defense
  • Problem: HSTS max-age is too short (15552000s) and missing directives; CSP lacks default-src. UGC signal is present but no auth/payments.
  • Solution:
    Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic';
    

2B. Implement responsive images (srcset)

  • Impact: Page weight, CLS, Mobile Performance
  • Problem: 16/16 raster images lack srcset and width/height attributes, preventing browser optimization and risking layout shifts.
  • Solution:
    • Generate multiple image sizes (e.g., 400w, 800w, 1200w).
    • Add srcset and sizes attributes to <img> tags.
    • Add explicit width and height to reserve space.

2C. Reduce JavaScript Bundle Size and Unused Code

  • Impact: TBT, FCP, TTI
  • Problem: 1397 KB of unused JavaScript detected in app-889782a39d4314ef1bf6.js. Multiple third-party scripts (GTM, GA, PostHog) contribute to long tasks (179 ms, 114 ms).
  • Solution:
    1. Code-split the main bundle to defer non-critical JS.
    2. Audit third-party scripts; remove unused tracking pixels (e.g., duplicate GTM/GA instances).
    3. Load non-critical scripts with defer or async.
    4. Implement resource hints (preconnect) for critical third-party origins.

2D. Implement Proper Caching Policy

  • Impact: Repeat Visit Performance, TTFB
  • Problem: Security Headers report shows cache-control: not set. Caching behavior is unpredictable, forcing re-downloads on repeat visits.
  • Solution:
    1. Set Cache-Control: public, max-age=31536000, immutable for static assets (images, CSS, JS).
    2. Set Cache-Control: no-cache, must-revalidate for HTML documents to ensure freshness.
    3. Ensure Vary header is set correctly for content negotiation.

2E. Fix W3C HTML Validation Errors

  • Impact: SEO, Rendering Consistency
  • Problem: 18 W3C errors including obsolete <font> tags, duplicate IDs, and <button> inside <a>.
  • Solution:
    1. Replace <font>: Use CSS for styling (color, size).
    2. Fix Structure: Ensure <button> is not nested inside <a> tags.
    3. Unique IDs: Ensure id="what-are-the-prices..." is unique across the page.
    4. Charset: Move <meta charset="UTF-8"> to the first 1024 bytes of the document.

2F. Optimize Image Delivery

  • Impact: Page Weight, CLS, LCP
  • Problem: 3 images lack width/height (risk of CLS) and srcset (no responsive sizing). Hero image incorrectly lazy-loaded.
  • Solution:
    1. Add Dimensions: Specify width and height attributes on all <img> tags.
    2. Responsive Images: Implement srcset or <picture> for different viewport sizes.
    3. Hero Image: Remove loading="lazy" from the LCP element.

2G. Optimize Hero Image and Add Responsive Variants

  • Impact: LCP, CLS, Data Usage
  • Problem: Hero image uses loading="lazy" (delays LCP) and all 3 images lack srcset or explicit dimensions.
  • Solution:
    • Remove loading="lazy" from the hero image; add fetchpriority="high".
    • Generate WebP/AVIF variants and implement <picture> with srcset.
    • Add width and height attributes to reserve space and prevent CLS.

2H. Fix HSTS and missing security headers

  • Impact: Transport security, Clickjacking protection
  • Problem: HSTS max-age is too short (15552000s) and missing includeSubDomains; X-Frame-Options is missing.
  • Solution:
    • Update HSTS: max-age=31536000; includeSubDomains; preload.
    • Add X-Frame-Options: SAMEORIGIN (or rely on CSP frame-ancestors).
    • Add Permissions-Policy to disable unused features.

2I. Optimize images for responsive delivery

  • Impact: LCP, Data usage, CLS
  • Problem: 16 images lack srcset/sizes; 16 lack explicit width/height; 4 missing loading="lazy".
  • Solution:
    • Generate WebP/AVIF variants and serve via <picture> or srcset.
    • Add width and height attributes to reserve space.
    • Add loading="lazy" to non-hero images.
    • Fix the 1 image missing alt text.

2J. Correct HTML structure and semantics

  • Impact: SEO, Accessibility, W3C validation
  • Problem: W3C reports 11 errors including button inside a (x5), heading skips (h2→h4), and missing lang.
  • Solution:
    • Remove <button> elements nested inside <a> tags; use <a> with role="button" or separate elements.
    • Fix heading hierarchy (h2 → h3, not h2 → h4).
    • Add lang="et" to <html>.
    • Add a skip-to-content link for keyboard navigation.

Priority 3: Best Practice

Recommended for long-term maintainability.

3A. Fix SEO and HTML structure issues

  • Impact: Search visibility, Accessibility
  • Problem: Missing lang attribute, canonical tag, and 11 W3C errors including heading skips (h2→h4).
  • Solution:
    • Add <html lang="en">.
    • Add <link rel="canonical" href="...">.
    • Fix heading hierarchy to not skip levels (h2 → h3).

3B. Improve SEO Metadata and Structure

  • Impact: Search Visibility, Indexing
  • Problem: HTML Inventory shows missing canonical tag, robots meta, and JSON-LD structured data. W3C validator notes missing lang attribute.
  • Solution:
    1. Add <link rel="canonical" href="https://larsen.ee/about">.
    2. Add <meta name="robots" content="index, follow">.
    3. Implement JSON-LD for LocalBusiness or Hotel schema.
    4. Add Twitter Card meta tags for social sharing.

3C. Enable Proper Caching and SEO Metadata

  • Impact: Repeat Visit Performance, Search Visibility
  • Problem: No Cache-Control header (unpredictable caching), missing canonical tag, missing robots.txt.
  • Solution:
    1. Cache-Control: Set Cache-Control: public, max-age=31536000 for static assets.
    2. Canonical: Add <link rel="canonical" href="https://larsen.ee/faq">.
    3. Robots: Ensure robots.txt exists and allows crawling.

3D. Add Missing SEO Metadata and Caching

  • Impact: Search Visibility, Repeat Load Performance
  • Problem: Missing meta description, canonical, and robots tags; no explicit Cache-Control header.
  • Solution:
    • Add <meta name="description" content="..."> and <link rel="canonical" href="...">.
    • Configure server to send Cache-Control: public, max-age=31536000 for static assets.
    • Ensure Terms page is crawlable (check robots.txt).
▸Raw Markdown sent to the LLM
# Site Audit — https://larsen.ee/
Run: 2026-06-10T08:04:47.565Z

Audited **5** of 5 discovered pages.
Average per-page audit coverage: **100%**

Pages audited:
- https://larsen.ee/
- https://larsen.ee/about
- https://larsen.ee/faq
- https://larsen.ee/terms-of-service
- https://larsen.ee/et

---

# Page 1 of 5 — https://larsen.ee/

Run: 2026-06-10T08:04:48.431Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — anchor href contains "review"
- E-commerce: no

## PageSpeed Insights
_Captured in 27215 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **35** | 54 |
| Accessibility | 74 | 74 |
| Best Practices | 96 | 96 |
| SEO | 82 | 82 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **18.9 s** / 2357 ms p75 (fast) | 4.7 s / 1834 ms p75 (fast) |
| CLS | **0.003** / 43 p75 (slow) | 0.000 / 39 p75 (slow) |
| TBT | **1.03 s** | 417 ms |
| FCP | **4.30 s** / 2046 ms p75 (average) | 848 ms / 1558 ms p75 (fast) |
| Speed Index | **15.30 s** | 2.14 s |
| TTFB | 25 ms / 1160 ms p75 (average) | **80 ms** / 918 ms p75 (average) |
| INP (field only) | 407 ms p75 (average) | 240 ms p75 (average) |

### Priority fixes
1. **largest-contentful-paint** (high) — 18.9 s
2. **total-blocking-time** (high) — 1,030 ms
3. **speed-index** (high) — 15.3 s
4. **first-contentful-paint** (high) — 4.3 s
5. **cache-insight** (high) — Est savings of 2,459 KiB

### Findings (mobile)

#### Unused JavaScript
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 1370 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 67 KB wasted
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 67 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 65 KB wasted
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 62 KB wasted
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 38 KB wasted
- https://connect.facebook.net/en_US/fbevents.js — 34 KB wasted
- https://eu-assets.i.posthog.com/static/array.js — 32 KB wasted
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 — 25 KB wasted
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 21 KB wasted
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 21 KB wasted

#### Layout-shift sources
- body > div#react-app > div.cookies — shift 0.003

#### Long tasks
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 478 ms
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 295 ms
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 192 ms
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 186 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 116 ms
- https://connect.facebook.net/en_US/fbevents.js — 110 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 104 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 104 ms
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 101 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 97 ms

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`
- Best Practices: `errorsInConsole`

#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.00, weight 25) — Largest Contentful Paint — 18.9 s
- `total-blocking-time` (performance, score 0.26, weight 30) — Total Blocking Time — 1,030 ms
- `button-name` (accessibility, score 0.00, weight 10) — Buttons do not have an accessible name
- `image-alt` (accessibility, score 0.00, weight 10) — Image elements do not have `[alt]` attributes
- `speed-index` (performance, score 0.01, weight 10) — Speed Index — 15.3 s
- `first-contentful-paint` (performance, score 0.18, weight 10) — First Contentful Paint — 4.3 s
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `html-has-lang` (accessibility, score 0.00, weight 7) — `<html>` element does not have a `[lang]` attribute
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `heading-order` (accessibility, score 0.00, weight 3) — Heading elements are not in a sequentially-descending order
- `lcp-discovery-insight` (performance, score 0.00, weight 0) — LCP request discovery
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `interactive` (performance, score 0.00, weight 0) — Time to Interactive — 40.4 s
- `errors-in-console` (best-practices, score 0.00, weight 1) — Browser errors were logged to the console
- `valid-source-maps` (best-practices, score 0.00, weight 0) — Missing source maps for large first-party JavaScript
- `link-text` (seo, score 0.00, weight 1) — Links do not have descriptive text — 1 link found
- `image-alt` (seo, score 0.00, weight 1) — Image elements do not have `[alt]` attributes
- `max-potential-fid` (performance, score 0.10, weight 0) — Max Potential First Input Delay — 480 ms

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 845 ms._

**Transport:**
- Final URL: https://larsen.ee/
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: not set
- etag: W/"cb905-lGyxHQgfzea1ZnpgWCyq9Dv2wv8"
- last-modified: n/a
- expires: n/a
- pragma: n/a
- vary: Accept-Encoding
- Issues:
  - no cache-control header — caching behavior is unpredictable

**Compression:**
- content-encoding: gzip
- content-length: n/a
- Decoded body: 814.3 KB

### Priority fixes
1. **strict-transport-security weak** (high) — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
2. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
5. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
6. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
7. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
8. **server header discloses technology** (low) — Server: Google Frontend

### Findings

#### Tracked headers
- **strict-transport-security** (weak, high) `max-age=15552000` — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
- **content-security-policy** (weak, high) `frame-ancestors https://hub.larsen.ee` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (missing, medium)
- **x-content-type-options** (present, medium) `nosniff`
- **referrer-policy** (present, low) `no-referrer`
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (present, low) `none`

#### Info disclosure
- Server: `Google Frontend`


#### All response headers
```
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
content-encoding: gzip
content-security-policy: frame-ancestors https://hub.larsen.ee
content-type: text/html; charset=utf-8
date: Wed, 10 Jun 2026 08:04:49 GMT
etag: W/"cb905-lGyxHQgfzea1ZnpgWCyq9Dv2wv8"
expect-ct: max-age=0
referrer-policy: no-referrer
server: Google Frontend
strict-transport-security: max-age=15552000
transfer-encoding: chunked
vary: Accept-Encoding
via: 1.1 google
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-xss-protection: 0
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 1342 ms._

**Scoring:** 11 errors · 1 warnings · 18 cosmetic (suppressed)

### Priority fixes
1. **The element “button” must not appear as a descendant of the “a” element.** (high) — x5, first at line 66
2. **An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.** (medium) — x2, first at line 63
3. **The value of the “for” attribute of the “label” element must be the ID of a non-hidden form control.** (medium) — x2, first at line 66
4. **The heading “h4” (with computed level 4) follows the heading “h2” (with computed level 2), skipping 1 heading level.** (medium) — x2, first at line 66

### Issue groups
- (×2) [error] An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images. — first at line 63 `pt>
      <img height="1" width="1" style="display:none"
        src="https://ww`
- (×5) [error] The element “button” must not appear as a descendant of the “a” element. — first at line 66 `"/search"><button class="button button--main desktop-header__yellow-button deskt`
- (×2) [error] The value of the “for” attribute of the “label” element must be the ID of a non-hidden form control. — first at line 66 `xt-area "><label for="room-type-1">Severa`
- (×1) [warning] This document appears to be written in English. Consider adding “lang="en"” (or variant) to the “html” start tag. — first at line 2 `type html>
<html >
  <he`
- (×2) [error] The heading “h4” (with computed level 4) follows the heading “h2” (with computed level 2), skipping 1 heading level. — first at line 66 `From</div><h4 class="apartment-type-slider__price-price">559<!-`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 5055 ms._

**Scoring:** 7 violations · 36 passes · critical 2 · serious 3 · moderate 2 · minor 0

### Priority fixes
1. **button-name** (high) — Buttons must have discernible text
2. **image-alt** (high) — Images must have alternative text
3. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
4. **html-has-lang** (high) — <html> element must have a lang attribute
5. **link-name** (high) — Links must have discernible text

### Findings

#### `button-name` (critical) — WCAG: wcag2a, wcag412
[Buttons must have discernible text](https://dequeuniversity.com/rules/axe/4.11/button-name?application=playwright)
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .active.slider__dot`
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(2)`
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(3)`
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(4)`
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(5)`
- … and 15 more nodes

#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `.search-container__stay-type-input-wrapper > .search-container__value`
- `.react-datepicker-wrapper:nth-child(4) > .react-datepicker__input-container > .search-container__date-picker-input-container > .search-container__date-picker-input-wrapper > .search-container__value`
- `.react-datepicker-wrapper:nth-child(5) > .react-datepicker__input-container > .search-container__date-picker-input-container > .search-container__date-picker-input-wrapper > .search-container__value`
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-from`
- `.apartment-type-box:nth-child(2) > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-from`
- … and 4 more nodes

#### `heading-order` (moderate)
[Heading levels should only increase by one](https://dequeuniversity.com/rules/axe/4.11/heading-order?application=playwright)
- `.apartment-type-box:nth-child(1) > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-price`
- `.other-features-container__feature:nth-child(1) > .other-features-container__title > h4`

#### `html-has-lang` (serious) — WCAG: wcag2a, wcag311
[<html> element must have a lang attribute](https://dequeuniversity.com/rules/axe/4.11/html-has-lang?application=playwright)
- `html`

#### `image-alt` (critical) — WCAG: wcag2a, wcag111
[Images must have alternative text](https://dequeuniversity.com/rules/axe/4.11/image-alt?application=playwright)
- `img[src$="Co-Liv.e0807b70.png"]`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.larsen-logo-wrapper > .active[aria-current="page"][href="/"]`
- `.footer__icon--facebook`
- `.footer__icon--instagram`

#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.language-switcher.fill-white[href="/et"]:nth-child(1)`
- `.language-switcher.fill-white[href="/et"]:nth-child(2)`
- `.cookies__content`

### Incomplete (axe could not determine)
- [ARIA attributes must conform to valid values](https://dequeuniversity.com/rules/axe/4.11/aria-valid-attr-value?application=playwright) — 1 node
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 16 nodes
- [<video> elements must have captions](https://dequeuniversity.com/rules/axe/4.11/video-caption?application=playwright) — 2 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 5072 ms._

**Capture summary:** 1 console events · 0 mixed-content requests · 56 network requests · 69.08 MB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| media | 4 | 55.78 MB |
| image | 21 | 12.39 MB |
| script | 17 | 820.7 KB |
| font | 2 | 67.8 KB |
| stylesheet | 2 | 40.8 KB |
| xhr | 2 | 15 B |
| document | 1 | 0 B |
| fetch | 5 | 0 B |
| ping | 2 | 0 B |

**Third-party origins (by bytes):**
- https://thumbor.larsen.ee — 5 requests, 4.66 MB
- https://www.googletagmanager.com — 4 requests, 648.0 KB
- https://connect.facebook.net — 3 requests, 152.4 KB
- https://fonts.gstatic.com — 1 request, 43.8 KB
- https://www.google-analytics.com — 2 requests, 20.3 KB
- https://www.google.ee — 2 requests, 84 B
- https://fonts.googleapis.com — 2 requests, 0 B
- https://eu-assets.i.posthog.com — 6 requests, 0 B
- https://region1.analytics.google.com — 2 requests, 0 B
- https://static.hotjar.com — 1 request, 0 B
- https://stats.g.doubleclick.net — 2 requests, 0 B
- https://pagead2.googlesyndication.com — 2 requests, 0 B

**Slowest requests (top 5):**
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (script) — 860 ms, 177.7 KB
- https://connect.facebook.net/en_US/fbevents.js (script) — 860 ms, 97.5 KB
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (script) — 859 ms, 159.2 KB
- https://larsen.ee/ (document) — 688 ms, 0 B
- https://larsen.ee/client/950db29f-e9ed-4c1c-a0ab-955d0b1e1140.46133dc4.woff2 (font) — 577 ms, 23.9 KB

### Priority fixes
1. **failed request** (medium) — media: https://larsen.ee/production/media/2023/video-files/Larsen%20-%20Kokkuvo%CC%83te%20eng%20bars.mp4 — net::ERR_ABORTED
2. **failed request** (medium) — media: https://larsen.ee/videos/uus-logota-larsen-video-2.mp4 — net::ERR_ABORTED
3. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641h1v9128456099za200zd9128456099&_p=1781078689189&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=673458601.1781078690&frm=0&ir=1&pscdl=noapi&rcb=4&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938466~115938469~119061278&sid=1781078690&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2F&dt=Larsen%20-%20The%20Coolest%20Accommodation%20in%20Tallinn&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1798 — net::ERR_ABORTED

### Findings

#### Failed requests
- media: https://larsen.ee/production/media/2023/video-files/Larsen%20-%20Kokkuvo%CC%83te%20eng%20bars.mp4 — net::ERR_ABORTED
- media: https://larsen.ee/videos/uus-logota-larsen-video-2.mp4 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641h1v9128456099za200zd9128456099&_p=1781078689189&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=673458601.1781078690&frm=0&ir=1&pscdl=noapi&rcb=4&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938466~115938469~119061278&sid=1781078690&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2F&dt=Larsen%20-%20The%20Coolest%20Accommodation%20in%20Tallinn&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1798 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=2&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2F&scrsrc=www.googletagmanager.com&rnd=1189765395.1781078690&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115938466~115938469&apve=1&apvf=f&apvc=1&tft=1781078690387&tfd=1893 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078689189&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=673458601.1781078690&frm=0&pscdl=noapi&rcb=17&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616985~115938466~115938469~118395334&sid=1781078690&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2F&dt=Larsen%20-%20The%20Coolest%20Accommodation%20in%20Tallinn&en=page_view&_fv=1&_ss=1&tfd=2149 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=17&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2F&scrsrc=www.googletagmanager.com&rnd=1189765395.1781078690&navt=n&npa=1&gtm=45be6641v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616985~115938466~115938469&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078690747&tfd=2253 — net::ERR_ABORTED

#### Console events
- [warning] Hotjar not launching due to suspicious userAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.7778.96 Safari/537.36 (https://static.hotjar.com/c/hotjar-3296638.js?sv=7)

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 5072 ms._

**Document:**
- Lang: not set
- Title: Larsen - The Coolest Accommodation in Tallinn
- Canonical: not set
- Viewport: width=device-width
- Charset: UTF-8
- HTML bytes: 850065

**Meta tags:**
- Description: Looking for a stress-free rental experience in Tallinn? Look no further than Larsen, your trusted accommodation service provider. From short-term to long-term rentals, our fully furnished apartments offer the perfect solution for your accommodation needs. Discover the Larsen difference today and enjoy the ultimate in comfort and convenience.
- Robots: not set
- Theme color: #ffffff
- Open Graph tags: 3 (og:title, og:description, og:image)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×1, h2 ×21, h3 ×6, h4 ×14, h5 ×0, h6 ×0
- Sequence (first 20):
  - h1: Tallinn accommodation made easy
  - h2: Everyone's welcome here -  no bureaucracy, no hassle.
  - h4: 559 €
  - h3: Sume Loft with Balcony
  - h4: 489 €
  - h3: Sume Twin Studio with Balcony
  - h4: 459 €
  - h3: Sume Studio with Balcony
  - h4: 54 €
  - h4: 419 €
  - h3: Eduard House Studio L
  - h2: Looking for something else?
  - h2: Eduard House
  - h2: Instant booking, no hassle
  - h2: Join our vibrant community
  - h2: Why stay with Larsen?
  - h4: Flexible length of stay
  - h4: Instant booking
  - h4: Fully furnished
  - h4: Co-living areas
- Skips:
  - h2 → h4 after "Everyone's welcome here -  no bureaucracy, no hassle."
  - h2 → h4 after "Why stay with Larsen?"

**Landmarks:**
- nav: present
- main: present
- header: **missing**
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 26 total — 0 defer, 16 async, 1 render-blocking. Speculation rules: no.

External scripts (first 15):
- https://static.hotjar.com/c/hotjar-3296638.js?sv=7 (async)
- https://www.google-analytics.com/analytics.js (async)
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 (async)
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 (async)
- https://eu-assets.i.posthog.com/static/array.js (async)
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (async)
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 (async)
- https://connect.facebook.net/en_US/fbevents.js (async)
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (async)
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (async)
- https://eu-assets.i.posthog.com/static/web-vitals.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/dead-clicks-autocapture.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/array/phc_9AAcqE521KLngxSgpVorPQDkU4ENZA9RJXVJnkr12nN/config.js (async)

**Stylesheets:** 1 external, 2 inline (1.2 KB)

**Images:** 16 total — **1 without alt**, **16 without width/height**, 4 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| s://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg | thumbnail of the video | _n/a_ | _n/a_ | ✗ |
| ttps://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| s://larsen.ee/production/media/2025/03/rocca-house-drone.png | _(empty)_ | _n/a_ | lazy | ✗ |
| 0)/https://larsen.ee/production/media/2021/12/img-1042-1.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /larsen.ee/production/media/2024/09/dji-0044-enhanced-nr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| (90)/https://larsen.ee/production/media/2025/11/ttun8888.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/11/ttun8720-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/09/ttun8103-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/09/ttun8394-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| (90)/https://larsen.ee/production/media/2024/04/-tun4221.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| ttps://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg | Building image | _n/a_ | lazy | ✗ |
| https://larsen.ee/images/rectangle/Rectangle-158.png | imageOne | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/rectangle/Rectangle-159.png | imageOne | _n/a_ | _n/a_ | ✗ |
| lity(90)/https://larsen.ee/production/media/2024/07/karl.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png | _(empty)_ | _n/a_ | lazy | ✗ |

**Links:** 36 anchors — 3 external, 1 preconnect, 0 preload.

Vague repeated link text:
- "all available rooms" ×2

### Priority fixes
1. **Heading level skips** (medium) — h2→h4 after "Everyone's welcome here -  no bureaucrac"; h2→h4 after "Why stay with Larsen?"
2. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
3. **1 images without alt attribute** (high) — Content images need descriptive alt text; decorative images need empty alt=""
4. **16 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 0 ms._

**Summary:** 1 pass · 3 warn · 3 fail

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ! warn | 3 of 15 non-hero raster images are not lazy-loaded. |
| Hero image eagerly loaded | ! warn | Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP. |
| Hero is a real <img> (not a CSS background-image) | ! warn | Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file. |
| Responsive images (srcset / <picture>) | ✗ fail | 16/16 raster images lack srcset and are not inside <picture>. |
| Reasonable number of image sizes | ✗ fail | No raster images use srcset; browsers cannot pick an optimally sized variant. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Images lazy-loaded:
  - `https://larsen.ee/images/rectangle/Rectangle-158.png`
  - `https://larsen.ee/images/rectangle/Rectangle-159.png`
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`
- Hero image eagerly loaded:
  - `hero: https://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg`
  - `loading: (not set)`
  - `fetchpriority: (not set)`
- Hero is a real <img> (not a CSS background-image):
  - `selector: div.buildings-map__map-overlay`
  - `url: https://larsen.ee/client/Tallinn.d777459c.png`
  - `box: 520×1021px`
- Responsive images (srcset / <picture>):
  - `https://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg`
  - `…ers:quality(90)/https://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg`
  - `…:quality(90)/https://larsen.ee/production/media/2025/03/rocca-house-drone.png`
  - `…filters:quality(90)/https://larsen.ee/production/media/2021/12/img-1042-1.jpg`
  - `…ality(90)/https://larsen.ee/production/media/2024/09/dji-0044-enhanced-nr.jpg`

### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Responsive images (srcset / <picture>)** (high) — 16/16 raster images lack srcset and are not inside <picture>.
3. **Reasonable number of image sizes** (high) — No raster images use srcset; browsers cannot pick an optimally sized variant.
4. **Images lazy-loaded** (medium) — 3 of 15 non-hero raster images are not lazy-loaded.
5. **Hero image eagerly loaded** (medium) — Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP.
6. **Hero is a real <img> (not a CSS background-image)** (medium) — Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file.

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).

---

# Page 2 of 5 — https://larsen.ee/about

Run: 2026-06-10T08:04:48.435Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — anchor href contains "review"
- E-commerce: no

## PageSpeed Insights
_Captured in 21594 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **53** | 54 |
| Accessibility | 82 | 82 |
| Best Practices | 100 | 100 |
| SEO | 91 | 91 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **6.9 s** / 3555 ms p75 (average) | 3.9 s / 2726 ms p75 (average) |
| CLS | **0.137** / 6 p75 (fast) | 0.000 / 43 p75 (slow) |
| TBT | 217 ms | **605 ms** |
| FCP | **3.21 s** / 3280 ms p75 (slow) | 968 ms / 2197 ms p75 (average) |
| Speed Index | **10.59 s** | 968 ms |
| TTFB | 27 ms / 2621 ms p75 (slow) | **30 ms** / 1414 ms p75 (average) |
| INP (field only) | 390 ms p75 (average) | 245 ms p75 (average) |

### Priority fixes
1. **largest-contentful-paint** (high) — 6.9 s
2. **speed-index** (high) — 10.6 s
3. **first-contentful-paint** (high) — 3.2 s
4. **cumulative-layout-shift** (low) — 0.137
5. **total-blocking-time** (low) — 220 ms

### Findings (mobile)

#### Unused JavaScript
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 1397 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 69 KB wasted
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 68 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 66 KB wasted
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 64 KB wasted
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 37 KB wasted
- https://connect.facebook.net/en_US/fbevents.js — 34 KB wasted
- https://eu-assets.i.posthog.com/static/array.js — 32 KB wasted
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 — 25 KB wasted
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 22 KB wasted
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 21 KB wasted

#### Layout-shift sources
- body > div#react-app > div.cookies — shift 0.136
- body > div#react-app > div.cookies — shift 0.001

#### Long tasks
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 179 ms
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 114 ms
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 89 ms
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 88 ms
- Unattributable — 67 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 66 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 55 ms
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 55 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 54 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 52 ms

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`

#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.06, weight 25) — Largest Contentful Paint — 6.9 s
- `image-alt` (accessibility, score 0.00, weight 10) — Image elements do not have `[alt]` attributes
- `speed-index` (performance, score 0.07, weight 10) — Speed Index — 10.6 s
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `html-has-lang` (accessibility, score 0.00, weight 7) — `<html>` element does not have a `[lang]` attribute
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `first-contentful-paint` (performance, score 0.43, weight 10) — First Contentful Paint — 3.2 s
- `cumulative-layout-shift` (performance, score 0.79, weight 25) — Cumulative Layout Shift — 0.137
- `total-blocking-time` (performance, score 0.88, weight 30) — Total Blocking Time — 220 ms
- `cls-culprits-insight` (performance, score 0.00, weight 0) — Layout shift culprits
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `interactive` (performance, score 0.00, weight 0) — Time to Interactive — 27.9 s
- `valid-source-maps` (best-practices, score 0.00, weight 0) — Missing source maps for large first-party JavaScript
- `image-alt` (seo, score 0.00, weight 1) — Image elements do not have `[alt]` attributes
- `max-potential-fid` (performance, score 0.74, weight 0) — Max Potential First Input Delay — 180 ms

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 428 ms._

**Transport:**
- Final URL: https://larsen.ee/about
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: not set
- etag: W/"2262f-fKX7/URi4xwqB6pna+/Ow705M0c"
- last-modified: n/a
- expires: n/a
- pragma: n/a
- vary: Accept-Encoding
- Issues:
  - no cache-control header — caching behavior is unpredictable

**Compression:**
- content-encoding: gzip
- content-length: n/a
- Decoded body: 137.5 KB

### Priority fixes
1. **strict-transport-security weak** (high) — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
2. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
5. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
6. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
7. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
8. **server header discloses technology** (low) — Server: Google Frontend

### Findings

#### Tracked headers
- **strict-transport-security** (weak, high) `max-age=15552000` — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
- **content-security-policy** (weak, high) `frame-ancestors https://hub.larsen.ee` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (missing, medium)
- **x-content-type-options** (present, medium) `nosniff`
- **referrer-policy** (present, low) `no-referrer`
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (present, low) `none`

#### Info disclosure
- Server: `Google Frontend`


#### All response headers
```
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
content-encoding: gzip
content-security-policy: frame-ancestors https://hub.larsen.ee
content-type: text/html; charset=utf-8
date: Wed, 10 Jun 2026 08:04:48 GMT
etag: W/"2262f-fKX7/URi4xwqB6pna+/Ow705M0c"
expect-ct: max-age=0
referrer-policy: no-referrer
server: Google Frontend
strict-transport-security: max-age=15552000
transfer-encoding: chunked
vary: Accept-Encoding
via: 1.1 google
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-xss-protection: 0
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 1120 ms._

**Scoring:** 3 errors · 1 warnings · 20 cosmetic (suppressed)

### Priority fixes
1. **An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.** (medium) — x2, first at line 63
2. **The element “button” must not appear as a descendant of the “a” element.** (medium) — x1, first at line 66

### Issue groups
- (×2) [error] An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images. — first at line 63 `pt>
      <img height="1" width="1" style="display:none"
        src="https://ww`
- (×1) [error] The element “button” must not appear as a descendant of the “a” element. — first at line 66 `"/search"><button class="button button--main desktop-header__yellow-button deskt`
- (×1) [warning] This document appears to be written in English. Consider adding “lang="en"” (or variant) to the “html” start tag. — first at line 2 `type html>
<html >
  <he`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 5215 ms._

**Scoring:** 5 violations · 33 passes · critical 1 · serious 3 · moderate 1 · minor 0

### Priority fixes
1. **image-alt** (high) — Images must have alternative text
2. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
3. **html-has-lang** (high) — <html> element must have a lang attribute
4. **link-name** (high) — Links must have discernible text
5. **region** (medium) — All page content should be contained by landmarks

### Findings

#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `a[href$="about"] > .text`

#### `html-has-lang` (serious) — WCAG: wcag2a, wcag311
[<html> element must have a lang attribute](https://dequeuniversity.com/rules/axe/4.11/html-has-lang?application=playwright)
- `html`

#### `image-alt` (critical) — WCAG: wcag2a, wcag111
[Images must have alternative text](https://dequeuniversity.com/rules/axe/4.11/image-alt?application=playwright)
- `img[src$="Co-Liv.e0807b70.png"]`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.active[aria-current="page"][href="/"]`
- `.footer__icon--facebook`
- `.footer__icon--instagram`

#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.language-switcher.active[href$="meist"]`
- `.language-switcher.fill-white[href$="meist"]:nth-child(2)`
- `.cookies__content`

### Incomplete (axe could not determine)
- [ARIA attributes must conform to valid values](https://dequeuniversity.com/rules/axe/4.11/aria-valid-attr-value?application=playwright) — 1 node
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 5 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 5223 ms._

**Capture summary:** 1 console events · 0 mixed-content requests · 40 network requests · 4.60 MB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| image | 9 | 3.75 MB |
| script | 17 | 765.8 KB |
| font | 2 | 67.8 KB |
| stylesheet | 2 | 40.8 KB |
| xhr | 2 | 15 B |
| document | 1 | 0 B |
| fetch | 5 | 0 B |
| ping | 2 | 0 B |

**Third-party origins (by bytes):**
- https://www.googletagmanager.com — 4 requests, 648.0 KB
- https://connect.facebook.net — 3 requests, 97.5 KB
- https://fonts.gstatic.com — 1 request, 43.8 KB
- https://www.google-analytics.com — 2 requests, 20.3 KB
- https://www.google.ee — 2 requests, 84 B
- https://fonts.googleapis.com — 2 requests, 0 B
- https://eu-assets.i.posthog.com — 6 requests, 0 B
- https://region1.analytics.google.com — 2 requests, 0 B
- https://stats.g.doubleclick.net — 2 requests, 0 B
- https://pagead2.googlesyndication.com — 2 requests, 0 B
- https://static.hotjar.com — 1 request, 0 B
- https://www.chatbase.co — 2 requests, 0 B

**Slowest requests (top 5):**
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (script) — 1.13 s, 0 B
- https://fonts.gstatic.com/s/intertight/v9/NGSwv5HMAFg6IuGlBNMjxLsH8ag.woff2 (font) — 532 ms, 43.8 KB
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (script) — 514 ms, 177.7 KB
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (script) — 514 ms, 159.2 KB
- https://connect.facebook.net/en_US/fbevents.js (script) — 514 ms, 97.5 KB

### Priority fixes
1. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078688640&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=1440177753.1781078690&frm=0&ir=1&pscdl=noapi&rcb=0&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938466~115938469&sid=1781078689&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fabout&dt=About%20Larsen&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1534 — net::ERR_ABORTED
2. **failed request** (medium) — fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=4&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fabout&scrsrc=www.googletagmanager.com&rnd=1734185287.1781078690&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115938466~115938468~117776794~119061279&apve=1&apvf=f&apvc=1&tft=1781078690079&tfd=1584 — net::ERR_ABORTED
3. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078688640&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=1440177753.1781078690&frm=0&pscdl=noapi&rcb=19&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938466~115938469~118012009&sid=1781078690&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fabout&dt=About%20Larsen&en=page_view&_fv=1&_ss=1&tfd=1866 — net::ERR_ABORTED

### Findings

#### Failed requests
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078688640&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=1440177753.1781078690&frm=0&ir=1&pscdl=noapi&rcb=0&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938466~115938469&sid=1781078689&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fabout&dt=About%20Larsen&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1534 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=4&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fabout&scrsrc=www.googletagmanager.com&rnd=1734185287.1781078690&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115938466~115938468~117776794~119061279&apve=1&apvf=f&apvc=1&tft=1781078690079&tfd=1584 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078688640&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=1440177753.1781078690&frm=0&pscdl=noapi&rcb=19&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938466~115938469~118012009&sid=1781078690&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fabout&dt=About%20Larsen&en=page_view&_fv=1&_ss=1&tfd=1866 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=1&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fabout&scrsrc=www.googletagmanager.com&rnd=1734185287.1781078690&navt=n&npa=1&gtm=45be6641v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938466~115938469&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078690448&tfd=1953 — net::ERR_ABORTED

#### Console events
- [warning] Hotjar not launching due to suspicious userAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.7778.96 Safari/537.36 (https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0)

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 5222 ms._

**Document:**
- Lang: not set
- Title: About Larsen
- Canonical: not set
- Viewport: width=device-width
- Charset: UTF-8
- HTML bytes: 152901

**Meta tags:**
- Description: Learn more about Larsen
- Robots: not set
- Theme color: #ffffff
- Open Graph tags: 3 (og:title, og:description, og:image)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×1, h2 ×18, h3 ×2, h4 ×1, h5 ×0, h6 ×0
- Sequence (first 20):
  - h1: About & Contact
  - h2: Finding a place to stay can be a stressful undertaking.
  - h2: But it doesn't have to be like that.
  - h2: Larsen houses offer a selection of fully furnished rooms
  - h2: Sounds good? Then book via this website or get in touch if you have further ques
  - h2: Navigate
  - h2: Home
  - h2: Rooms
  - h2: Locations
  - h2: Features
  - h2: Testimonials
  - h2: About & Contact
  - h2: FAQ
  - h2: Kuubik Storages
  - h2: For customers
  - h2: Report an issue
  - h2: House rules
  - h2: Contract preview
  - h2: Customer support
  - h3: Karl Limbak

**Landmarks:**
- nav: present
- main: present
- header: **missing**
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 26 total — 0 defer, 16 async, 1 render-blocking. Speculation rules: no.

External scripts (first 15):
- https://static.hotjar.com/c/hotjar-3296638.js?sv=7 (async)
- https://www.google-analytics.com/analytics.js (async)
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 (async)
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 (async)
- https://eu-assets.i.posthog.com/static/array.js (async)
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (async)
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 (async)
- https://connect.facebook.net/en_US/fbevents.js (async)
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (async)
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (async)
- https://eu-assets.i.posthog.com/static/web-vitals.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/dead-clicks-autocapture.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/array/phc_9AAcqE521KLngxSgpVorPQDkU4ENZA9RJXVJnkr12nN/config.js (async)

**Stylesheets:** 1 external, 2 inline (1.2 KB)

**Images:** 8 total — **1 without alt**, **8 without width/height**, 6 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| https://larsen.ee/images/features/about_and_contact/1.jpg | imageOne | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/features/about_and_contact/2.jpg | imageTwo | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/features/about_and_contact/3.jpg | imageOne | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/features/about_and_contact/4.jpg | imageTwo | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/features/about_and_contact/5.jpg | imageOne | _n/a_ | _n/a_ | ✗ |
| lity(90)/https://larsen.ee/production/media/2024/07/karl.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/client/Co-Liv.e0807b70.png | _(no attr)_ | _n/a_ | _n/a_ | ✗ |

**Links:** 20 anchors — 3 external, 1 preconnect, 0 preload.

### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **1 images without alt attribute** (high) — Content images need descriptive alt text; decorative images need empty alt=""
3. **8 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 0 ms._

**Summary:** 1 pass · 2 warn · 4 fail

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ✗ fail | 5 of 7 non-hero raster images are not lazy-loaded (threshold: 2). |
| Hero image eagerly loaded | ! warn | Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP. |
| Hero is a real <img> (not a CSS background-image) | ! warn | Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file. |
| Responsive images (srcset / <picture>) | ✗ fail | 8/8 raster images lack srcset and are not inside <picture>. |
| Reasonable number of image sizes | ✗ fail | No raster images use srcset; browsers cannot pick an optimally sized variant. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Images lazy-loaded:
  - `https://larsen.ee/images/features/about_and_contact/2.jpg`
  - `https://larsen.ee/images/features/about_and_contact/3.jpg`
  - `https://larsen.ee/images/features/about_and_contact/4.jpg`
  - `https://larsen.ee/images/features/about_and_contact/5.jpg`
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`
- Hero image eagerly loaded:
  - `hero: https://larsen.ee/images/features/about_and_contact/1.jpg`
  - `loading: (not set)`
  - `fetchpriority: (not set)`
- Hero is a real <img> (not a CSS background-image):
  - `selector: div.single-feature-page__title-container`
  - `url: https://larsen.ee/images/features/about_and_contact/hero_about_and_contact.jpg`
  - `box: 1280×576px`
- Responsive images (srcset / <picture>):
  - `https://larsen.ee/images/features/about_and_contact/1.jpg`
  - `https://larsen.ee/images/features/about_and_contact/2.jpg`
  - `https://larsen.ee/images/features/about_and_contact/3.jpg`
  - `https://larsen.ee/images/features/about_and_contact/4.jpg`
  - `https://larsen.ee/images/features/about_and_contact/5.jpg`

### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Images lazy-loaded** (high) — 5 of 7 non-hero raster images are not lazy-loaded (threshold: 2).
3. **Responsive images (srcset / <picture>)** (high) — 8/8 raster images lack srcset and are not inside <picture>.
4. **Reasonable number of image sizes** (high) — No raster images use srcset; browsers cannot pick an optimally sized variant.
5. **Hero image eagerly loaded** (medium) — Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP.
6. **Hero is a real <img> (not a CSS background-image)** (medium) — Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file.

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).

---

# Page 3 of 5 — https://larsen.ee/faq

Run: 2026-06-10T08:05:10.031Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — anchor href contains "review"
- E-commerce: no

## PageSpeed Insights
_Captured in 23901 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **42** | 51 |
| Accessibility | 80 | 80 |
| Best Practices | 100 | 100 |
| SEO | 91 | 91 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **20.6 s** / 3555 ms p75 (average) | 3.1 s / 2726 ms p75 (average) |
| CLS | 0.000 / 6 p75 (fast) | **0.000** / 43 p75 (slow) |
| TBT | 531 ms | **1.01 s** |
| FCP | **10.65 s** / 3280 ms p75 (slow) | 1.03 s / 2197 ms p75 (average) |
| Speed Index | **10.65 s** | 1.58 s |
| TTFB | 47 ms / 2621 ms p75 (slow) | **49 ms** / 1414 ms p75 (average) |
| INP (field only) | 390 ms p75 (average) | 245 ms p75 (average) |

### Priority fixes
1. **largest-contentful-paint** (high) — 20.6 s
2. **total-blocking-time** (medium) — 530 ms
3. **first-contentful-paint** (high) — 10.7 s
4. **speed-index** (high) — 10.7 s
5. **cache-insight** (high) — Est savings of 484 KiB

### Findings (mobile)

#### Unused JavaScript
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 1398 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 69 KB wasted
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 68 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 66 KB wasted
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 63 KB wasted
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 38 KB wasted
- https://connect.facebook.net/en_US/fbevents.js — 34 KB wasted
- https://eu-assets.i.posthog.com/static/array.js — 32 KB wasted
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 — 25 KB wasted
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 22 KB wasted
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 21 KB wasted

#### Long tasks
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 286 ms
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 163 ms
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 134 ms
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 120 ms
- Unattributable — 117 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 90 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 84 ms
- https://connect.facebook.net/en_US/fbevents.js — 81 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 65 ms
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 65 ms

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`

#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.00, weight 25) — Largest Contentful Paint — 20.6 s
- `total-blocking-time` (performance, score 0.55, weight 30) — Total Blocking Time — 530 ms
- `first-contentful-paint` (performance, score 0.00, weight 10) — First Contentful Paint — 10.7 s
- `image-alt` (accessibility, score 0.00, weight 10) — Image elements do not have `[alt]` attributes
- `speed-index` (performance, score 0.07, weight 10) — Speed Index — 10.7 s
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `html-has-lang` (accessibility, score 0.00, weight 7) — `<html>` element does not have a `[lang]` attribute
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `forced-reflow-insight` (performance, score 0.00, weight 0) — Forced reflow
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `valid-source-maps` (best-practices, score 0.00, weight 0) — Missing source maps for large first-party JavaScript
- `image-alt` (seo, score 0.00, weight 1) — Image elements do not have `[alt]` attributes
- `interactive` (performance, score 0.02, weight 0) — Time to Interactive — 20.6 s
- `max-potential-fid` (performance, score 0.39, weight 0) — Max Potential First Input Delay — 290 ms

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 186 ms._

**Transport:**
- Final URL: https://larsen.ee/faq
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: not set
- etag: W/"3bc31-wIMAA6OM6U8zFExsjO/Zl0alJus"
- last-modified: n/a
- expires: n/a
- pragma: n/a
- vary: Accept-Encoding
- Issues:
  - no cache-control header — caching behavior is unpredictable

**Compression:**
- content-encoding: gzip
- content-length: n/a
- Decoded body: 239.0 KB

### Priority fixes
1. **strict-transport-security weak** (high) — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
2. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
5. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
6. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
7. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
8. **server header discloses technology** (low) — Server: Google Frontend

### Findings

#### Tracked headers
- **strict-transport-security** (weak, high) `max-age=15552000` — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
- **content-security-policy** (weak, high) `frame-ancestors https://hub.larsen.ee` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (missing, medium)
- **x-content-type-options** (present, medium) `nosniff`
- **referrer-policy** (present, low) `no-referrer`
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (present, low) `none`

#### Info disclosure
- Server: `Google Frontend`


#### All response headers
```
alt-svc: h3=":443"; ma=2592000
content-encoding: gzip
content-security-policy: frame-ancestors https://hub.larsen.ee
content-type: text/html; charset=utf-8
date: Wed, 10 Jun 2026 08:05:10 GMT
etag: W/"3bc31-wIMAA6OM6U8zFExsjO/Zl0alJus"
expect-ct: max-age=0
referrer-policy: no-referrer
server: Google Frontend
strict-transport-security: max-age=15552000
transfer-encoding: chunked
vary: Accept-Encoding
via: 1.1 google
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-xss-protection: 0
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 533 ms._

**Scoring:** 18 errors · 3 warnings · 15 cosmetic (suppressed)

### Priority fixes
1. **The “font” element is obsolete. Use CSS instead.** (high) — x7, first at line 66
2. **No “p” element in scope but a “p” end tag seen.** (medium) — x4, first at line 67
3. **An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.** (medium) — x2, first at line 63
4. **CSS: “color”: Parse Error.** (medium) — x2, first at line 67
5. **A “charset” attribute on a “meta” element found after the first 1024 bytes.** (medium) — x1, first at line 35

### Issue groups
- (×1) [error] A “charset” attribute on a “meta” element found after the first 1024 bytes. — first at line 35 `charset="UTF-8">
    <title d`
- (×2) [error] An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images. — first at line 63 `pt>
      <img height="1" width="1" style="display:none"
        src="https://ww`
- (×1) [error] The element “button” must not appear as a descendant of the “a” element. — first at line 66 `"/search"><button class="button button--main desktop-header__yellow-button deskt`
- (×7) [error] The “font” element is obsolete. Use CSS instead. — first at line 66 `style=""><font color="#000000"><span`
- (×1) [error] Duplicate ID “what-are-the-prices-of-the-rooms-and-what-does-the-price-depend-on?”. — first at line 66 `div></div><div class="accordion-wrapper  " id="what-are-the-prices-of-the-rooms-`
- (×1) [warning] The first occurrence of ID “what-are-the-prices-of-the-rooms-and-what-does-the-price-depend-on?” was here. — first at line 66 `div></div><div class="accordion-wrapper  " id="what-are-the-prices-of-the-rooms-`
- (×4) [error] No “p” element in scope but a “p” end tag seen. — first at line 67 `an></font></p><p cla`
- (×2) [error] CSS: “color”: Parse Error. — first at line 67 `></div><p><span style="background-color: rgba(255,255,255,var(--tw-bg-opacity));`
- (×1) [warning] This document appears to be written in English. Consider adding “lang="en"” (or variant) to the “html” start tag. — first at line 2 `type html>
<html >
  <he`
- (×1) [warning] This document has heading elements but none of them has a computed heading level of 1. — first at line 66 `s="topic"><h3 id="long-term-booking" class="topic-title h3">Long-T`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 3278 ms._

**Scoring:** 7 violations · 29 passes · critical 1 · serious 3 · moderate 3 · minor 0

### Priority fixes
1. **image-alt** (high) — Images must have alternative text
2. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
3. **html-has-lang** (high) — <html> element must have a lang attribute
4. **link-name** (high) — Links must have discernible text
5. **landmark-one-main** (medium) — Document should have one main landmark

### Findings

#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `a[href$="faq"] > h2`

#### `html-has-lang` (serious) — WCAG: wcag2a, wcag311
[<html> element must have a lang attribute](https://dequeuniversity.com/rules/axe/4.11/html-has-lang?application=playwright)
- `html`

#### `image-alt` (critical) — WCAG: wcag2a, wcag111
[Images must have alternative text](https://dequeuniversity.com/rules/axe/4.11/image-alt?application=playwright)
- `img[src$="Co-Liv.e0807b70.png"]`

#### `landmark-one-main` (moderate)
[Document should have one main landmark](https://dequeuniversity.com/rules/axe/4.11/landmark-one-main?application=playwright)
- `html`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.active[aria-current="page"][href="/"]`
- `.footer__icon--facebook`
- `.footer__icon--instagram`

#### `page-has-heading-one` (moderate)
[Page should contain a level-one heading](https://dequeuniversity.com/rules/axe/4.11/page-has-heading-one?application=playwright)
- `html`

#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.language-switcher.active[href$="kkk"]`
- `.language-switcher.fill-black[href$="kkk"]:nth-child(2)`
- `.page`
- `.cookies__content`

### Incomplete (axe could not determine)
- [ARIA attributes must conform to valid values](https://dequeuniversity.com/rules/axe/4.11/aria-valid-attr-value?application=playwright) — 1 node
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 18 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 3293 ms._

**Capture summary:** 1 console events · 0 mixed-content requests · 35 network requests · 1.21 MB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| script | 17 | 843.4 KB |
| image | 3 | 267.0 KB |
| font | 3 | 91.3 KB |
| stylesheet | 2 | 40.8 KB |
| xhr | 2 | 15 B |
| document | 1 | 0 B |
| fetch | 5 | 0 B |
| ping | 2 | 0 B |

**Third-party origins (by bytes):**
- https://www.googletagmanager.com — 4 requests, 648.0 KB
- https://connect.facebook.net — 3 requests, 175.1 KB
- https://fonts.gstatic.com — 1 request, 43.8 KB
- https://www.google-analytics.com — 2 requests, 20.3 KB
- https://www.google.ee — 2 requests, 84 B
- https://fonts.googleapis.com — 2 requests, 0 B
- https://eu-assets.i.posthog.com — 6 requests, 0 B
- https://region1.analytics.google.com — 2 requests, 0 B
- https://static.hotjar.com — 1 request, 0 B
- https://stats.g.doubleclick.net — 2 requests, 0 B
- https://pagead2.googlesyndication.com — 2 requests, 0 B
- https://www.chatbase.co — 2 requests, 0 B

**Slowest requests (top 5):**
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (script) — 358 ms, 177.7 KB
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (script) — 358 ms, 159.2 KB
- https://connect.facebook.net/en_US/fbevents.js (script) — 358 ms, 97.5 KB
- https://www.chatbase.co/api/get-chatbot-styles/y7CotFfAzSHKzmcew7JaK (fetch) — 328 ms, 0 B
- https://eu-assets.i.posthog.com/static/array.js (script) — 196 ms, 0 B

### Priority fixes
1. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078710244&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=344294286.1781078711&frm=0&ir=1&pscdl=noapi&rcb=7&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938468~119061279&sid=1781078710&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Ffaq&dt=Larsen%20Accommodation%20FAQ%20%E2%80%93%20Contracts%2C%20Payments%2C%20Check-In%20%26%20More&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=631 — net::ERR_ABORTED
2. **failed request** (medium) — fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=19&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Ffaq&scrsrc=www.googletagmanager.com&rnd=780803480.1781078711&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938469~117776793&apve=1&apvf=f&apvc=1&tft=1781078710759&tfd=694 — net::ERR_ABORTED
3. **failed request** (medium) — fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=3&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Ffaq&scrsrc=www.googletagmanager.com&rnd=780803480.1781078711&navt=n&npa=1&gtm=45be6641v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938468~117776793~118012009~119061279&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078710994&tfd=928 — net::ERR_ABORTED

### Findings

#### Failed requests
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078710244&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=344294286.1781078711&frm=0&ir=1&pscdl=noapi&rcb=7&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938468~119061279&sid=1781078710&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Ffaq&dt=Larsen%20Accommodation%20FAQ%20%E2%80%93%20Contracts%2C%20Payments%2C%20Check-In%20%26%20More&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=631 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=19&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Ffaq&scrsrc=www.googletagmanager.com&rnd=780803480.1781078711&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938469~117776793&apve=1&apvf=f&apvc=1&tft=1781078710759&tfd=694 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=3&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Ffaq&scrsrc=www.googletagmanager.com&rnd=780803480.1781078711&navt=n&npa=1&gtm=45be6641v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938468~117776793~118012009~119061279&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078710994&tfd=928 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078710244&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=344294286.1781078711&frm=0&pscdl=noapi&rcb=19&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938469&sid=1781078711&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Ffaq&dt=Larsen%20Accommodation%20FAQ%20%E2%80%93%20Contracts%2C%20Payments%2C%20Check-In%20%26%20More&en=page_view&_fv=1&_ss=1&tfd=987 — net::ERR_ABORTED

#### Console events
- [warning] Hotjar not launching due to suspicious userAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.7778.96 Safari/537.36 (https://static.hotjar.com/c/hotjar-3296638.js?sv=7)

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 3293 ms._

**Document:**
- Lang: not set
- Title: Larsen Accommodation FAQ – Contracts, Payments, Check-In & More
- Canonical: not set
- Viewport: width=device-width
- Charset: UTF-8
- HTML bytes: 256700

**Meta tags:**
- Description: Find answers to common questions about staying at Larsen — including contract terms, payments, deposits, utilities, check-in info, and long-term housing support.
- Robots: not set
- Theme color: #ffffff
- Open Graph tags: 3 (og:title, og:description, og:image)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×0, h2 ×14, h3 ×18, h4 ×1, h5 ×0, h6 ×0
- Sequence (first 20):
  - h3: Long-Term booking
  - h3: Short-Term booking
  - h3: Payments
  - h3: Houses and room types
  - h3: Arrival
  - h3: Parking
  - h3: Pets
  - h3: Room and house change
  - h3: In your new room
  - h3: Larsen community
  - h3: Departure
  - h3: Extension
  - h3: Cancellation
  - h3: Contacts
  - h3: Legal Residence & Documents
  - h3: Storages -  Kuubik
  - h2: Navigate
  - h2: Home
  - h2: Rooms
  - h2: Locations

**Landmarks:**
- nav: present
- main: **missing**
- header: **missing**
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 26 total — 0 defer, 16 async, 1 render-blocking. Speculation rules: no.

External scripts (first 15):
- https://static.hotjar.com/c/hotjar-3296638.js?sv=7 (async)
- https://www.google-analytics.com/analytics.js (async)
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 (async)
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 (async)
- https://eu-assets.i.posthog.com/static/array.js (async)
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (async)
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 (async)
- https://connect.facebook.net/en_US/fbevents.js (async)
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (async)
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (async)
- https://eu-assets.i.posthog.com/static/web-vitals.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/dead-clicks-autocapture.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/array/phc_9AAcqE521KLngxSgpVorPQDkU4ENZA9RJXVJnkr12nN/config.js (async)

**Stylesheets:** 1 external, 2 inline (1.2 KB)

**Images:** 3 total — **1 without alt**, **3 without width/height**, 1 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| lity(90)/https://larsen.ee/production/media/2024/07/karl.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/client/Co-Liv.e0807b70.png | _(no attr)_ | _n/a_ | _n/a_ | ✗ |

**Links:** 46 anchors — 22 external, 1 preconnect, 0 preload.

Vague repeated link text:
- "support@larsen.ee" ×6
- "hello@larsen.ee" ×4
- "report an issue" ×2

### Priority fixes
1. **Document has 0 <h1> elements** (high) — A page should have exactly one h1; multiple h1s break document outline
2. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
3. **1 images without alt attribute** (high) — Content images need descriptive alt text; decorative images need empty alt=""
4. **3 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 0 ms._

**Summary:** 2 pass · 0 warn · 4 fail · 1 n/a

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ✓ pass | All non-hero raster images use loading="lazy" except one. |
| Hero image eagerly loaded | ✗ fail | 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". |
| Hero is a real <img> (not a CSS background-image) | – n/a | No CSS background-images detected on raster-image-eligible elements. |
| Responsive images (srcset / <picture>) | ✗ fail | 3/3 raster images lack srcset and are not inside <picture>. |
| Reasonable number of image sizes | ✗ fail | No raster images use srcset; browsers cannot pick an optimally sized variant. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Images lazy-loaded:
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`
- Hero image eagerly loaded:
  - `hero: …256x0/filters:quality(90)/https://larsen.ee/production/media/2024/07/karl.png`
  - `loading: lazy`
  - `fetchpriority: (not set)`
- Responsive images (srcset / <picture>):
  - `…256x0/filters:quality(90)/https://larsen.ee/production/media/2024/07/karl.png`
  - `…ters:quality(90)/https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png`
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`

### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Hero image eagerly loaded** (high) — 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".
3. **Responsive images (srcset / <picture>)** (high) — 3/3 raster images lack srcset and are not inside <picture>.
4. **Reasonable number of image sizes** (high) — No raster images use srcset; browsers cannot pick an optimally sized variant.

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).

---

# Page 4 of 5 — https://larsen.ee/terms-of-service

Run: 2026-06-10T08:05:15.647Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — anchor href contains "review"
- E-commerce: no

## PageSpeed Insights
_Captured in 24663 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | 60 | **57** |
| Accessibility | 84 | 84 |
| Best Practices | 100 | 100 |
| SEO | 82 | 82 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **4.2 s** / 3555 ms p75 (average) | 2.8 s / 2726 ms p75 (average) |
| CLS | 0.001 / 6 p75 (fast) | **0.063** / 43 p75 (slow) |
| TBT | **756 ms** | 734 ms |
| FCP | **3.16 s** / 3280 ms p75 (slow) | 804 ms / 2197 ms p75 (average) |
| Speed Index | **4.42 s** | 804 ms |
| TTFB | 7 ms / 2621 ms p75 (slow) | **28 ms** / 1414 ms p75 (average) |
| INP (field only) | 390 ms p75 (average) | 245 ms p75 (average) |

### Priority fixes
1. **total-blocking-time** (high) — 760 ms
2. **largest-contentful-paint** (high) — 4.2 s
3. **first-contentful-paint** (high) — 3.2 s
4. **speed-index** (medium) — 4.4 s
5. **cache-insight** (high) — Est savings of 490 KiB

### Findings (mobile)

#### Unused JavaScript
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 1398 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 69 KB wasted
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 68 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 66 KB wasted
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 62 KB wasted
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 38 KB wasted
- https://connect.facebook.net/en_US/fbevents.js — 34 KB wasted
- https://eu-assets.i.posthog.com/static/array.js — 32 KB wasted
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 — 25 KB wasted
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 21 KB wasted
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 21 KB wasted

#### Layout-shift sources
- body > div#react-app > div.cookies — shift 0.001

#### Long tasks
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 275 ms
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 — 211 ms
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 — 171 ms
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 168 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 130 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 104 ms
- https://connect.facebook.net/en_US/fbevents.js — 95 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 92 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 89 ms
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 82 ms

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `metaDescription`
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`

#### All failing PSI audits (sorted by weight × failure margin)
- `total-blocking-time` (performance, score 0.39, weight 30) — Total Blocking Time — 760 ms
- `largest-contentful-paint` (performance, score 0.44, weight 25) — Largest Contentful Paint — 4.2 s
- `image-alt` (accessibility, score 0.00, weight 10) — Image elements do not have `[alt]` attributes
- `html-has-lang` (accessibility, score 0.00, weight 7) — `<html>` element does not have a `[lang]` attribute
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `first-contentful-paint` (performance, score 0.44, weight 10) — First Contentful Paint — 3.2 s
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `speed-index` (performance, score 0.74, weight 10) — Speed Index — 4.4 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `valid-source-maps` (best-practices, score 0.00, weight 0) — Missing source maps for large first-party JavaScript
- `meta-description` (seo, score 0.00, weight 1) — Document does not have a meta description
- `image-alt` (seo, score 0.00, weight 1) — Image elements do not have `[alt]` attributes
- `interactive` (performance, score 0.03, weight 0) — Time to Interactive — 19.1 s
- `max-potential-fid` (performance, score 0.42, weight 0) — Max Potential First Input Delay — 280 ms

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 234 ms._

**Transport:**
- Final URL: https://larsen.ee/terms-of-service
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: not set
- etag: W/"23d47-6Ovy9AyiVLMXDM3ElvItPKAPeyE"
- last-modified: n/a
- expires: n/a
- pragma: n/a
- vary: Accept-Encoding
- Issues:
  - no cache-control header — caching behavior is unpredictable

**Compression:**
- content-encoding: gzip
- content-length: n/a
- Decoded body: 143.3 KB

### Priority fixes
1. **strict-transport-security weak** (high) — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
2. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
5. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
6. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
7. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
8. **server header discloses technology** (low) — Server: Google Frontend

### Findings

#### Tracked headers
- **strict-transport-security** (weak, high) `max-age=15552000` — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
- **content-security-policy** (weak, high) `frame-ancestors https://hub.larsen.ee` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (missing, medium)
- **x-content-type-options** (present, medium) `nosniff`
- **referrer-policy** (present, low) `no-referrer`
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (present, low) `none`

#### Info disclosure
- Server: `Google Frontend`


#### All response headers
```
alt-svc: h3=":443"; ma=2592000
content-encoding: gzip
content-security-policy: frame-ancestors https://hub.larsen.ee
content-type: text/html; charset=utf-8
date: Wed, 10 Jun 2026 08:05:15 GMT
etag: W/"23d47-6Ovy9AyiVLMXDM3ElvItPKAPeyE"
expect-ct: max-age=0
referrer-policy: no-referrer
server: Google Frontend
strict-transport-security: max-age=15552000
transfer-encoding: chunked
vary: Accept-Encoding
via: 1.1 google
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-xss-protection: 0
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 473 ms._

**Scoring:** 5 errors · 3 warnings · 12 cosmetic (suppressed)

### Priority fixes
1. **An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.** (medium) — x2, first at line 63
2. **CSS: “color”: Parse Error.** (medium) — x2, first at line 66
3. **The element “button” must not appear as a descendant of the “a” element.** (medium) — x1, first at line 66

### Issue groups
- (×2) [error] An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images. — first at line 63 `pt>
      <img height="1" width="1" style="display:none"
        src="https://ww`
- (×1) [error] The element “button” must not appear as a descendant of the “a” element. — first at line 66 `"/search"><button class="button button--main desktop-header__yellow-button deskt`
- (×2) [error] CSS: “color”: Parse Error. — first at line 66 `p><ul><li><span style="background-color: rgba(255,255,255,var(--tw-bg-opacity));`
- (×1) [warning] Empty heading. — first at line 66 `s="topic"><h3 id="-" class="topic-title h3"> </h3>`
- (×1) [warning] This document appears to be written in English. Consider adding “lang="en"” (or variant) to the “html” start tag. — first at line 2 `type html>
<html >
  <he`
- (×1) [warning] This document has heading elements but none of them has a computed heading level of 1. — first at line 66 `s="topic"><h3 id="-1.-acceptance-of-terms" class="topic-title h3"> 1. Ac`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 2765 ms._

**Scoring:** 7 violations · 29 passes · critical 1 · serious 2 · moderate 3 · minor 1

### Priority fixes
1. **image-alt** (high) — Images must have alternative text
2. **html-has-lang** (high) — <html> element must have a lang attribute
3. **link-name** (high) — Links must have discernible text
4. **landmark-one-main** (medium) — Document should have one main landmark
5. **page-has-heading-one** (medium) — Page should contain a level-one heading

### Findings

#### `empty-heading` (minor)
[Headings should not be empty](https://dequeuniversity.com/rules/axe/4.11/empty-heading?application=playwright)
- `#\-`

#### `html-has-lang` (serious) — WCAG: wcag2a, wcag311
[<html> element must have a lang attribute](https://dequeuniversity.com/rules/axe/4.11/html-has-lang?application=playwright)
- `html`

#### `image-alt` (critical) — WCAG: wcag2a, wcag111
[Images must have alternative text](https://dequeuniversity.com/rules/axe/4.11/image-alt?application=playwright)
- `img[src$="Co-Liv.e0807b70.png"]`

#### `landmark-one-main` (moderate)
[Document should have one main landmark](https://dequeuniversity.com/rules/axe/4.11/landmark-one-main?application=playwright)
- `html`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `a[aria-current="page"]`
- `.footer__icon--facebook`
- `.footer__icon--instagram`

#### `page-has-heading-one` (moderate)
[Page should contain a level-one heading](https://dequeuniversity.com/rules/axe/4.11/page-has-heading-one?application=playwright)
- `html`

#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.language-switcher.active[href$="kasutustingimused"]`
- `.language-switcher.fill-black[href$="kasutustingimused"]:nth-child(2)`
- `.page`
- `.cookies__content`

### Incomplete (axe could not determine)
- [ARIA attributes must conform to valid values](https://dequeuniversity.com/rules/axe/4.11/aria-valid-attr-value?application=playwright) — 1 node
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 14 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 2771 ms._

**Capture summary:** 1 console events · 0 mixed-content requests · 37 network requests · 1.27 MB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| script | 17 | 843.4 KB |
| image | 5 | 323.5 KB |
| font | 3 | 91.3 KB |
| stylesheet | 2 | 40.8 KB |
| xhr | 2 | 15 B |
| document | 1 | 0 B |
| fetch | 5 | 0 B |
| ping | 2 | 0 B |

**Third-party origins (by bytes):**
- https://www.googletagmanager.com — 4 requests, 648.0 KB
- https://connect.facebook.net — 3 requests, 175.1 KB
- https://thumbor.larsen.ee — 2 requests, 56.5 KB
- https://fonts.gstatic.com — 1 request, 43.8 KB
- https://www.google-analytics.com — 2 requests, 20.3 KB
- https://www.google.ee — 2 requests, 84 B
- https://fonts.googleapis.com — 2 requests, 0 B
- https://eu-assets.i.posthog.com — 6 requests, 0 B
- https://region1.analytics.google.com — 2 requests, 0 B
- https://stats.g.doubleclick.net — 2 requests, 0 B
- https://static.hotjar.com — 1 request, 0 B
- https://pagead2.googlesyndication.com — 2 requests, 0 B

**Slowest requests (top 5):**
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (script) — 368 ms, 177.7 KB
- https://connect.facebook.net/en_US/fbevents.js (script) — 367 ms, 97.5 KB
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (script) — 367 ms, 159.2 KB
- https://www.chatbase.co/api/get-chatbot-styles/y7CotFfAzSHKzmcew7JaK (fetch) — 325 ms, 0 B
- https://larsen.ee/terms-of-service (document) — 258 ms, 0 B

### Priority fixes
1. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078715941&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=757772502.1781078716&frm=0&ir=1&pscdl=noapi&rcb=18&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938468&sid=1781078716&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&dt=Larsen&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=770 — net::ERR_ABORTED
2. **failed request** (medium) — fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=14&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&scrsrc=www.googletagmanager.com&rnd=882540049.1781078717&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641h1v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938468&apve=1&apvf=f&apvc=1&tft=1781078716565&tfd=888 — net::ERR_ABORTED
3. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641h1v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078715941&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=757772502.1781078716&frm=0&pscdl=noapi&rcb=2&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938465~115938469~119061279&sid=1781078716&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&dt=Larsen&en=page_view&_fv=1&_ss=1&tfd=1063 — net::ERR_ABORTED

### Findings

#### Failed requests
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6641v9128456099za200zd9128456099&_p=1781078715941&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=757772502.1781078716&frm=0&ir=1&pscdl=noapi&rcb=18&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938468&sid=1781078716&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&dt=Larsen&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=770 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=14&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&scrsrc=www.googletagmanager.com&rnd=882540049.1781078717&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641h1v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938468&apve=1&apvf=f&apvc=1&tft=1781078716565&tfd=888 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641h1v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078715941&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=757772502.1781078716&frm=0&pscdl=noapi&rcb=2&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938465~115938469~119061279&sid=1781078716&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&dt=Larsen&en=page_view&_fv=1&_ss=1&tfd=1063 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=9&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fterms-of-service&scrsrc=www.googletagmanager.com&rnd=882540049.1781078717&navt=n&npa=1&gtm=45be6641h1v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115616986~115938465~115938469~117776794&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078716783&tfd=1106 — net::ERR_ABORTED

#### Console events
- [warning] Hotjar not launching due to suspicious userAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.7778.96 Safari/537.36 (https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0)

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 2771 ms._

**Document:**
- Lang: not set
- Title: Larsen
- Canonical: not set
- Viewport: width=device-width
- Charset: UTF-8
- HTML bytes: 158881

**Meta tags:**
- Description: not set
- Robots: not set
- Theme color: #ffffff
- Open Graph tags: 1 (og:title)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×0, h2 ×14, h3 ×15, h4 ×1, h5 ×0, h6 ×0
- Sequence (first 20):
  - h3: 1. Acceptance of Terms
  - h3: 2. Changes to Terms
  - h3: 3. Use of the Website
  - h3: 4. Intellectual Property
  - h3: 5. User-Generated Content
  - h3: 6. Booking and Payments
  - h3: 7. Privacy
  - h3: 8. Limitation of Liability
  - h3: 9. Indemnification
  - h3: 10. Termination
  - h3: 11. Governing Law
  - h3: 12. Contact Information
  - h3: 
  - h2: Navigate
  - h2: Home
  - h2: Rooms
  - h2: Locations
  - h2: Features
  - h2: Testimonials
  - h2: About & Contact

**Landmarks:**
- nav: present
- main: **missing**
- header: **missing**
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 26 total — 0 defer, 16 async, 1 render-blocking. Speculation rules: no.

External scripts (first 15):
- https://static.hotjar.com/c/hotjar-3296638.js?sv=7 (async)
- https://www.google-analytics.com/analytics.js (async)
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641h1 (async)
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641h1 (async)
- https://eu-assets.i.posthog.com/static/array.js (async)
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (async)
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 (async)
- https://connect.facebook.net/en_US/fbevents.js (async)
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (async)
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (async)
- https://eu-assets.i.posthog.com/static/web-vitals.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/dead-clicks-autocapture.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/array/phc_9AAcqE521KLngxSgpVorPQDkU4ENZA9RJXVJnkr12nN/config.js (async)

**Stylesheets:** 1 external, 2 inline (1.2 KB)

**Images:** 3 total — **1 without alt**, **3 without width/height**, 1 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| lity(90)/https://larsen.ee/production/media/2024/07/karl.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png | _(empty)_ | _n/a_ | lazy | ✗ |
| https://larsen.ee/client/Co-Liv.e0807b70.png | _(no attr)_ | _n/a_ | _n/a_ | ✗ |

**Links:** 20 anchors — 3 external, 1 preconnect, 0 preload.

### Priority fixes
1. **Document has 0 <h1> elements** (high) — A page should have exactly one h1; multiple h1s break document outline
2. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
3. **1 images without alt attribute** (high) — Content images need descriptive alt text; decorative images need empty alt=""
4. **3 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 1 ms._

**Summary:** 2 pass · 0 warn · 4 fail · 1 n/a

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ✓ pass | All non-hero raster images use loading="lazy" except one. |
| Hero image eagerly loaded | ✗ fail | 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". |
| Hero is a real <img> (not a CSS background-image) | – n/a | No CSS background-images detected on raster-image-eligible elements. |
| Responsive images (srcset / <picture>) | ✗ fail | 3/3 raster images lack srcset and are not inside <picture>. |
| Reasonable number of image sizes | ✗ fail | No raster images use srcset; browsers cannot pick an optimally sized variant. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Images lazy-loaded:
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`
- Hero image eagerly loaded:
  - `hero: …256x0/filters:quality(90)/https://larsen.ee/production/media/2024/07/karl.png`
  - `loading: lazy`
  - `fetchpriority: (not set)`
- Responsive images (srcset / <picture>):
  - `…256x0/filters:quality(90)/https://larsen.ee/production/media/2024/07/karl.png`
  - `…ters:quality(90)/https://larsen.ee/production/media/2022/03/ehrl-blue-eng.png`
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`

### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Hero image eagerly loaded** (high) — 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".
3. **Responsive images (srcset / <picture>)** (high) — 3/3 raster images lack srcset and are not inside <picture>.
4. **Reasonable number of image sizes** (high) — No raster images use srcset; browsers cannot pick an optimally sized variant.

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).

---

# Page 5 of 5 — https://larsen.ee/et

Run: 2026-06-10T08:05:33.935Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — anchor href contains "review"
- E-commerce: no

## PageSpeed Insights
_Captured in 23029 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **43** | 55 |
| Accessibility | 74 | 74 |
| Best Practices | 96 | 96 |
| SEO | 91 | 91 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **18.9 s** / 3555 ms p75 (average) | 4.7 s / 2726 ms p75 (average) |
| CLS | **0.001** / 6 p75 (fast) | 0.001 / 43 p75 (slow) |
| TBT | **541 ms** | 372 ms |
| FCP | **4.27 s** / 3280 ms p75 (slow) | 850 ms / 2197 ms p75 (average) |
| Speed Index | **13.66 s** | 2.39 s |
| TTFB | 17 ms / 2621 ms p75 (slow) | **68 ms** / 1414 ms p75 (average) |
| INP (field only) | 390 ms p75 (average) | 245 ms p75 (average) |

### Priority fixes
1. **largest-contentful-paint** (high) — 18.9 s
2. **total-blocking-time** (medium) — 540 ms
3. **speed-index** (high) — 13.7 s
4. **first-contentful-paint** (high) — 4.3 s
5. **cache-insight** (high) — Est savings of 2,450 KiB

### Findings (mobile)

#### Unused JavaScript
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 1370 KB wasted
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 67 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 67 KB wasted
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6690h2 — 64 KB wasted
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6690h2 — 63 KB wasted
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 38 KB wasted
- https://connect.facebook.net/en_US/fbevents.js — 34 KB wasted
- https://eu-assets.i.posthog.com/static/array.js — 32 KB wasted
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 — 25 KB wasted
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 21 KB wasted
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 — 21 KB wasted

#### Layout-shift sources
- div.calendar-container — shift 0.001

#### Long tasks
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 348 ms
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6690h2 — 154 ms
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js — 136 ms
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6690h2 — 121 ms
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 — 104 ms
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ — 100 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 81 ms
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM — 67 ms
- https://script.hotjar.com/modules.c3d712579ef0b1b5af2a.js — 66 ms
- https://connect.facebook.net/en_US/fbevents.js — 64 ms

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `canonical`
- SEO: `robotsTxt`
- SEO: `tapTargets`
- SEO: `structuredData`
- Best Practices: `errorsInConsole`

#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.00, weight 25) — Largest Contentful Paint — 18.9 s
- `total-blocking-time` (performance, score 0.54, weight 30) — Total Blocking Time — 540 ms
- `button-name` (accessibility, score 0.00, weight 10) — Buttons do not have an accessible name
- `image-alt` (accessibility, score 0.00, weight 10) — Image elements do not have `[alt]` attributes
- `speed-index` (performance, score 0.02, weight 10) — Speed Index — 13.7 s
- `first-contentful-paint` (performance, score 0.18, weight 10) — First Contentful Paint — 4.3 s
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `html-has-lang` (accessibility, score 0.00, weight 7) — `<html>` element does not have a `[lang]` attribute
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `heading-order` (accessibility, score 0.00, weight 3) — Heading elements are not in a sequentially-descending order
- `lcp-discovery-insight` (performance, score 0.00, weight 0) — LCP request discovery
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `interactive` (performance, score 0.00, weight 0) — Time to Interactive — 40.3 s
- `errors-in-console` (best-practices, score 0.00, weight 1) — Browser errors were logged to the console
- `valid-source-maps` (best-practices, score 0.00, weight 0) — Missing source maps for large first-party JavaScript
- `image-alt` (seo, score 0.00, weight 1) — Image elements do not have `[alt]` attributes
- `max-potential-fid` (performance, score 0.25, weight 0) — Max Potential First Input Delay — 350 ms

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 925 ms._

**Transport:**
- Final URL: https://larsen.ee/et
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: not set
- etag: W/"cb584-pFQAvoImDLzbpWp7YyWnKwaQtVQ"
- last-modified: n/a
- expires: n/a
- pragma: n/a
- vary: Accept-Encoding
- Issues:
  - no cache-control header — caching behavior is unpredictable

**Compression:**
- content-encoding: gzip
- content-length: n/a
- Decoded body: 813.4 KB

### Priority fixes
1. **strict-transport-security weak** (high) — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
2. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **weak caching policy** (medium) — no cache-control header — caching behavior is unpredictable
5. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
6. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
7. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
8. **server header discloses technology** (low) — Server: Google Frontend

### Findings

#### Tracked headers
- **strict-transport-security** (weak, high) `max-age=15552000` — max-age too short (15552000s, recommended >= 31536000); missing includeSubDomains directive; missing preload directive
- **content-security-policy** (weak, high) `frame-ancestors https://hub.larsen.ee` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (missing, medium)
- **x-content-type-options** (present, medium) `nosniff`
- **referrer-policy** (present, low) `no-referrer`
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (present, low) `none`

#### Info disclosure
- Server: `Google Frontend`


#### All response headers
```
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
content-encoding: gzip
content-security-policy: frame-ancestors https://hub.larsen.ee
content-type: text/html; charset=utf-8
date: Wed, 10 Jun 2026 08:05:34 GMT
etag: W/"cb584-pFQAvoImDLzbpWp7YyWnKwaQtVQ"
expect-ct: max-age=0
referrer-policy: no-referrer
server: Google Frontend
strict-transport-security: max-age=15552000
transfer-encoding: chunked
vary: Accept-Encoding
via: 1.1 google
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-xss-protection: 0
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 1444 ms._

**Scoring:** 11 errors · 1 warnings · 18 cosmetic (suppressed)

### Priority fixes
1. **The element “button” must not appear as a descendant of the “a” element.** (high) — x5, first at line 66
2. **An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.** (medium) — x2, first at line 63
3. **The value of the “for” attribute of the “label” element must be the ID of a non-hidden form control.** (medium) — x2, first at line 66
4. **The heading “h4” (with computed level 4) follows the heading “h2” (with computed level 2), skipping 1 heading level.** (medium) — x2, first at line 66

### Issue groups
- (×2) [error] An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images. — first at line 63 `pt>
      <img height="1" width="1" style="display:none"
        src="https://ww`
- (×5) [error] The element “button” must not appear as a descendant of the “a” element. — first at line 66 `"/otsing"><button class="button button--main desktop-header__yellow-button deskt`
- (×2) [error] The value of the “for” attribute of the “label” element must be the ID of a non-hidden form control. — first at line 66 `xt-area "><label for="room-type-1">Mõni p`
- (×1) [warning] This document appears to be written in Estonian. Consider adding “lang="et"” (or variant) to the “html” start tag. — first at line 2 `type html>
<html >
  <he`
- (×2) [error] The heading “h4” (with computed level 4) follows the heading “h2” (with computed level 2), skipping 1 heading level. — first at line 66 `ates</div><h4 class="apartment-type-slider__price-price">559<!-`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 4721 ms._

**Scoring:** 7 violations · 36 passes · critical 2 · serious 3 · moderate 2 · minor 0

### Priority fixes
1. **button-name** (high) — Buttons must have discernible text
2. **image-alt** (high) — Images must have alternative text
3. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
4. **html-has-lang** (high) — <html> element must have a lang attribute
5. **link-name** (high) — Links must have discernible text

### Findings

#### `button-name` (critical) — WCAG: wcag2a, wcag412
[Buttons must have discernible text](https://dequeuniversity.com/rules/axe/4.11/button-name?application=playwright)
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .active.slider__dot`
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(2)`
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(3)`
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(4)`
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .slider > .slider__dots > .slider__dot:nth-child(5)`
- … and 15 more nodes

#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `.search-container__stay-type-input-wrapper > .search-container__value`
- `.react-datepicker-wrapper:nth-child(4) > .react-datepicker__input-container > .search-container__date-picker-input-container > .search-container__date-picker-input-wrapper > .search-container__value`
- `.react-datepicker-wrapper:nth-child(5) > .react-datepicker__input-container > .search-container__date-picker-input-container > .search-container__date-picker-input-wrapper > .search-container__value`
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-from`
- `.apartment-type-box:nth-child(2) > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-from`
- … and 4 more nodes

#### `heading-order` (moderate)
[Heading levels should only increase by one](https://dequeuniversity.com/rules/axe/4.11/heading-order?application=playwright)
- `a[href$="sume-loft-roduga-452"] > .apartment-type-slider.apartment-type-box__slider-box > .apartment-type-slider__prices > .apartment-type-slider__price > .apartment-type-slider__price-price`
- `.other-features-container__feature:nth-child(1) > .other-features-container__title > h4`

#### `html-has-lang` (serious) — WCAG: wcag2a, wcag311
[<html> element must have a lang attribute](https://dequeuniversity.com/rules/axe/4.11/html-has-lang?application=playwright)
- `html`

#### `image-alt` (critical) — WCAG: wcag2a, wcag111
[Images must have alternative text](https://dequeuniversity.com/rules/axe/4.11/image-alt?application=playwright)
- `img[src$="Co-Liv.e0807b70.png"]`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.larsen-logo-wrapper > .active[aria-current="page"][href="/et"]`
- `.footer__icon--facebook`
- `.footer__icon--instagram`

#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.language-switcher.fill-white[href="/"]:nth-child(1)`
- `.language-switcher.fill-white[href="/"]:nth-child(2)`
- `.cookies__content`

### Incomplete (axe could not determine)
- [ARIA attributes must conform to valid values](https://dequeuniversity.com/rules/axe/4.11/aria-valid-attr-value?application=playwright) — 1 node
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 16 nodes
- [<video> elements must have captions](https://dequeuniversity.com/rules/axe/4.11/video-caption?application=playwright) — 2 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 4741 ms._

**Capture summary:** 1 console events · 0 mixed-content requests · 56 network requests · 69.19 MB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| media | 4 | 55.96 MB |
| image | 21 | 12.30 MB |
| script | 17 | 844.5 KB |
| font | 2 | 67.8 KB |
| stylesheet | 2 | 40.8 KB |
| xhr | 2 | 15 B |
| document | 1 | 0 B |
| fetch | 5 | 0 B |
| ping | 2 | 0 B |

**Third-party origins (by bytes):**
- https://thumbor.larsen.ee — 5 requests, 4.66 MB
- https://www.googletagmanager.com — 4 requests, 649.1 KB
- https://connect.facebook.net — 3 requests, 175.1 KB
- https://fonts.gstatic.com — 1 request, 43.8 KB
- https://www.google-analytics.com — 2 requests, 20.3 KB
- https://www.google.ee — 2 requests, 84 B
- https://fonts.googleapis.com — 2 requests, 0 B
- https://eu-assets.i.posthog.com — 6 requests, 0 B
- https://region1.analytics.google.com — 2 requests, 0 B
- https://static.hotjar.com — 1 request, 0 B
- https://stats.g.doubleclick.net — 2 requests, 0 B
- https://pagead2.googlesyndication.com — 2 requests, 0 B

**Slowest requests (top 5):**
- https://larsen.ee/et (document) — 862 ms, 0 B
- https://larsen.ee/client/app-889782a39d4314ef1bf6.js (script) — 586 ms, 0 B
- https://stats.g.doubleclick.net/g/collect?v=2&tid=G-9DLXLVKRKQ&cid=1877777640.1781078735&gtm=45je6690h2v9128456099za200zd9128456099&rcb=1&aip=1&dma=1&dma_cps=-&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&frm=0&tag_exp=0~115616986~115938465~115938469 (ping) — 370 ms, 0 B
- https://fonts.gstatic.com/s/intertight/v9/NGSwv5HMAFg6IuGlBNMjxLsH8ag.woff2 (font) — 368 ms, 43.8 KB
- https://larsen.ee/production/media/2023/video-files/Larsen%20-%20Kokkuvo%CC%83te%20est%20bars.mp4 (media) — 367 ms, 43.88 MB

### Priority fixes
1. **failed request** (medium) — media: https://larsen.ee/videos/uus-logota-larsen-video-2.mp4 — net::ERR_ABORTED
2. **failed request** (medium) — media: https://larsen.ee/production/media/2023/video-files/Larsen%20-%20Kokkuvo%CC%83te%20est%20bars.mp4 — net::ERR_ABORTED
3. **failed request** (medium) — fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6690h2v9128456099za200zd9128456099&_p=1781078734833&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=1877777640.1781078735&frm=0&ir=1&pscdl=noapi&rcb=1&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938469&sid=1781078735&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fet&dt=Larsen%20-%20Tallinna%20vingeim%20majutus&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1506 — net::ERR_ABORTED

### Findings

#### Failed requests
- media: https://larsen.ee/videos/uus-logota-larsen-video-2.mp4 — net::ERR_ABORTED
- media: https://larsen.ee/production/media/2023/video-files/Larsen%20-%20Kokkuvo%CC%83te%20est%20bars.mp4 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-9DLXLVKRKQ&gtm=45je6690h2v9128456099za200zd9128456099&_p=1781078734833&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=EAAAAGAC&are=1&cid=1877777640.1781078735&frm=0&ir=1&pscdl=noapi&rcb=1&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115616986~115938465~115938469&sid=1781078735&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fet&dt=Larsen%20-%20Tallinna%20vingeim%20majutus&en=page_view&_fv=1&_nsi=1&_ss=1&_ee=1&tfd=1506 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=6&frm=0&ae=g&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fet&scrsrc=www.googletagmanager.com&rnd=1050470011.1781078736&navt=n&npa=1&ep.ads_data_redaction=0&gtm=45He6641v847628427za200zd847628427xea&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115938465~115938469&apve=1&apvf=f&apvc=1&tft=1781078735647&tfd=1682 — net::ERR_ABORTED
- fetch: https://pagead2.googlesyndication.com/ccm/collect?rcb=8&frm=0&en=page_view&dl=https%3A%2F%2Flarsen.ee%2Fet&scrsrc=www.googletagmanager.com&rnd=1050470011.1781078736&navt=n&npa=1&gtm=45be6641v9218844185z8847628427za20gzb847628427zd847628427xec&gcs=G1--&gcd=13l3l3p2p5l1&dma_cps=-&dma=1&tag_exp=0~115938465~115938468&apve=1&apvf=f&apvc=0&tids=AW-17042172798&tid=AW-17042172798&tft=1781078736284&tfd=2320 — net::ERR_ABORTED
- fetch: https://region1.analytics.google.com/g/collect?v=2&tid=G-L1DE8WRGT9&gtm=45je6641v9119440986z8847628427za20gzb847628427zd847628427&_p=1781078734833&_gaz=1&gcs=G1--&gcd=13l3l3p2p5l1&npa=1&dma_cps=-&dma=1&_eu=AAAAAGAC&are=1&cid=1877777640.1781078735&frm=0&pscdl=noapi&rcb=15&sr=1280x720&uaa=x86&uab=64&uafvl=Chromium%3B148.0.7778.96%7CHeadlessChrome%3B148.0.7778.96%7CNot%252FA)Brand%3B99.0.0.0&uam=&uamb=0&uap=Linux&uapv=&uaw=0&ul=en-us&gaf=2&_s=1&tag_exp=0~115938465~115938468&sid=1781078736&sct=1&seg=0&dl=https%3A%2F%2Flarsen.ee%2Fet&dt=Larsen%20-%20Tallinna%20vingeim%20majutus&en=page_view&_fv=1&_ss=1&tfd=2371 — net::ERR_ABORTED

#### Console events
- [warning] Hotjar not launching due to suspicious userAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.7778.96 Safari/537.36 (https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0)

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 4740 ms._

**Document:**
- Lang: not set
- Title: Larsen - Tallinna vingeim majutus
- Canonical: not set
- Viewport: width=device-width
- Charset: UTF-8
- HTML bytes: 848981

**Meta tags:**
- Description: Täismöbleeritud majutusruumid lühemaks või pikemaks ajaks - 1. Vali majutusruum välja. 2. Broneeri netist. 3. Tee kontaktivaba check-in.
- Robots: not set
- Theme color: #ffffff
- Open Graph tags: 3 (og:title, og:description, og:image)
- Twitter tags: 0
- hreflang: none
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×1, h2 ×21, h3 ×6, h4 ×14, h5 ×0, h6 ×0
- Sequence (first 20):
  - h1: Broneeri oma peatuspaik Tallinnas hetkega
  - h2: Kõik on siin oodatud – ilma bürokraatia ja liigse jamata.
  - h4: 559 €
  - h3: Sume Loft - rõduga
  - h4: 489 €
  - h3: Sume Twin Studio - rõduga
  - h4: 459 €
  - h3: Sume Studio - rõduga
  - h4: 54 €
  - h4: 419 €
  - h3: Eduard House Studio L
  - h2: Otsid midagi teistsugust?
  - h2: Eduard House
  - h2: Kohene lihtne broneerimine
  - h2: Saa osa Larseni kogukonnast
  - h2: Miks valida Larsen?
  - h4: Paindlik lepingu pikkus
  - h4: Sõlmi leping otse veebist
  - h4: Täismöbleeritud
  - h4: Ühisalad
- Skips:
  - h2 → h4 after "Kõik on siin oodatud – ilma bürokraatia ja liigse jamata."
  - h2 → h4 after "Miks valida Larsen?"

**Landmarks:**
- nav: present
- main: present
- header: **missing**
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 26 total — 0 defer, 16 async, 1 render-blocking. Speculation rules: no.

External scripts (first 15):
- https://static.hotjar.com/c/hotjar-3296638.js?sv=7 (async)
- https://www.google-analytics.com/analytics.js (async)
- https://www.googletagmanager.com/gtag/js?id=AW-17042172798&cx=c&gtm=4e6641 (async)
- https://www.googletagmanager.com/gtag/js?id=G-L1DE8WRGT9&cx=c&gtm=4e6641 (async)
- https://eu-assets.i.posthog.com/static/array.js (async)
- https://connect.facebook.net/signals/config/1726152210919905?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171%2C231%2C230%2C225%2C227%2C228%2C229%2C226%2C214%2C224%2C196%2C193%2C194%2C188%2C192%2C195%2C191%2C186%2C322%2C199%2C189%2C190%2C218%2C187%2C185%2C238%2C209%2C179%2C180%2C175%2C181%2C178%2C176%2C177%2C174%2C172%2C183%2C184%2C182%2C269%2C321%2C291%2C289%2C290%2C288%2C197%2C241%2C247%2C242%2C244%2C246%2C245%2C243%2C240%2C256%2C251%2C253%2C250%2C257%2C254%2C249%2C255%2C252%2C248%2C284%2C295 (async)
- https://connect.facebook.net/signals/config/1122870719174136?v=2.9.334&r=stable&domain=larsen.ee&hme=d9eb83ce5750216745fae8e2064a8c1ed2255ecaf2468f800b2a146e6168b65e&ex_m=105%2C208%2C156%2C22%2C73%2C74%2C147%2C69%2C68%2C11%2C165%2C91%2C16%2C139%2C128%2C39%2C76%2C79%2C135%2C161%2C167%2C8%2C4%2C5%2C7%2C6%2C3%2C92%2C102%2C168%2C173%2C222%2C30%2C75%2C234%2C233%2C232%2C23%2C33%2C55%2C104%2C61%2C10%2C64%2C98%2C99%2C100%2C106%2C131%2C31%2C29%2C133%2C134%2C130%2C129%2C157%2C77%2C160%2C158%2C159%2C50%2C60%2C124%2C15%2C164%2C45%2C267%2C268%2C266%2C26%2C27%2C28%2C48%2C148%2C78%2C113%2C18%2C20%2C44%2C40%2C42%2C41%2C84%2C93%2C97%2C111%2C146%2C149%2C46%2C112%2C24%2C21%2C120%2C70%2C36%2C151%2C150%2C152%2C143%2C141%2C25%2C35%2C59%2C110%2C163%2C71%2C17%2C154%2C115%2C82%2C67%2C19%2C86%2C87%2C117%2C85%2C137%2C136%2C140%2C162%2C34%2C282%2C298%2C215%2C204%2C62%2C205%2C203%2C301%2C292%2C52%2C216%2C108%2C132%2C81%2C122%2C54%2C47%2C49%2C114%2C121%2C127%2C126%2C58%2C65%2C63%2C153%2C116%2C37%2C32%2C53%2C56%2C101%2C166%2C1%2C125%2C14%2C123%2C12%2C2%2C57%2C94%2C66%2C119%2C90%2C89%2C169%2C170%2C95%2C96%2C9%2C103%2C51%2C144%2C88%2C80%2C72%2C118%2C107%2C43%2C145%2C0%2C83%2C138%2C142%2C155%2C38%2C109%2C13%2C171 (async)
- https://connect.facebook.net/en_US/fbevents.js (async)
- https://www.googletagmanager.com/gtm.js?id=GTM-KWS6MWM (async)
- https://www.googletagmanager.com/gtag/js?id=G-9DLXLVKRKQ (async)
- https://eu-assets.i.posthog.com/static/web-vitals.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/dead-clicks-autocapture.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/surveys.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/static/posthog-recorder.js?v=1.384.0 (async)
- https://eu-assets.i.posthog.com/array/phc_9AAcqE521KLngxSgpVorPQDkU4ENZA9RJXVJnkr12nN/config.js (async)

**Stylesheets:** 1 external, 2 inline (1.2 KB)

**Images:** 16 total — **1 without alt**, **16 without width/height**, 4 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| s://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg | thumbnail of the video | _n/a_ | _n/a_ | ✗ |
| ttps://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| s://larsen.ee/production/media/2025/03/rocca-house-drone.png | _(empty)_ | _n/a_ | lazy | ✗ |
| 0)/https://larsen.ee/production/media/2021/12/img-1042-1.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /larsen.ee/production/media/2024/09/dji-0044-enhanced-nr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| (90)/https://larsen.ee/production/media/2025/11/ttun8888.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/11/ttun8720-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/09/ttun8103-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| /https://larsen.ee/production/media/2025/09/ttun8394-hdr.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| (90)/https://larsen.ee/production/media/2024/04/-tun4221.jpg | _(empty)_ | _n/a_ | lazy | ✗ |
| ttps://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg | Building image | _n/a_ | lazy | ✗ |
| https://larsen.ee/images/rectangle/Rectangle-158.png | imageOne | _n/a_ | _n/a_ | ✗ |
| https://larsen.ee/images/rectangle/Rectangle-159.png | imageOne | _n/a_ | _n/a_ | ✗ |
| lity(90)/https://larsen.ee/production/media/2024/07/karl.png | _(empty)_ | _n/a_ | lazy | ✗ |
| oduction/media/2022/03/ehrl-liikmem2rgis-sinine-est-002-.png | _(empty)_ | _n/a_ | lazy | ✗ |

**Links:** 36 anchors — 3 external, 1 preconnect, 0 preload.

Vague repeated link text:
- "kasutustingimused" ×2

### Priority fixes
1. **Heading level skips** (medium) — h2→h4 after "Kõik on siin oodatud – ilma bürokraatia "; h2→h4 after "Miks valida Larsen?"
2. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
3. **1 images without alt attribute** (high) — Content images need descriptive alt text; decorative images need empty alt=""
4. **16 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 0 ms._

**Summary:** 1 pass · 3 warn · 3 fail

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✗ fail | No WordPress cache plugin marker or CDN edge cache detected on the document response. |
| Images lazy-loaded | ! warn | 3 of 15 non-hero raster images are not lazy-loaded. |
| Hero image eagerly loaded | ! warn | Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP. |
| Hero is a real <img> (not a CSS background-image) | ! warn | Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file. |
| Responsive images (srcset / <picture>) | ✗ fail | 16/16 raster images lack srcset and are not inside <picture>. |
| Reasonable number of image sizes | ✗ fail | No raster images use srcset; browsers cannot pick an optimally sized variant. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Images lazy-loaded:
  - `https://larsen.ee/images/rectangle/Rectangle-158.png`
  - `https://larsen.ee/images/rectangle/Rectangle-159.png`
  - `https://larsen.ee/client/Co-Liv.e0807b70.png`
- Hero image eagerly loaded:
  - `hero: https://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg`
  - `loading: (not set)`
  - `fetchpriority: (not set)`
- Hero is a real <img> (not a CSS background-image):
  - `selector: div.buildings-map__map-overlay`
  - `url: https://larsen.ee/client/Eduard_House.e76047f2.png`
  - `box: 520×1021px`
- Responsive images (srcset / <picture>):
  - `https://larsen.ee/images/uus-logota-larsen-video-2-thumbnail.jpg`
  - `…ers:quality(90)/https://larsen.ee/production/media/2023/11/maja-fasssad-2.jpg`
  - `…:quality(90)/https://larsen.ee/production/media/2025/03/rocca-house-drone.png`
  - `…filters:quality(90)/https://larsen.ee/production/media/2021/12/img-1042-1.jpg`
  - `…ality(90)/https://larsen.ee/production/media/2024/09/dji-0044-enhanced-nr.jpg`

### Priority fixes
1. **Page caching plugin / CDN active** (high) — No WordPress cache plugin marker or CDN edge cache detected on the document response.
2. **Responsive images (srcset / <picture>)** (high) — 16/16 raster images lack srcset and are not inside <picture>.
3. **Reasonable number of image sizes** (high) — No raster images use srcset; browsers cannot pick an optimally sized variant.
4. **Images lazy-loaded** (medium) — 3 of 15 non-hero raster images are not lazy-loaded.
5. **Hero image eagerly loaded** (medium) — Hero image has no explicit loading or fetchpriority (inferred from DOM order/size — Lighthouse LCP element unavailable). Browser default is eager but adding fetchpriority="high" helps LCP.
6. **Hero is a real <img> (not a CSS background-image)** (medium) — Hero element uses a CSS background-image (no image-set() variants), so the browser always loads the original asset regardless of viewport — there is no srcset equivalent. Move the hero to a real <img> with srcset/sizes (or <picture>) so smaller viewports can fetch a smaller file.

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).