20260915T131014Z-cb17
- Audited URL
- https://play.ee/
- Timestamp
- 2026-09-15T13:17:04.561Z
- Kind
- site
- Pages
- 5
Weighted audit summary
Site overall 74 is the mean of 5 pages. Scores range 68 (https://play.ee/web-development-case-studies/) → 82 (https://play.ee/). Weakest page: Mobile performance is strong (88) with acceptable LCP (2.7 s), but the Speed Index (5.89 s) indicates render delays. Security configuration is critically weak (Grade 20/100) with HTTP not redirecting to HTTPS and missing HSTS, which heavily penalizes the SEO/Security bucket. Accessibility has a serious color-contrast violation and missing main landmark, preventing a higher score. HTML validation shows 7 errors including parser recovery failure, indicating structural issues in the head section. Confidence is high as all audit tools returned complete data.
Audit Report: Perfectly formed web development team - gotoAndPlay
Website: https://play.ee/
Date: 15.09.2026
Audit Coverage: 100% — all sources returned data
Confidence: high
Pages Audited (5 of 5):
- https://play.ee/
- https://play.ee/web-development-case-studies/
- https://play.ee/software-development-work-index/
- https://play.ee/wordpress-support-service/
- https://play.ee/web-development-in-estonia/
Summary of results
Overall Score: 74 / 100
Status: 🟡 Needs Improvement
Site overall 74 is the mean of 5 pages. Scores range 68 (https://play.ee/web-development-case-studies/) → 82 (https://play.ee/). Weakest page: Mobile performance is strong (88) with acceptable LCP (2.7 s), but the Speed Index (5.89 s) indicates render delays. Security configuration is critically weak (Grade 20/100) with HTTP not redirecting to HTTPS and missing HSTS, which heavily penalizes the SEO/Security bucket. Accessibility has a serious color-contrast violation and missing main landmark, preventing a higher score. HTML validation shows 7 errors including parser recovery failure, indicating structural issues in the head section. Confidence is high as all audit tools returned complete data.
Per-page scores
🟡 Needs Improvement · https://play.ee/
| Score | Performance | Accessibility | Best Practices | SEO | Security |
|---|---|---|---|---|---|
| 82 | 93 | 100 | 100 | 92 | 20 |
🟡 Needs Improvement · https://play.ee/web-development-case-studies/
| Score | Performance | Accessibility | Best Practices | SEO | Security |
|---|---|---|---|---|---|
| 68 | 88 | 90 | 96 | 100 | 20 |
🟡 Needs Improvement · https://play.ee/software-development-work-index/
| Score | Performance | Accessibility | Best Practices | SEO | Security |
|---|---|---|---|---|---|
| 74 | 94 | 90 | 96 | 100 | 20 |
🟡 Needs Improvement · https://play.ee/wordpress-support-service/
| Score | Performance | Accessibility | Best Practices | SEO | Security |
|---|---|---|---|---|---|
| 72 | 94 | 91 | 100 | 100 | 20 |
🟡 Needs Improvement · https://play.ee/web-development-in-estonia/
| Score | Performance | Accessibility | Best Practices | SEO | Security |
|---|---|---|---|---|---|
| 75 | 93 | 94 | 100 | 100 | 20 |
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://play.ee/ | 93 / 100 | 2.62 s / 591 ms | 0.000 / 0.007 |
| https://play.ee/web-development-case-studies/ | 88 / 100 | 2.68 s / 547 ms | 0.005 / 0.006 |
| https://play.ee/software-development-work-index/ | 94 / 100 | 2.50 s / 536 ms | 0.000 / 0.003 |
| https://play.ee/wordpress-support-service/ | 94 / 100 | 2.59 s / 621 ms | 0.000 / 0.002 |
| https://play.ee/web-development-in-estonia/ | 93 / 99 | 2.62 s / 536 ms | 0.000 / 0.005 |
Optimization Checklist
2 of 2 passing — 2 pass · 0 warn · 0 fail · 5 n/a
| Item | Status | Detail |
|---|---|---|
| Page caching plugin / CDN active | Pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | N/A | No raster <img> elements found (37 SVGs, 13 placeholders excluded). |
| Hero image eagerly loaded | N/A | No raster <img> elements found (37 SVGs, 13 placeholders excluded). |
| 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>) | N/A | Only 0 raster images on the page (37 SVGs, 13 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | N/A | Too few raster images to evaluate srcset width variety. |
| 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. Enforce HTTPS redirect Security
- Impact: Transport security, data integrity
- Problem: HTTP does not redirect to HTTPS (http://play.ee/ does not redirect to https://play.ee/), exposing users to man-in-the-middle risks.
- Solution:
Configure the web server (Apache/Nginx) to return a 301/302 redirect for all HTTP requests to the HTTPS equivalent:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
1B. Force HTTPS Redirect Security
- Impact: Transport security, data integrity
- Problem: HTTP requests to http://play.ee/web-development-case-studies/ do not redirect to HTTPS, leaving users vulnerable to interception.
- Solution:
Configure the web server (Apache/Nginx) to return a 301 redirect for all HTTP traffic to HTTPS:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
1C. Add HSTS Header Security
- Impact: HTTPS enforcement, downgrade attacks
- Problem: Strict-Transport-Security header is missing; browsers cannot enforce HTTPS on subsequent visits.
- Solution:
Add HSTS with a long max-age and includeSubDomains:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
1D. Enforce HTTPS and add baseline security headers Security
- Impact: Transport security, clickjacking, MIME sniffing
- Problem: HTTP does not redirect to HTTPS; HSTS, X-Content-Type-Options, and X-Frame-Options are missing (Security Headers grade 20/100).
- Solution:
Configure server to redirect all HTTP traffic to HTTPS. Add the following headers:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN"
1E. Enforce HTTPS and add HSTS Security
- Impact: Transport security, downgrade attacks
- Problem: HTTP does not redirect to HTTPS and HSTS is missing (Security Headers Grade 20/100).
- Solution:
Configure server to redirect all HTTP traffic to HTTPS and send:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
1F. Fix color contrast and link names Accessibility
- Impact: WCAG 1.4.3, 2.4.4 compliance
- Problem: 2 serious axe violations: color-contrast on multiple text elements and logo grid links lack discernible names.
- Solution:
- Increase contrast ratio to ≥4.5:1 for
.button--tertiaryand.capabilities__heading. - Add
aria-labelto logo links (e.g.,<a aria-label="Client Name Logo">).
- Increase contrast ratio to ≥4.5:1 for
1G. Add HSTS and X-Content-Type-Options Security
- Impact: Clickjacking, MIME sniffing, downgrade attacks
- Problem: Security Headers grade is 20/100; HSTS and X-Content-Type-Options are missing.
- Solution:
Add these headers to the server response.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" Header always set X-Content-Type-Options "nosniff"
Priority 2: Important
Essential for compliance, user reach, and search visibility.
2A. Add HSTS and X-Content-Type-Options Security
- Impact: Protocol downgrade protection, MIME sniffing
- Problem: Security Headers grade is 20/100; HSTS and X-Content-Type-Options are missing despite HTTPS being available.
- Solution:
Add the following headers to the server configuration:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff"
2B. Add main landmark and skip-to-content link Accessibility
- Impact: Keyboard navigation, screen reader usability
- Problem: axe-core reports missing
mainlandmark andregionviolations; HTML inventory confirms no skip-to-content link. - Solution:
Wrap the primary content in
<main>and add a skip link at the top of the<body>:<a href="#main-content" class="skip-link">Skip to content</a> <!-- ... header ... --> <main id="main-content"> <!-- content --> </main>
2C. Fix W3C HTML validation errors SEO
- Impact: Parser reliability, SEO crawling
- Problem: W3C Validator reports 7 errors including parser recovery failure at line 101 and invalid iframe placement in
<head>. - Solution:
Move the Google Tag Manager iframe out of the
<head>or ensure it is properly closed within<body>. Remove invalidnameattributes on<meta>tags. Ensure<noscript>tags are not nested incorrectly inside<head>.
2D. Fix Color Contrast Violations Accessibility
- Impact: WCAG 1.4.3 compliance, readability
- Problem: axe-core reports 1 serious violation on multiple nodes (e.g., h1 > .heading__main) where foreground/background contrast is insufficient.
- Solution:
Adjust CSS colors to meet a 4.5:1 contrast ratio for normal text. Use a contrast checker tool to verify specific hex codes for
.heading__mainand.card__meta.
2E. Add Main Landmark and Skip Link Accessibility
- Impact: Screen reader navigation, keyboard access
- Problem: HTML Inventory confirms
mainlandmark is missing; PSI auditlandmark-one-mainfails. No skip-to-content link exists. - Solution:
Wrap primary content in
<main id="main-content">and add a skip link at the top of<body>:<a href="#main-content" class="skip-link">Skip to content</a> <!-- ... content ... --> <main id="main-content">...</main>
2F. Resolve HTML Validation Errors Best Practices
- Impact: Parser reliability, SEO rendering
- Problem: W3C Validator reports 7 errors including bad start tags in
iframe/noscriptand parser recovery failure at line 100. - Solution:
Inspect the
<head>section around line 97-100. Fix the Google Tag Managernoscriptiframe nesting and remove invalidmetaattributes (e.g.,nameon meta where not allowed).
2G. Fix contrast and landmark structure Accessibility
- Impact: WCAG 1.4.3 contrast, 1.3.1 info and relationships
- Problem: axe-core reports 1 serious color-contrast violation (h1, span) and missing
mainlandmark; skip-to-content link is absent. - Solution:
- Increase contrast on
.heading__mainandp > spanto ≥4.5:1. - Wrap main content in
<main>tag. - Add
<a href="#content" class="skip-link">Skip to content</a>before navigation.
- Increase contrast on
2H. Eliminate render-blocking resources Performance
- Impact: LCP, FCP, Speed Index
- Problem: Render-blocking insight estimates 980 ms savings; LCP is 2.6 s (warning threshold 2.5 s).
- Solution:
- Defer non-critical scripts (e.g.,
jquery.bfe1bb19d13b3c17b682.min.js). - Inline critical CSS and defer non-critical stylesheets.
- Defer non-critical scripts (e.g.,
2I. Fix color contrast on headings Accessibility
- Impact: WCAG 1.4.3 compliance, readability
- Problem: axe-core found 1 serious violation: color-contrast on
.focus__headingand.capabilities__headingelements. - Solution:
Increase contrast ratio to at least 4.5:1 for normal text. Adjust CSS colors for
.heading__mainand.heading__smallelements.
Priority 3: Best Practice
Recommended for long-term maintainability.
3A. Optimize LCP and font loading Performance
- Impact: LCP (2.6 s), FCP (1.96 s)
- Problem: LCP is 2.6 s on mobile; Browser Runtime shows 3 font requests taking ~580 ms each, contributing to render delay.
- Solution:
Preload the primary font used for the LCP element and use
font-display: swapin CSS. Consider reducing font file sizes or using variable fonts:<link rel="preload" href="/fonts/primary.woff2" as="font" type="font/woff2" crossorigin>
3B. Implement Content Security Policy (CSP) Security
- Impact: XSS mitigation (low risk site)
- Problem: CSP is weak (only
frame-ancestors). Site signals indicate no auth/payments/UGC, so XSS risk is lower but defense-in-depth is recommended. - Solution:
Deploy a strict CSP with nonces for scripts rather than a flat allowlist:
Header set Content-Security-Policy "default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none';"
3C. Add Explicit Image Dimensions Performance
- Impact: CLS, Layout stability
- Problem: HTML Inventory shows 56 images missing width/height attributes, risking layout shifts during load.
- Solution:
Ensure all
<img>tags includewidthandheightattributes matching the intrinsic aspect ratio:<img src="image.jpg" alt="..." width="800" height="600">
3D. Add explicit dimensions to images Performance
- Impact: CLS (Cumulative Layout Shift)
- Problem: 53 images lack width/height attributes, risking layout shifts despite current CLS 0.000 score.
- Solution:
Add
widthandheightattributes to all<img>tags matching their intrinsic aspect ratio. Use CSSaspect-ratioif dimensions vary.
3E. Add image dimensions and lazy loading Best Practices
- Impact: CLS, bandwidth
- Problem: 31 images missing width/height attributes and
loading="lazy". - Solution:
- Add
widthandheightto all<img>tags to reserve space. - Add
loading="lazy"to images below the fold.
- Add
3F. Implement Content-Security-Policy Security
- Impact: XSS defense-in-depth
- Problem: CSP is missing (only
frame-ancestorsset). Site has no auth/payments, so risk is lower but still recommended. - Solution:
Deploy a strict CSP with nonce/hash:
Content-Security-Policy: default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none';
3G. Add explicit width/height to images Performance
- Impact: CLS (Cumulative Layout Shift)
- Problem: HTML Inventory shows 67 images without explicit width/height attributes, risking layout shifts despite current CLS 0.000.
- Solution:
Add
widthandheightattributes to all<img>tags matching the intrinsic aspect ratio.<img src="logo.svg" alt="Logo" width="200" height="50">
▸Raw Markdown sent to the LLM
# Site Audit — https://play.ee/
Run: 2026-09-15T13:10:14.864Z
Audited **5** of 5 discovered pages.
Average per-page audit coverage: **100%**
Pages audited:
- https://play.ee/
- https://play.ee/web-development-case-studies/
- https://play.ee/software-development-work-index/
- https://play.ee/wordpress-support-service/
- https://play.ee/web-development-in-estonia/
---
# Page 1 of 5 — https://play.ee/
Run: 2026-09-15T13:10:14.943Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 26485 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **93** | 100 |
| Accessibility | 100 | 100 |
| Best Practices | 100 | 100 |
| SEO | 92 | 92 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.6 s** | 0.6 s |
| CLS | 0.000 | **0.007** |
| TBT | **21 ms** | 0 ms |
| FCP | **1.96 s** | 516 ms |
| Speed Index | **3.90 s** | 516 ms |
| TTFB | 5 ms | **10 ms** |
### Priority fixes
1. **largest-contentful-paint** (low) — 2.6 s
2. **speed-index** (low) — 3.9 s
3. **first-contentful-paint** (low) — 2.0 s
4. **network-dependency-tree-insight** (high)
5. **render-blocking-insight** (high) — Est savings of 1,000 ms
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### Long tasks
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 71 ms
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.87, weight 25) — Largest Contentful Paint — 2.6 s
- `speed-index` (performance, score 0.82, weight 10) — Speed Index — 3.9 s
- `first-contentful-paint` (performance, score 0.85, weight 10) — First Contentful Paint — 2.0 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `link-text` (seo, score 0.00, weight 1) — Links do not have descriptive text — 9 links found
### 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 48 ms._
**Transport:**
- Final URL: https://play.ee/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 15 Sep 2026 08:38:43 GMT
- expires: Tue, 15 Sep 2026 13:10:14 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 35451
- Decoded body: 216.5 KB
- Compression ratio: 0.16
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
- X-Powered-By: `PHP/8.3.33`
#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 35451
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Tue, 15 Sep 2026 13:10:14 GMT
expires: Tue, 15 Sep 2026 13:10:14 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 15 Sep 2026 08:38:43 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.33
```
### 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 739 ms._
**Scoring:** 7 errors · 0 warnings · 23 cosmetic (suppressed)
> **Validator truncated at line 101** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 101** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 98
3. **Stray end tag “noscript”.** (medium) — x1, first at line 98
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 100
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 100
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 98 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 98 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 100 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 100 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Stray end tag “head”. — first at line 100 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 101 `/></head>
<body class="home wp-singular page-template page-template-template-dyn`
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 101 `/></head>
<body class="home wp-singular page-template page-template-template-dyn`
### 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 2300 ms._
**Scoring:** 2 violations · 32 passes · critical 0 · serious 0 · moderate 2 · minor 0
### Priority fixes
1. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
2. **region** (medium) — All page content should be contained by landmarks
### Findings
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.home-hero__main`
- `.home-hero__bottom`
- `canvas`
- `.keywords__mouse`
- `.keywords__intro`
- … and 31 more nodes
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 38 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 2317 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 13 network requests · 178.1 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 4 | 45.6 KB |
| document | 1 | 34.6 KB |
| stylesheet | 2 | 34.2 KB |
| other | 1 | 5.5 KB |
| image | 1 | 576 B |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/fc2fa85e-cd2d-4004-930a-8adad6c60317.3bd2a5f3705d9fb438c5.woff2 (font) — 589 ms, 19.3 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/f389f79b-6013-4448-aa6a-b6fd235eab80.b91a05bafb09e626383a.woff2 (font) — 588 ms, 19.0 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/1c0243aa-c535-4d42-ac53-d6f0f74a1412.bd94708352cbb3b4863c.woff2 (font) — 404 ms, 19.3 KB
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 80 ms, 0 B
- https://play.ee/ (document) — 27 ms, 34.6 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 2317 ms._
**Document:**
- Lang: en
- Title: Perfectly formed web development team - gotoAndPlay
- Canonical: https://play.ee/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 217719
**Meta tags:**
- Description: Small, agile web development team working on big ideas in close collaboration with our clients. Result driven from day one!
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 7 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time)
- Twitter tags: 3
- hreflang:
- en → http://play.ee/
- et → http://play.ee/et/
- x-default → http://play.ee/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×1, h2 ×6, h3 ×5, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: we create memorable experiences with
web technologi
- h2: Your result
- h2: we offer
more than expected
- h2: Üks
- h2: meet the team of
uncommon talent
- h2: proof to our approach are
happy clients
- h3: Deliverables with high quality standards
- h3: Working with gotoAndPlay is a great experience
- h3: Speed, attitude, skills!
- h3: Hardworking, fun & ready to adopt new technologies
- h3: The sky is the limit
- h2: take a look at our
case studies
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 23 total — 3 defer, 0 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
**Stylesheets:** 1 external, 3 inline (9.6 KB)
**Images:** 50 total — **0 without alt**, **50 without width/height**, 50 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| ee/wp-content/themes/gotoandplay/inc/theme/img/landscape.svg | Please turn your device sideways | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 46 anchors — 34 external, 1 preconnect, 0 preload.
Vague repeated link text:
- "read more" ×9
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "case studies" ×2
- "styleguide" ×2
- "privacy policy" ×2
**Forms:**
Form 1:
- text — labeled
### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **50 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)
3. **Vague link text repeated** (medium) — "read more" ×9
### 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 · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (37 SVGs, 13 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (37 SVGs, 13 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (37 SVGs, 13 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.23.3.3`
### 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://play.ee/web-development-case-studies/
Run: 2026-09-15T13:10:14.946Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 56239 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **88** | 100 |
| Accessibility | 90 | **89** |
| Best Practices | 96 | 96 |
| SEO | 100 | 100 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.7 s** | 0.5 s |
| CLS | 0.005 | **0.006** |
| TBT | **151 ms** | 0 ms |
| FCP | **1.99 s** | 487 ms |
| Speed Index | **5.89 s** | 521 ms |
| TTFB | 4 ms | 4 ms |
### Priority fixes
1. **speed-index** (high) — 5.9 s
2. **largest-contentful-paint** (low) — 2.7 s
3. **first-contentful-paint** (low) — 2.0 s
4. **lcp-breakdown-insight** (high)
5. **network-dependency-tree-insight** (high)
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### Layout-shift sources
- footer.footer > h2.heading > span.heading__main > a.link — shift 0.004
- div.main > footer.footer > h2.heading > span.heading__small — shift 0.000
#### Long tasks
- https://play.ee/web-development-case-studies/ — 302 ms
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 201 ms
- https://play.ee/web-development-case-studies/ — 135 ms
- Unattributable — 99 ms
- https://play.ee/web-development-case-studies/ — 72 ms
- Unattributable — 70 ms
- Unattributable — 68 ms
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `speed-index` (performance, score 0.48, weight 10) — Speed Index — 5.9 s
- `largest-contentful-paint` (performance, score 0.86, weight 25) — Largest Contentful Paint — 2.7 s
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `first-contentful-paint` (performance, score 0.84, weight 10) — First Contentful Paint — 2.0 s
- `lcp-breakdown-insight` (performance, score 0.00, weight 0) — LCP breakdown
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `image-size-responsive` (best-practices, score 0.00, weight 1) — Serves images with low resolution
- `max-potential-fid` (performance, score 0.66, weight 0) — Max Potential First Input Delay — 200 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 44 ms._
**Transport:**
- Final URL: https://play.ee/web-development-case-studies/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/web-development-case-studies/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 15 Sep 2026 08:38:53 GMT
- expires: Tue, 15 Sep 2026 13:10:14 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 28049
- Decoded body: 192.3 KB
- Compression ratio: 0.142
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/web-development-case-studies/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
- X-Powered-By: `PHP/8.3.33`
#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 28049
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Tue, 15 Sep 2026 13:10:14 GMT
expires: Tue, 15 Sep 2026 13:10:14 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 15 Sep 2026 08:38:53 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.33
```
### 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 751 ms._
**Scoring:** 7 errors · 0 warnings · 23 cosmetic (suppressed)
> **Validator truncated at line 100** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 100** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 97
3. **Stray end tag “noscript”.** (medium) — x1, first at line 97
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 99
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 99
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 97 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 97 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Stray end tag “head”. — first at line 99 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
### 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 2072 ms._
**Scoring:** 3 violations · 28 passes · critical 0 · serious 1 · moderate 2 · minor 0
### Priority fixes
1. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
2. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
3. **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)
- `h1 > .heading__main`
- `#case_study-20063 > .card__inner > .card__content > .card__meta`
- `#case_study-3610 > .card__inner > .card__content > .card__title.h4`
- `#case_study-3610 > .card__inner > .card__content > .card__meta`
- `#case_study-3420 > .card__inner > .card__content > .card__title.h4`
- … and 18 more nodes
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `h1`
- `.sidebar__title`
- `.sidebar__list`
- `.button__text`
- `#case_study-20063 > .card__inner > .card__content`
- … and 22 more nodes
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 9 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 2085 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 13 network requests · 178.2 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 5 | 53.5 KB |
| stylesheet | 2 | 34.2 KB |
| document | 1 | 27.4 KB |
| other | 1 | 5.5 KB |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/1c0243aa-c535-4d42-ac53-d6f0f74a1412.bd94708352cbb3b4863c.woff2 (font) — 214 ms, 19.3 KB
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 66 ms, 0 B
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (xhr) — 52 ms, 0 B
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (script) — 30 ms, 10.1 KB
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (script) — 30 ms, 3.0 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 2085 ms._
**Document:**
- Lang: en
- Title: Case studies of the web development company gotoAndPlay
- Canonical: https://play.ee/web-development-case-studies/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 193709
**Meta tags:**
- Description: Read about the different web development projects of gotoAndPlay. Find out more about the process, challenges and results of our work.
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 7 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time)
- Twitter tags: 3
- hreflang:
- en → https://play.ee/web-development-case-studies/
- et → https://play.ee/et/tehtud-tood/
- x-default → https://play.ee/web-development-case-studies/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×1, h2 ×22, h3 ×0, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: take a look at our
featured projects
- h2: by client
- h2: unlocking the future of trailer sharing
- h2: a digital glow-up for one of Estonia’s top furniture retailers
- h2: coding a healthier future
- h2: building cyber bridges
- h2: navigating digital waters
- h2: egg-citing digital transformation
- h2: heating up the web with a new site
- h2: bringing a breath of fresh air to office environments
- h2: Swooshing through the ERP world using Katana
- h2: three interwoven websites for a single pizza franchise
- h2: A web ecosystem for the most unique cinema in town
- h2: website for a top tier law firm
- h2: A handcrafted sofa for your living room
- h2: a total makeover for a business that will never cease to exist
- h2: a modular webpage for a company that has their sight set on the future
- h2: a high security web application for keeping an eye on your finances
- h2: Award winning website for 21st century home
- h2: Stress-free tutoring with tutor.id web application
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 25 total — 3 defer, 1 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
- https://play.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (async)
**Stylesheets:** 1 external, 3 inline (9.6 KB)
**Images:** 56 total — **0 without alt**, **56 without width/height**, 56 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20300%20240%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 69 anchors — 14 external, 1 preconnect, 0 preload.
Vague repeated link text:
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "styleguide" ×2
- "privacy policy" ×2
### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **56 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 · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (20 SVGs, 36 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (20 SVGs, 36 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (20 SVGs, 36 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.23.3.3`
### 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://play.ee/software-development-work-index/
Run: 2026-09-15T13:10:54.621Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 74473 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **94** | 100 |
| Accessibility | 90 | **89** |
| Best Practices | 96 | 96 |
| SEO | 100 | 100 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.5 s** | 0.5 s |
| CLS | 0.000 | **0.003** |
| TBT | 0 ms | 0 ms |
| FCP | **1.96 s** | 516 ms |
| Speed Index | **4.08 s** | 619 ms |
| TTFB | **41 ms** | 32 ms |
### Priority fixes
1. **speed-index** (low) — 4.1 s
2. **first-contentful-paint** (low) — 2.0 s
3. **network-dependency-tree-insight** (high)
4. **render-blocking-insight** (high) — Est savings of 1,290 ms
5. **unused-css-rules** (high) — Est savings of 32 KiB
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `speed-index` (performance, score 0.79, weight 10) — Speed Index — 4.1 s
- `first-contentful-paint` (performance, score 0.85, weight 10) — First Contentful Paint — 2.0 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `image-size-responsive` (best-practices, score 0.00, weight 1) — Serves images with low resolution
### 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 42 ms._
**Transport:**
- Final URL: https://play.ee/software-development-work-index/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/software-development-work-index/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 15 Sep 2026 08:38:52 GMT
- expires: Tue, 15 Sep 2026 13:10:54 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 32392
- Decoded body: 271.6 KB
- Compression ratio: 0.116
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/software-development-work-index/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
- X-Powered-By: `PHP/8.3.33`
#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 32392
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Tue, 15 Sep 2026 13:10:54 GMT
expires: Tue, 15 Sep 2026 13:10:54 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 15 Sep 2026 08:38:52 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.33
```
### 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 731 ms._
**Scoring:** 7 errors · 0 warnings · 23 cosmetic (suppressed)
> **Validator truncated at line 100** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 100** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 97
3. **Stray end tag “noscript”.** (medium) — x1, first at line 97
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 99
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 99
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 97 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 97 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Stray end tag “head”. — first at line 99 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
### 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 1869 ms._
**Scoring:** 3 violations · 26 passes · critical 0 · serious 1 · moderate 2 · minor 0
### Priority fixes
1. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
2. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
3. **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)
- `h1 > .heading__main`
- `p:nth-child(1) > span`
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `h1`
- `.project-index__row.grid__col:nth-child(1) > .grid--middle.grid > .grid__col--last-xs.grid__col--original-sm.grid__col--sm-6`
- `.project-index__row.grid__col:nth-child(1) > .grid--middle.grid > .grid__col--sm-6.grid__col:nth-child(2) > .grid--no-wrap.grid--middle.grid > .grid__col--min.grid__col`
- `.project-index__link[href$="ehl.ee/"][target="_blank"]`
- `.has-link.project-index__row.grid__col:nth-child(2) > .grid--middle.grid > .grid__col--last-xs.grid__col--original-sm.grid__col--sm-6 > .project-index__heading`
- … and 147 more nodes
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 10 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 1887 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 13 network requests · 182.4 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 5 | 53.5 KB |
| stylesheet | 2 | 34.2 KB |
| document | 1 | 31.6 KB |
| other | 1 | 5.5 KB |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 36 ms, 0 B
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (script) — 26 ms, 3.0 KB
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (script) — 26 ms, 10.1 KB
- https://play.ee/software-development-work-index/ (document) — 24 ms, 31.6 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (script) — 22 ms, 31.5 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 1887 ms._
**Document:**
- Lang: en
- Title: High-quality software development – from idea to launch
- Canonical: https://play.ee/software-development-work-index/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 274801
**Meta tags:**
- Description: Our focus is on web application, website and software development, utilizing top-tier technologies such as Laravel, React, and Node.js.
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 7 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time)
- Twitter tags: 3
- hreflang:
- en → https://play.ee/software-development-work-index/
- et → https://play.ee/et/tarkvaraarendus-saavutuste-indeks/
- x-default → https://play.ee/software-development-work-index/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×1, h2 ×30, h3 ×0, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: highlights from the
last couple of years
- h2: Future-proof software development for Tallink
- h2: Built on years of trust – the EHL web transformation
- h2: Web experience capturing the spirit and energy of Tallinn City Theatre
- h2: Building the future of Estonian engineering with a next-gen web experience
- h2: New website for a new perspective
- h2: Risk management portal for IUTE
- h2: Unlocking the future of trailer sharing
- h2: Smart web for smart lockers
- h2: WordPress website for Forus
- h2: A new website for Coop Pank that offers the best experience for their customers
- h2: Bringing together cybersecurity experts and stakeholders
- h2: Auctions platform MVP for Foxway
- h2: Going beyond the benchmark with Katana website
- h2: Web application for a green energy marketplace
- h2: Custom tailored PIM for Telia Eesti
- h2: Back-office system for arthouse cinema
- h2: Updating a webpage for most stylish quarter in Tallinn
- h2: Amplifying the future with Low Noise Factory
- h2: Just like Airbnb, but for trailers
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 25 total — 3 defer, 1 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
- https://play.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (async)
**Stylesheets:** 1 external, 3 inline (9.6 KB)
**Images:** 53 total — **0 without alt**, **53 without width/height**, 53 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 94 anchors — 76 external, 1 preconnect, 0 preload.
Vague repeated link text:
- "visit the website" ×21
- "visit website" ×21
- "read more about the project" ×15
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "read the case study" ×3
- "read case study" ×3
### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **53 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)
3. **Vague link text repeated** (medium) — "read more about the project" ×15, "read more about futuclass" ×3
### 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 · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (24 SVGs, 29 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (24 SVGs, 29 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (24 SVGs, 29 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.23.3.3`
### 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://play.ee/wordpress-support-service/
Run: 2026-09-15T13:11:35.571Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 39702 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **94** | 100 |
| Accessibility | 91 | 91 |
| Best Practices | 100 | 100 |
| SEO | 100 | 100 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.6 s** | 0.6 s |
| CLS | 0.000 | **0.002** |
| TBT | **12 ms** | 0 ms |
| FCP | **1.96 s** | 487 ms |
| Speed Index | **4.01 s** | 557 ms |
| TTFB | 3 ms | **8 ms** |
### Priority fixes
1. **largest-contentful-paint** (low) — 2.6 s
2. **speed-index** (low) — 4.0 s
3. **first-contentful-paint** (low) — 2.0 s
4. **network-dependency-tree-insight** (high)
5. **render-blocking-insight** (high) — Est savings of 980 ms
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### Long tasks
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 73 ms
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `largest-contentful-paint` (performance, score 0.88, weight 25) — Largest Contentful Paint — 2.6 s
- `speed-index` (performance, score 0.81, weight 10) — Speed Index — 4.0 s
- `first-contentful-paint` (performance, score 0.85, weight 10) — First Contentful Paint — 2.0 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
### 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 36 ms._
**Transport:**
- Final URL: https://play.ee/wordpress-support-service/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/wordpress-support-service/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 15 Sep 2026 08:37:43 GMT
- expires: Tue, 15 Sep 2026 13:11:35 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 31016
- Decoded body: 184.1 KB
- Compression ratio: 0.165
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/wordpress-support-service/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
- X-Powered-By: `PHP/8.3.33`
#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 31016
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Tue, 15 Sep 2026 13:11:35 GMT
expires: Tue, 15 Sep 2026 13:11:35 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 15 Sep 2026 08:37:43 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.33
```
### 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 834 ms._
**Scoring:** 7 errors · 0 warnings · 30 cosmetic (suppressed)
> **Validator truncated at line 107** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 107** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 104
3. **Stray end tag “noscript”.** (medium) — x1, first at line 104
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 106
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 106
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 104 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 104 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 106 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 106 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Stray end tag “head”. — first at line 106 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 107 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 107 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
### 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 1926 ms._
**Scoring:** 4 violations · 32 passes · critical 0 · serious 2 · moderate 2 · minor 0
### Priority fixes
1. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
2. **link-name** (high) — Links must have discernible text
3. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
4. **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)
- `.button--tertiary > .button__inner > .button__text`
- `.grid__col--md-4.capabilities__grid-col.grid__col--sm-6:nth-child(1) > .heading--h5.capabilities__heading.h5 > .heading__small`
- `.grid__col--md-4.capabilities__grid-col.grid__col--sm-6:nth-child(2) > .heading--h5.capabilities__heading.h5 > .heading__small`
- `.grid__col--md-4.capabilities__grid-col.grid__col--sm-6:nth-child(3) > .heading--h5.capabilities__heading.h5 > .heading__small`
- `.grid__col--md-4.capabilities__grid-col.grid__col--sm-6:nth-child(4) > .heading--h5.capabilities__heading.h5 > .heading__small`
- … and 10 more nodes
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.logo-grid__row.js-in-viewport:nth-child(1) > .logo-grid__item:nth-child(1) > .logo-grid__link[href=""][rel="noopener"]`
- `.logo-grid__row.js-in-viewport:nth-child(1) > .logo-grid__item:nth-child(2) > .logo-grid__link[href=""][rel="noopener"]`
- `.logo-grid__row.js-in-viewport:nth-child(1) > .logo-grid__item:nth-child(3) > .logo-grid__link[href=""][rel="noopener"]`
- `.logo-grid__row.js-in-viewport:nth-child(2) > .logo-grid__item:nth-child(1) > .logo-grid__link[href=""][rel="noopener"]`
- `.logo-grid__row.js-in-viewport:nth-child(2) > .logo-grid__item:nth-child(2) > .logo-grid__link[href=""][rel="noopener"]`
- … and 4 more nodes
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.contact-hero__intro > h1`
- `.intro__content > p:nth-child(2)`
- `p:nth-child(3)`
- `.button--tertiary`
- `canvas`
- … and 95 more nodes
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 15 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 1941 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 24 network requests · 201.9 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 5 | 53.5 KB |
| stylesheet | 2 | 34.2 KB |
| document | 1 | 30.3 KB |
| image | 11 | 20.8 KB |
| other | 1 | 5.5 KB |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 36 ms, 0 B
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (script) — 29 ms, 10.1 KB
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (script) — 28 ms, 3.0 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/f389f79b-6013-4448-aa6a-b6fd235eab80.b91a05bafb09e626383a.woff2 (font) — 28 ms, 19.0 KB
- https://play.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (script) — 27 ms, 7.9 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 1941 ms._
**Document:**
- Lang: en
- Title: WordPress support service
- Canonical: https://play.ee/wordpress-support-service/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 187229
**Meta tags:**
- Description: From ongoing WordPress support to health monitoring and expert fixes, we take care of your website so you can spend more time building your business.
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 13 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time, og:image, og:image:secure_url, og:image:width, og:image:height, og:image:alt, og:image:type)
- Twitter tags: 4
- hreflang:
- en → https://play.ee/wordpress-support-service/
- et → https://play.ee/et/tugiteenus/
- x-default → https://play.ee/wordpress-support-service/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×2, h2 ×16, h3 ×14, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: Your worry-free
WordPress website
- h2: Why choose our
WordPress support service
- h3: #1
peace of mind
- h3: #2
security first
- h3: #3
expert team on-call
- h3: #4
performance wins
- h3: #5
save money
- h3: #6
monthly health reports
- h3: #7
collaboration
- h3: #8
extensive network
- h3: #9
top notch tools
- h2: service by professionals who
build websites for a l
- h2: customizable & transparent
Pricing
- h2: <Basic/>
- h2: <Advanced/>
- h2: <Pro/>
- h2: five-step
onboarding process
- h1: additional services
to upgrade your online presence
- h2: UX/UI audit
- h2: WCAG audit
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 27 total — 3 defer, 1 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
- https://play.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (async)
**Stylesheets:** 1 external, 3 inline (9.6 KB)
**Images:** 31 total — **0 without alt**, **31 without width/height**, 31 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | Expert WordPress support service | _n/a_ | _n/a_ | ✗ |
| p-content/themes/gotoandplay/inc/theme/img/line-1-mobile.svg | line-1 | _n/a_ | _n/a_ | ✗ |
| ay.ee/wp-content/themes/gotoandplay/inc/theme/img/line-1.svg | line-1 | _n/a_ | _n/a_ | ✗ |
| p-content/themes/gotoandplay/inc/theme/img/line-2-mobile.svg | line-2 | _n/a_ | _n/a_ | ✗ |
| ay.ee/wp-content/themes/gotoandplay/inc/theme/img/line-2.svg | line-2 | _n/a_ | _n/a_ | ✗ |
| p-content/themes/gotoandplay/inc/theme/img/line-3-mobile.svg | line-3 | _n/a_ | _n/a_ | ✗ |
| ay.ee/wp-content/themes/gotoandplay/inc/theme/img/line-3.svg | line-3 | _n/a_ | _n/a_ | ✗ |
| p-content/themes/gotoandplay/inc/theme/img/line-4-mobile.svg | line-4 | _n/a_ | _n/a_ | ✗ |
| ay.ee/wp-content/themes/gotoandplay/inc/theme/img/line-4.svg | line-4 | _n/a_ | _n/a_ | ✗ |
| p-content/themes/gotoandplay/inc/theme/img/line-5-mobile.svg | line-5 | _n/a_ | _n/a_ | ✗ |
| ay.ee/wp-content/themes/gotoandplay/inc/theme/img/line-5.svg | line-5 | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 57 anchors — 17 external, 2 preconnect, 0 preload.
Vague repeated link text:
- "get in touch" ×14
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "styleguide" ×2
- "privacy policy" ×2
### Priority fixes
1. **Document has 2 <h1> elements** (medium) — 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. **31 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 · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (24 SVGs, 7 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (24 SVGs, 7 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (24 SVGs, 7 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.23.3.3`
### 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://play.ee/web-development-in-estonia/
Run: 2026-09-15T13:12:42.277Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 28980 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **93** | 99 |
| Accessibility | 94 | **93** |
| Best Practices | 100 | 100 |
| SEO | 100 | 100 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.6 s** | 0.5 s |
| CLS | 0.000 | **0.005** |
| TBT | **7 ms** | 0 ms |
| FCP | **1.98 s** | 485 ms |
| Speed Index | **4.13 s** | 1.25 s |
| TTFB | 35 ms | **41 ms** |
### Priority fixes
1. **largest-contentful-paint** (low) — 2.6 s
2. **speed-index** (low) — 4.1 s
3. **first-contentful-paint** (low) — 2.0 s
4. **network-dependency-tree-insight** (high)
5. **render-blocking-insight** (high) — Est savings of 1,260 ms
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### Long tasks
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 64 ms
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `color-contrast` (accessibility, score 0.00, weight 7) — Background and foreground colors do not have a sufficient contrast ratio.
- `largest-contentful-paint` (performance, score 0.87, weight 25) — Largest Contentful Paint — 2.6 s
- `landmark-one-main` (accessibility, score 0.00, weight 3) — Document does not have a main landmark.
- `speed-index` (performance, score 0.79, weight 10) — Speed Index — 4.1 s
- `first-contentful-paint` (performance, score 0.85, weight 10) — First Contentful Paint — 2.0 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
### 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 39 ms._
**Transport:**
- Final URL: https://play.ee/web-development-in-estonia/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/web-development-in-estonia/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 15 Sep 2026 08:38:52 GMT
- expires: Tue, 15 Sep 2026 13:12:42 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 33599
- Decoded body: 219.6 KB
- Compression ratio: 0.149
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/web-development-in-estonia/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)
#### Info disclosure
- Server: `Apache`
- X-Powered-By: `PHP/8.3.33`
#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 33599
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Tue, 15 Sep 2026 13:12:42 GMT
expires: Tue, 15 Sep 2026 13:12:42 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 15 Sep 2026 08:38:52 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.33
```
### 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 843 ms._
**Scoring:** 7 errors · 0 warnings · 23 cosmetic (suppressed)
> **Validator truncated at line 100** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 100** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 97
3. **Stray end tag “noscript”.** (medium) — x1, first at line 97
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 99
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 99
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 97 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 97 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 99 `<meta name="generator" content="WP Rocket 3.23.3.3" data-wpr-features="wpr_delay`
- (×1) [error] Stray end tag “head”. — first at line 99 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 100 `/></head>
<body class="wp-singular page-template page-template-template-dynamic `
### 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 2097 ms._
**Scoring:** 3 violations · 32 passes · critical 0 · serious 1 · moderate 2 · minor 0
### Priority fixes
1. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
2. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
3. **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)
- `.focus__heading > h1 > .heading__main`
- `.capabilities__grid-col.grid__col--sm-6.grid__col--md-4:nth-child(1) > .capabilities__heading.heading--h5.h5 > .heading__small`
- `.capabilities__grid-col.grid__col--sm-6.grid__col--md-4:nth-child(2) > .capabilities__heading.heading--h5.h5 > .heading__small`
- `.capabilities__grid-col.grid__col--sm-6.grid__col--md-4:nth-child(3) > .capabilities__heading.heading--h5.h5 > .heading__small`
- `.capabilities__grid-col.grid__col--sm-6.grid__col--md-4:nth-child(4) > .capabilities__heading.heading--h5.h5 > .heading__small`
- … and 21 more nodes
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.section--page-intro`
- `.capabilities`
- `.alliance`
- `.mentoring > .section__inner > .section__content > .h-container > .intro`
- `.partners-logos`
- … and 58 more nodes
### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 88 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 2113 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 14 network requests · 201.7 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 5 | 53.5 KB |
| stylesheet | 2 | 34.2 KB |
| document | 1 | 32.8 KB |
| image | 1 | 18.1 KB |
| other | 1 | 5.5 KB |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/1c0243aa-c535-4d42-ac53-d6f0f74a1412.bd94708352cbb3b4863c.woff2 (font) — 215 ms, 19.3 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/fc2fa85e-cd2d-4004-930a-8adad6c60317.3bd2a5f3705d9fb438c5.woff2 (font) — 215 ms, 19.3 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/fonts/f389f79b-6013-4448-aa6a-b6fd235eab80.b91a05bafb09e626383a.woff2 (font) — 215 ms, 19.0 KB
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 39 ms, 0 B
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (script) — 29 ms, 3.0 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 2113 ms._
**Document:**
- Lang: en
- Title: Expert web development in Estonia and worldwide
- Canonical: https://play.ee/web-development-in-estonia/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 221970
**Meta tags:**
- Description: Premium web development in Estonia and beyond. We provide a full range of services, from building simple websites to complex web applications.
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 7 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time)
- Twitter tags: 3
- hreflang:
- en → https://play.ee/web-development-in-estonia/
- et → https://play.ee/et/veebiarendus-eestis/
- x-default → https://play.ee/web-development-in-estonia/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×2, h2 ×27, h3 ×37, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: our
strong suit
- h2: we love
web apps
- h2: we make awesome
websites
- h2: we validate ideas by
prototyping
- h2: how it's done
our way
- h3: 01
discover
- h3: 02
research
- h3: 03
plan
- h3: 04
create and iterate
- h3: 05
launch
- h3: 06
support
- h2: we are part of
play & nope alliance
- h2: we believe in learning from
each other
- h2: we love our
partners
- h2: follow our
journey
- h3: GOTOANDPLAY WAS FOUNDED
- h3: THE TEAM IS GROWING
- h3: FIRST BIG PROJECT
- h3: FIRST BIG CLIENT
- h3: WE SNATCHED PLAY.EE
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 32 total — 3 defer, 1 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
- https://play.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (async)
**Stylesheets:** 1 external, 3 inline (9.6 KB)
**Images:** 67 total — **0 without alt**, **67 without width/height**, 67 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20352%20264%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| ;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| 0%2Fsvg%22%20viewBox%3D%220%200%20230%2080%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 62 anchors — 46 external, 1 preconnect, 0 preload.
Vague repeated link text:
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "styleguide" ×2
- "privacy policy" ×2
### Priority fixes
1. **Document has 2 <h1> elements** (medium) — 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. **67 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 · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (52 SVGs, 15 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (52 SVGs, 15 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (52 SVGs, 15 placeholders excluded) — responsive-image rule does not apply. |
| Reasonable number of image sizes | – n/a | Too few raster images to evaluate srcset width variety. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.23.3.3`
### 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).