{
  "data": {
    "slug": "bcdd95e2",
    "url": "https://www.liveagent.sk",
    "domain": "liveagent.sk",
    "overall_score": 78,
    "scores_json": {
      "seo": {
        "score": 85,
        "checks": [
          {
            "i18n": {
              "key": "seo.meta-title.pass",
              "params": {
                "chars": 40,
                "title": "LiveAgent - Helpdesk Softvér a Live Chat"
              }
            },
            "name": "Meta Title",
            "value": "40 chars — \"LiveAgent - Helpdesk Softvér a Live Chat\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.meta-desc.fail-missing"
            },
            "name": "Meta Description",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Write a compelling meta description (120-160 chars) with a call-to-action. Include your target keyword naturally.",
            "whyMatters": "Without a meta description, Google auto-generates one — often poorly. A custom description gives you control over the SERP snippet and improves click-through."
          },
          {
            "i18n": {
              "key": "seo.h1.pass",
              "params": {
                "text": "Poskytujte bezproblémovú podporu s AI helpdeskom"
              }
            },
            "name": "H1 Heading",
            "value": "\"Poskytujte bezproblémovú podporu s AI helpdeskom\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.h2.pass",
              "params": {
                "count": 9
              }
            },
            "name": "Content Structure (H2 Headings)",
            "value": "9 H2 subheadings found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.og.pass",
              "params": {
                "tags": "og:title, og:description, og:image, og:type"
              }
            },
            "name": "Open Graph Tags",
            "value": "og:title, og:description, og:image, og:type",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.og-format.pass",
              "params": {
                "contentType": "image/jpeg"
              }
            },
            "name": "Open Graph Image Format",
            "value": "image/jpeg",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.twitter.warning"
            },
            "name": "Twitter/X Cards",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add <meta name='twitter:card' content='summary_large_image'>, twitter:title, and twitter:image tags.",
            "whyMatters": "Twitter Cards make your links stand out in X/Twitter feeds. Without them, shared links appear as plain text URLs."
          },
          {
            "i18n": {
              "key": "seo.canonical.warning-ogurl",
              "params": {
                "ogUrl": "https://www.liveagent.sk/"
              }
            },
            "name": "Canonical URL",
            "value": "og:url present (https://www.liveagent.sk/) but <link rel=canonical> missing",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add <link rel='canonical' href='https://www.liveagent.sk/'> to <head>. og:url covers social sharing; canonical covers Google + AI crawlers explicitly.",
            "whyMatters": "og:url helps social platforms but Google ranks the canonical tag higher. With both present, you avoid any duplicate-content ambiguity."
          },
          {
            "i18n": {
              "key": "seo.jsonld.pass",
              "params": {
                "count": 1,
                "types": "Review, Person, SoftwareApplication"
              }
            },
            "name": "Structured Data (JSON-LD)",
            "value": "1 block(s): Review, Person, SoftwareApplication",
            "status": "pass",
            "evidence": {
              "source": "schema"
            }
          },
          {
            "i18n": {
              "key": "seo.jsonld-valid.pass",
              "params": {
                "count": 1
              }
            },
            "name": "JSON-LD Validity",
            "value": "1 block(s) parse cleanly",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.robots.pass-sitemap"
            },
            "name": "robots.txt",
            "value": "Present, references sitemap",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "seo.sitemap.pass-count",
              "params": {
                "count": 1347
              }
            },
            "name": "XML Sitemap",
            "value": "Found with 1347 URLs",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "seo.html-lang.warning"
            },
            "name": "HTML Language Attribute",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add lang attribute to your <html> tag, e.g., <html lang='en'> or <html lang='de'>.",
            "whyMatters": "The lang attribute helps search engines serve your content to the right language audience and improves accessibility."
          },
          {
            "i18n": {
              "key": "seo.img-alt.pass",
              "params": {
                "rate": 99,
                "total": 207
              }
            },
            "name": "Image Alt Attributes",
            "value": "99% of 207 images have alt text",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.text-ratio.info",
              "params": {
                "ratio": 4,
                "words": 1876
              }
            },
            "name": "Text-to-HTML Ratio",
            "value": "4% ratio but 1876 words — content is substantial; the low ratio is markup/inline-JS bloat, not thin content",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your text content is sufficient. To raise the ratio, move inline <script>/<style> to external files and trim template bloat — this is a performance/cleanliness win, not a content gap.",
            "whyMatters": "Text-to-HTML ratio is only a thin-content signal when actual word count is also low. With 500+ words, search engines have plenty to rank on."
          },
          {
            "i18n": {
              "key": "seo.favicon.pass"
            },
            "name": "Favicon",
            "value": "Favicon detected",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "seo.img-format.pass",
              "params": {
                "avif": 0,
                "rate": 74,
                "webp": 88
              }
            },
            "name": "Image Format Optimization",
            "value": "74% next-gen formats (88 WebP, 0 AVIF)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.semantic.pass",
              "params": {
                "used": "<article>, <nav>, <main>, <header>, <footer>",
                "count": 5
              }
            },
            "name": "Semantic HTML Structure",
            "value": "5/6 semantic elements: <article>, <nav>, <main>, <header>, <footer>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.content-depth.pass",
              "params": {
                "words": 1876
              }
            },
            "name": "Content Depth",
            "value": "1876 words — sufficient content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.deep-heading.pass",
              "params": {
                "h2": 9,
                "h3": 32
              }
            },
            "name": "Deep Heading Hierarchy",
            "value": "H2: 9, H3: 32 — well-structured content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.internal-links.pass",
              "params": {
                "count": 29
              }
            },
            "name": "Internal Linking",
            "value": "29 internal links — strong site navigation",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.a11y.warning",
              "params": {
                "missing": "skip navigation link, lang attribute",
                "signals": 2
              }
            },
            "name": "Accessibility Fundamentals",
            "value": "2/4 a11y signals — missing: skip navigation link, lang attribute",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add: ARIA landmark roles (role='navigation', role='main'), aria-label on interactive elements, a 'Skip to content' link, and lang attribute on <html>.",
            "whyMatters": "The European Accessibility Act (EAA) takes effect June 2025 for e-commerce. Non-compliant sites face fines. Accessibility also improves SEO, as Google treats it as a ranking signal."
          },
          {
            "i18n": {
              "key": "seo.sitemap-freshness.pass",
              "params": {
                "days": 14
              }
            },
            "name": "Sitemap Freshness",
            "value": "Newest <lastmod> 14 day(s) ago",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          }
        ]
      },
      "gdpr": {
        "score": 70,
        "checks": [
          {
            "i18n": {
              "key": "gdpr.cmp.pass",
              "params": {
                "provider": "TrustArc"
              }
            },
            "name": "Cookie Consent Banner (CMP)",
            "value": "TrustArc detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "legalRefs": {
              "gdpr": [
                "Art. 6(1)(a)",
                "Art. 7"
              ],
              "skLaw": [
                "§ 14"
              ],
              "verified": [
                {
                  "title": "Zákonnosť spracúvania",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 6 — Zákonnosť spracúvania 1. Spracúvanie je zákonné iba vtedy a iba v tom rozsahu, keď je splnená aspoň jedna z týchto podmienok: Písmeno f) prvého pododseku sa nevzťahuje na spracúvanie vykonávané orgánmi verejnej moci pri výkone i",
                  "citation": "čl. 6 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky vyjadrenia súhlasu",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 7 — Podmienky vyjadrenia súhlasu 1. Ak je spracúvanie založené na súhlase, prevádzkovateľ musí vedieť preukázať, že dotknutá osoba vyjadrila súhlas so spracúvaním svojich osobných údajov. 2. Ak dá dotknutá osoba súhlas v rámci písom",
                  "citation": "čl. 7 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky poskytnutia súhlasu so spracúvaním osobných údajov",
                  "excerpt": "§ 14 Podmienky poskytnutia súhlasu so spracúvaním osobných údajov (1) Ak je spracúvanie osobných údajov založené na súhlase dotknutej osoby, prevádzkovateľ je povinný kedykoľvek vedieť preukázať, že dotknutá osoba poskytla súhlas so spracúv",
                  "citation": "§14 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.tracking.pass-none"
            },
            "name": "Tracking Scripts & Consent",
            "value": "No tracking scripts detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "legalRefs": {
              "gdpr": [
                "Art. 6(1)(a)",
                "Art. 7",
                "EDPB Opinion 5/2019"
              ],
              "skLaw": [
                "§ 14"
              ],
              "verified": [
                {
                  "title": "Zákonnosť spracúvania",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 6 — Zákonnosť spracúvania 1. Spracúvanie je zákonné iba vtedy a iba v tom rozsahu, keď je splnená aspoň jedna z týchto podmienok: Písmeno f) prvého pododseku sa nevzťahuje na spracúvanie vykonávané orgánmi verejnej moci pri výkone i",
                  "citation": "čl. 6 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky vyjadrenia súhlasu",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 7 — Podmienky vyjadrenia súhlasu 1. Ak je spracúvanie založené na súhlase, prevádzkovateľ musí vedieť preukázať, že dotknutá osoba vyjadrila súhlas so spracúvaním svojich osobných údajov. 2. Ak dá dotknutá osoba súhlas v rámci písom",
                  "citation": "čl. 7 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky poskytnutia súhlasu so spracúvaním osobných údajov",
                  "excerpt": "§ 14 Podmienky poskytnutia súhlasu so spracúvaním osobných údajov (1) Ak je spracúvanie osobných údajov založené na súhlase dotknutej osoby, prevádzkovateľ je povinný kedykoľvek vedieť preukázať, že dotknutá osoba poskytla súhlas so spracúv",
                  "citation": "§14 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.privacy-policy.fail"
            },
            "name": "Privacy Policy Page",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Create a comprehensive privacy policy covering: what data you collect, why (legal basis), how long you store it, who you share it with, and how users can exercise their GDPR rights (access, deletion, portability).",
            "legalRefs": {
              "gdpr": [
                "Art. 12",
                "Art. 13",
                "Art. 14"
              ],
              "skLaw": [
                "§ 19",
                "§ 20"
              ],
              "verified": [
                {
                  "title": "Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 12 — Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby 3. Prevádzkovateľ poskytne dotknutej osobe informácie o opatreniach, ktoré sa prijali na základe žiadosti podľa článkov 15 až 22, bez zbytočného odklad",
                  "citation": "čl. 12 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 13 — Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby 2. Okrem informácií, ktoré sa uvádzajú v odseku 1, prevádzkovateľ poskytne dotknutej osobe pri získavaní osobných údajov tieto ďalšie informá",
                  "citation": "čl. 13 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Informácie, ktoré sa majú poskytnúť, ak osobné údaje neboli získané od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 14 — Informácie, ktoré sa majú poskytnúť, ak osobné údaje neboli získané od dotknutej osoby 2. Okrem informácií uvedených v odseku 1 prevádzkovateľ poskytne dotknutej osobe tieto ďalšie informácie potrebné na zabezpečenie spravodliv",
                  "citation": "čl. 14 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby",
                  "excerpt": "§ 19 Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby (4) Odseky 1 až 3 sa neuplatňujú v rozsahu, v akom boli informácie dotknutej osobe poskytnuté pred spracúvaním osobných údajov.",
                  "citation": "§19 ods. 4 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje nie sú získané od dotknutej osoby",
                  "excerpt": "§ 20 Poskytované informácie, ak osobné údaje nie sú získané od dotknutej osoby (5) d) ak osobné údaje musia zostať dôverné na základe povinnosti mlčanlivosti podľa osobitného predpisu. 15 )",
                  "citation": "§20 ods. 5 písm. d) zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            },
            "whyMatters": "A missing privacy policy is one of the most frequently cited GDPR violations. Every EU data protection authority considers it a basic requirement."
          },
          {
            "i18n": {
              "key": "gdpr.cookie-policy.warning"
            },
            "name": "Cookie Policy",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Create a separate cookie policy page listing every cookie by: name, provider, purpose, category (necessary/analytics/marketing), and expiration. Most CMPs auto-generate this.",
            "legalRefs": {
              "gdpr": [
                "Art. 12",
                "Art. 13(1)(c)-(e)"
              ],
              "skLaw": [
                "§ 19"
              ],
              "verified": [
                {
                  "title": "Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 12 — Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby 3. Prevádzkovateľ poskytne dotknutej osobe informácie o opatreniach, ktoré sa prijali na základe žiadosti podľa článkov 15 až 22, bez zbytočného odklad",
                  "citation": "čl. 12 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 13 — Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby 2. Okrem informácií, ktoré sa uvádzajú v odseku 1, prevádzkovateľ poskytne dotknutej osobe pri získavaní osobných údajov tieto ďalšie informá",
                  "citation": "čl. 13 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby",
                  "excerpt": "§ 19 Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby (4) Odseky 1 až 3 sa neuplatňujú v rozsahu, v akom boli informácie dotknutej osobe poskytnuté pred spracúvaním osobných údajov.",
                  "citation": "§19 ods. 4 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            },
            "whyMatters": "The ePrivacy Directive requires transparent cookie disclosure. Vague statements like 'we use cookies for functionality' don't meet the specificity requirement."
          },
          {
            "i18n": {
              "key": "gdpr.imprint.warning"
            },
            "name": "Legal Contact / Imprint Page",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add an imprint/about-us page with: company name, registered address, contact email, VAT number, and trade register info. In Germany/Austria/Switzerland this is legally required (Impressumspflicht).",
            "whyMatters": "In DACH countries, a missing Impressum can trigger fines and competitor cease-and-desist letters. For all EU stores, identifying the data controller is a GDPR Article 13 requirement."
          },
          {
            "i18n": {
              "key": "gdpr.terms.info-noncommercial"
            },
            "name": "Terms & Conditions Page",
            "value": "No Terms & Conditions link found — for a non-commercial/informational site this is optional (no purchase or paid service to govern)",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "If you accept memberships, donations, sign-ups, or run events with paid tickets, publish simple Terms of Use / participation rules and link them in the footer.",
            "confidence": "low",
            "whyMatters": "Consumer T&C (AGB/VOP) obligations attach to selling goods or services. A purely informational or non-profit site has no transaction to govern, so missing T&C isn't a compliance gap."
          },
          {
            "i18n": {
              "key": "gdpr.mixed-content.pass"
            },
            "name": "Data Encryption (No Mixed Content)",
            "value": "All resources loaded over HTTPS",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "gdpr.third-party.pass",
              "params": {
                "count": 3
              }
            },
            "name": "Third-party Data Sharing",
            "value": "3 third-party domain(s)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "gdpr.forms.warning",
              "params": {
                "count": 1
              }
            },
            "name": "Forms Without Privacy Notice",
            "value": "1 form(s) on page with no privacy policy link",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a link to your privacy policy next to or below every form that collects personal data (contact, registration, newsletter). Include a checkbox for consent where required.",
            "legalRefs": {
              "gdpr": [
                "Art. 13",
                "Art. 14"
              ],
              "skLaw": [
                "§ 19",
                "§ 20"
              ],
              "verified": [
                {
                  "title": "Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 13 — Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby 2. Okrem informácií, ktoré sa uvádzajú v odseku 1, prevádzkovateľ poskytne dotknutej osobe pri získavaní osobných údajov tieto ďalšie informá",
                  "citation": "čl. 13 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Informácie, ktoré sa majú poskytnúť, ak osobné údaje neboli získané od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 14 — Informácie, ktoré sa majú poskytnúť, ak osobné údaje neboli získané od dotknutej osoby 2. Okrem informácií uvedených v odseku 1 prevádzkovateľ poskytne dotknutej osobe tieto ďalšie informácie potrebné na zabezpečenie spravodliv",
                  "citation": "čl. 14 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby",
                  "excerpt": "§ 19 Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby (4) Odseky 1 až 3 sa neuplatňujú v rozsahu, v akom boli informácie dotknutej osobe poskytnuté pred spracúvaním osobných údajov.",
                  "citation": "§19 ods. 4 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje nie sú získané od dotknutej osoby",
                  "excerpt": "§ 20 Poskytované informácie, ak osobné údaje nie sú získané od dotknutej osoby (5) d) ak osobné údaje musia zostať dôverné na základe povinnosti mlčanlivosti podľa osobitného predpisu. 15 )",
                  "citation": "§20 ods. 5 písm. d) zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            },
            "whyMatters": "GDPR Article 13 requires informing users about data processing at the point of collection. Forms without privacy notices violate the transparency principle."
          },
          {
            "i18n": {
              "key": "gdpr.erasure.warning"
            },
            "name": "Right to Erasure (Data Deletion)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Provide a clear mechanism for users to request data deletion — either a dedicated page, a form, or explicit instructions in your privacy policy. Include a 'Delete my account' option in user settings.",
            "legalRefs": {
              "gdpr": [
                "Art. 17"
              ],
              "skLaw": [
                "§ 23"
              ],
              "verified": [
                {
                  "title": "Právo na vymazanie (právo „na zabudnutie“)",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 17 — Právo na vymazanie (právo „na zabudnutie“) 1. Dotknutá osoba má tiež právo dosiahnuť u prevádzkovateľa bez zbytočného odkladu vymazanie osobných údajov, ktoré sa jej týkajú, a prevádzkovateľ je povinný bez zbytočného odkladu vy",
                  "citation": "čl. 17 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Právo na výmaz osobných údajov",
                  "excerpt": "§ 23 Právo na výmaz osobných údajov (1) Dotknutá osoba má právo na to, aby prevádzkovateľ bez zbytočného odkladu vymazal osobné údaje, ktoré sa jej týkajú.",
                  "citation": "§23 ods. 1 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            },
            "whyMatters": "GDPR Article 17 gives users the 'right to be forgotten.' EU regulators expect a clear, accessible process, and obstructing erasure requests is a documented enforcement finding."
          },
          {
            "i18n": {
              "key": "gdpr.newsletter.pass"
            },
            "name": "Newsletter Consent",
            "value": "Newsletter form with consent mechanism detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "legalRefs": {
              "gdpr": [
                "Art. 6(1)(a)",
                "Art. 7",
                "ePrivacy Art. 13"
              ],
              "skLaw": [
                "§ 14",
                "§ 109 zák. 452/2021"
              ],
              "verified": [
                {
                  "title": "Zákonnosť spracúvania",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 6 — Zákonnosť spracúvania 1. Spracúvanie je zákonné iba vtedy a iba v tom rozsahu, keď je splnená aspoň jedna z týchto podmienok: Písmeno f) prvého pododseku sa nevzťahuje na spracúvanie vykonávané orgánmi verejnej moci pri výkone i",
                  "citation": "čl. 6 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky vyjadrenia súhlasu",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 7 — Podmienky vyjadrenia súhlasu 1. Ak je spracúvanie založené na súhlase, prevádzkovateľ musí vedieť preukázať, že dotknutá osoba vyjadrila súhlas so spracúvaním svojich osobných údajov. 2. Ak dá dotknutá osoba súhlas v rámci písom",
                  "citation": "čl. 7 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky poskytnutia súhlasu so spracúvaním osobných údajov",
                  "excerpt": "§ 14 Podmienky poskytnutia súhlasu so spracúvaním osobných údajov (1) Ak je spracúvanie osobných údajov založené na súhlase dotknutej osoby, prevádzkovateľ je povinný kedykoľvek vedieť preukázať, že dotknutá osoba poskytla súhlas so spracúv",
                  "citation": "§14 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                },
                {
                  "title": "—",
                  "excerpt": "§ 109 — (8) Každý, kto ukladá alebo získava prístup k informáciám uloženým v koncovom zariadení užívateľa, je na to oprávnený iba ak užívateľ udelil preukázateľný súhlas spĺňajúci náležitosti podľa osobitného predpisu. 126 ) Povinnosť získa",
                  "citation": "§109 ods. 8 zákona č. 452/2021 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.dpo.pass"
            },
            "name": "Data Protection Officer Contact",
            "value": "DPO / data protection contact found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "gdpr.withdrawal.pass"
            },
            "name": "Withdrawal of Consent Mechanism",
            "value": "Consent withdrawal / opt-out mechanism found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "legalRefs": {
              "gdpr": [
                "Art. 7(3)"
              ],
              "skLaw": [
                "§ 14(4)"
              ],
              "verified": [
                {
                  "title": "Podmienky vyjadrenia súhlasu",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 7 — Podmienky vyjadrenia súhlasu 1. Ak je spracúvanie založené na súhlase, prevádzkovateľ musí vedieť preukázať, že dotknutá osoba vyjadrila súhlas so spracúvaním svojich osobných údajov. 2. Ak dá dotknutá osoba súhlas v rámci písom",
                  "citation": "čl. 7 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky poskytnutia súhlasu so spracúvaním osobných údajov",
                  "excerpt": "§ 14 Podmienky poskytnutia súhlasu so spracúvaním osobných údajov (1) Ak je spracúvanie osobných údajov založené na súhlase dotknutej osoby, prevádzkovateľ je povinný kedykoľvek vedieť preukázať, že dotknutá osoba poskytla súhlas so spracúv",
                  "citation": "§14 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.ai-chat.info",
              "params": {
                "widgets": "LiveAgent"
              }
            },
            "name": "AI Chatbot Disclosure",
            "value": "Chat widget detected: LiveAgent. If it answers with AI (e.g. an AI agent or auto-replies), visitors must be told they are talking to an AI.",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic",
              "measured": "LiveAgent"
            },
            "howToFix": "If the chat uses AI (Tidio Lyro, Intercom Fin, Smartsupp AI, Chatbase…), show a clear notice at the start of the conversation, e.g. 'You are chatting with an AI assistant' / 'Komunikujete s AI asistentom', and offer a way to reach a human. If only people answer, nothing to do.",
            "confidence": "low",
            "whyMatters": "AI Act Article 50(1) (Regulation (EU) 2024/1689, applies from 2 August 2026) requires AI systems that interact with people to inform them they are interacting with an AI, unless it is obvious from the context."
          }
        ]
      },
      "nis2": {
        "score": -1,
        "checks": [
          {
            "i18n": {
              "key": "nis2.scope.unknown"
            },
            "name": "NIS2 Compliance",
            "value": "Scope undetermined — IČO/company enrichment unavailable for this domain.",
            "status": "info",
            "howToFix": "",
            "whyMatters": ""
          }
        ]
      },
      "mobile": {
        "score": 62,
        "checks": [
          {
            "i18n": {
              "key": "mob.viewport.fail"
            },
            "name": "Viewport Configuration",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add <meta name='viewport' content='width=device-width, initial-scale=1'> to your <head>. This is the absolute minimum for mobile compatibility.",
            "whyMatters": "Without the viewport tag, mobile browsers render at 980px width and zoom out — making text unreadable and buttons untappable. Google uses mobile-first indexing, so this directly kills rankings."
          },
          {
            "i18n": {
              "key": "mob.perf.warning",
              "params": {
                "score": 68
              }
            },
            "name": "Mobile Performance Score",
            "value": "68/100 (target: 90+)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Optimize for mobile: compress images to WebP, defer non-critical JS, reduce CSS file size. Mobile CPUs are several times slower than desktop — what's fast on desktop is slow on mobile.",
            "whyMatters": "Most e-commerce traffic is mobile. Google ranks based on mobile performance, not desktop."
          },
          {
            "i18n": {
              "key": "mob.taptarget.warning",
              "params": {
                "detail": "Some tappable targets are too small or too close together (Lighthouse tap-targets audit)"
              }
            },
            "name": "Touch Target Size",
            "value": "Some tappable targets are too small or too close together (Lighthouse tap-targets audit)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab",
              "measured": "Some tappable targets are too small or too close together (Lighthouse tap-targets audit)"
            },
            "howToFix": "Ensure ALL interactive elements (buttons, links, form fields) are at least 48×48px with 8px minimum spacing between them. Pay special attention to: navigation menus, filter buttons, product variant selectors, and footer links.",
            "whyMatters": "Small tap targets cause mis-taps on mobile. In e-commerce, a mis-tap on 'Remove from cart' instead of 'Checkout' directly loses revenue."
          },
          {
            "i18n": {
              "key": "mob.fontsize.warning",
              "params": {
                "detail": "Some text renders below the 12px legibility threshold (Lighthouse font-size audit)"
              }
            },
            "name": "Font Size Readability",
            "value": "Some text renders below the 12px legibility threshold (Lighthouse font-size audit)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab",
              "measured": "Some text renders below the 12px legibility threshold (Lighthouse font-size audit)"
            },
            "howToFix": "Google's font-size audit flags text under 12px. Find the small text (often footer fine-print, captions, or cookie notices) and raise it; aim for a 16px+ body base with relative units (rem/em) so all text scales legibly on mobile.",
            "whyMatters": "Text below the legibility threshold forces mobile users to pinch-zoom. This measures the actual rendered page (Lighthouse), so it catches sub-12px nodes even when the base font looks fine."
          },
          {
            "i18n": {
              "key": "mob.contentwidth.pass"
            },
            "name": "Content Fits Viewport",
            "value": "No horizontal scrolling needed",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.responsive.warning"
            },
            "name": "Responsive Design Techniques",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Implement responsive CSS with @media queries for key breakpoints: 480px (small mobile), 768px (tablet), 1024px (laptop). Use Flexbox and CSS Grid for fluid layouts.",
            "whyMatters": "Non-responsive sites are automatically penalized by Google in mobile search results. With mobile-first indexing, this is a critical ranking factor."
          },
          {
            "i18n": {
              "key": "mob.themecolor.warning"
            },
            "name": "Theme Color",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add <meta name='theme-color' content='#your-brand-color'> to match your brand. Browsers use this to color the address bar, task switcher, and PWA chrome.",
            "whyMatters": "Theme-color creates a polished, branded mobile experience. It makes your site look native and professional."
          },
          {
            "i18n": {
              "key": "mob.nav.pass"
            },
            "name": "Mobile Navigation (Semantic)",
            "value": "<nav> element present — proper navigation landmark",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.srcset.pass",
              "params": {
                "count": 182
              }
            },
            "name": "Responsive Images (srcset)",
            "value": "182 image(s) use srcset for responsive sizing",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.inputtypes.warning",
              "params": {
                "issues": "email fields use type='text' instead of type='email'"
              }
            },
            "name": "Form Input Types",
            "value": "email fields use type='text' instead of type='email'",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Use semantic input types: type='email' for email (shows @ keyboard), type='tel' for phone (shows number pad), type='search' for search (shows search button). These trigger optimized mobile keyboards.",
            "whyMatters": "Correct input types show specialized mobile keyboards — email keyboard with @, phone with number pad. This reduces input errors and speeds up form completion."
          },
          {
            "i18n": {
              "key": "mob.wcaglabels.fail",
              "params": {
                "rate": 0,
                "total": 8,
                "missing": 8,
                "withLabel": 0
              }
            },
            "name": "Form Input Labels (WCAG 3.3.2)",
            "value": "Iba 0/8 inputs má label (0%)",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Accessibility audit — Inger"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "8 input elementov nemá label. Každý input musí mať priradený <label for=\"id\">Text</label> alebo aria-label. Placeholder NIE je label (WCAG 3.3.2). Ak je checkout/registrácia formulár — toto znižuje konverziu a porušuje EN 301 549 (EAA 2026).",
            "whyMatters": "EAA 2026 (European Accessibility Act) vstupuje do platnosti 28.6.2025. E-shopy nad 10 zamestnancov alebo €2M obrat musia byť WCAG 2.1 AA kompatibilné — chýbajúce labely sú jedna z najčastejších žalovateľných chýb."
          },
          {
            "i18n": {
              "key": "mob.wcagheading.pass"
            },
            "name": "Heading Hierarchy (WCAG 1.3.1)",
            "value": "Žiadne preskočené úrovne",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.wcaglinks.warning",
              "params": {
                "count": 1
              }
            },
            "name": "Link Text Quality (WCAG 2.4.4)",
            "value": "1 odkazov má generický text (\"click here\", \"more\", \"tu\"...)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Nahraď 'Click here' / 'Read more' / 'Viac' popisným textom: 'Prečítaj si viac o GDPR', 'Pozri cenník modulov'. Screen readers čítajú odkazy mimo kontextu — samostatné 'viac' nemá význam.",
            "whyMatters": "WCAG 2.4.4: Účel odkazu musí byť zrejmý z textu. Vágne odkazy zhoršujú UX, konverziu aj SEO (Google anchor text relevancia)."
          }
        ]
      },
      "company": null,
      "modules": [],
      "security": {
        "score": 84,
        "checks": [
          {
            "i18n": {
              "key": "sec.ssl.pass"
            },
            "name": "SSL/TLS Certificate",
            "value": "Valid HTTPS connection established",
            "status": "pass",
            "evidence": {
              "source": "SSL"
            }
          },
          {
            "i18n": {
              "key": "sec.dnssec.warning"
            },
            "name": "DNSSEC",
            "value": "No DNSKEY records — zone is unsigned",
            "status": "warning",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "DNSSEC setup help →"
            },
            "evidence": {
              "source": "DNS"
            },
            "howToFix": "Enable DNSSEC at your DNS host (most modern registrars offer 1-click activation: Cloudflare, Route 53, Google Cloud DNS, web.sk, websupport.sk). Verify via dnsviz.net afterwards.",
            "whyMatters": "Without DNSSEC, attackers controlling intermediate resolvers can forge responses for your domain — sending users to phishing sites with valid HTTPS that match your name. EU national CSIRTs (SK-CERT, NÚKIB) recommend DNSSEC for all in-scope entities."
          },
          {
            "i18n": {
              "key": "sec.caa.pass",
              "params": {
                "detail": "2 CAA records (issuers: amazon.com, letsencrypt.org)"
              }
            },
            "name": "CAA DNS Record",
            "value": "2 CAA records (issuers: amazon.com, letsencrypt.org)",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            },
            "whyMatters": "CAA records prevent unauthorized CAs from issuing certs for your domain — a documented attack vector after the DigiNotar and Symantec incidents."
          },
          {
            "i18n": {
              "key": "sec.https-redirect.pass"
            },
            "name": "HTTP → HTTPS Redirect",
            "value": "HTTP properly redirects to HTTPS",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.hsts.pass",
              "params": {
                "detail": "max-age=31536000, preload, includeSubDomains"
              }
            },
            "name": "HSTS (Strict-Transport-Security)",
            "value": "max-age=31536000, preload, includeSubDomains",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.csp.pass"
            },
            "name": "Content-Security-Policy (CSP)",
            "value": "Present and reasonably configured",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.clickjacking.pass",
              "params": {
                "detail": "SAMEORIGIN"
              }
            },
            "name": "Clickjacking Protection",
            "value": "X-Frame-Options: SAMEORIGIN",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.x-content-type.pass"
            },
            "name": "X-Content-Type-Options",
            "value": "nosniff",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.referrer-policy.warning"
            },
            "name": "Referrer-Policy",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add header: Referrer-Policy: strict-origin-when-cross-origin — this is the best balance between functionality and privacy.",
            "whyMatters": "Without a referrer policy, browsers send the full URL to third parties. This can leak sensitive data like session tokens in URLs or internal page paths."
          },
          {
            "i18n": {
              "key": "sec.permissions-policy.warning"
            },
            "name": "Permissions-Policy",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add: Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=() — disable APIs your site doesn't need.",
            "whyMatters": "Without Permissions-Policy, any third-party script (ads, analytics, chat widgets) can access camera, microphone, and geolocation without your knowledge."
          },
          {
            "i18n": {
              "key": "sec.cookie-flags.pass-none"
            },
            "name": "Cookie Security Flags",
            "value": "No cookies set on initial response",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.tech-disclosure.warning",
              "params": {
                "detail": "Server: AmazonS3"
              }
            },
            "name": "Technology Disclosure",
            "value": "Server: AmazonS3",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Hide server version: set ServerTokens Prod (Apache) or server_tokens off (Nginx). Remove X-Powered-By header completely.",
            "whyMatters": "Exposing exact server/PHP versions lets attackers search CVE databases for specific exploits. This is the first step in most automated attacks."
          },
          {
            "i18n": {
              "key": "sec.sri.warning",
              "params": {
                "eligible": 3,
                "exemptNote": "",
                "withIntegrity": 0
              }
            },
            "name": "Subresource Integrity (SRI)",
            "value": "Only 0/3 SRI-eligible third-party scripts have integrity hashes",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add integrity='sha384-...' and crossorigin='anonymous' to version-pinned third-party <script> tags (use srihash.org). Auto-updating provider scripts (analytics, payment SDKs, consent tools) are correctly excluded — they can't use SRI.",
            "whyMatters": "Without SRI, if a version-pinned third-party CDN is compromised, attackers can inject malicious code into your site — the same vector as the British Airways Magecart breach."
          },
          {
            "i18n": {
              "key": "sec.security-txt.warning"
            },
            "name": "security.txt (RFC 9116)",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Create /.well-known/security.txt with Contact, Expires, and Preferred-Languages fields. See securitytxt.org for the generator.",
            "whyMatters": "security.txt lets ethical hackers report vulnerabilities responsibly. Without it, they may disclose publicly or not report at all."
          },
          {
            "i18n": {
              "key": "sec.server-version.pass",
              "params": {
                "name": "AmazonS3"
              }
            },
            "name": "Server Version Disclosure",
            "value": "AmazonS3 — version hidden",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.cdn.warning"
            },
            "name": "CDN / WAF Protection",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add a CDN/WAF like Cloudflare (free tier), Sucuri, or Fastly. They provide DDoS protection, bot filtering, and SSL management.",
            "whyMatters": "Without a CDN/WAF, your origin server is directly exposed to DDoS attacks, bot traffic, and brute-force attempts."
          },
          {
            "i18n": {
              "key": "sec.iframe-sandbox.warning",
              "params": {
                "total": 1,
                "untrusted": 1,
                "trustedNote": ""
              }
            },
            "name": "Iframe Sandboxing",
            "value": "1/1 unknown iframe(s) without sandbox attribute",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a sandbox attribute to non-provider <iframe> elements. Use sandbox='allow-scripts allow-same-origin' for third-party embeds. Trusted media/payment embeds (YouTube, Maps, Stripe, reCAPTCHA) are correctly excluded — they need full privileges to work.",
            "confidence": "low",
            "whyMatters": "Unsandboxed iframes from unknown sources can access your DOM, run scripts, and navigate the top window. They should be sandboxed to prevent clickjacking and XSS."
          }
        ]
      },
      "tech_stack": [
        {
          "name": "Splide",
          "category": "js-library"
        },
        {
          "name": "AmazonS3",
          "category": "server"
        }
      ],
      "performance": {
        "score": 91,
        "checks": [
          {
            "i18n": {
              "key": "perf.ttfb.pass",
              "params": {
                "ms": 8
              }
            },
            "name": "Server Response Time (TTFB)",
            "value": "8ms",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.fcp.pass",
              "params": {
                "s": "0.30"
              }
            },
            "name": "First Contentful Paint (FCP)",
            "value": "0.30s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.lcp.pass",
              "params": {
                "s": "0.98"
              }
            },
            "name": "Largest Contentful Paint (LCP)",
            "value": "0.98s — Core Web Vital ✓",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.tbt.pass",
              "params": {
                "ms": 168
              }
            },
            "name": "Total Blocking Time (TBT)",
            "value": "168ms",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.cls.pass",
              "params": {
                "cls": "0.000"
              }
            },
            "name": "Cumulative Layout Shift (CLS)",
            "value": "0.000 — Core Web Vital ✓",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.speed-index.pass",
              "params": {
                "s": "1.29"
              }
            },
            "name": "Speed Index",
            "value": "1.29s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.page-weight.warning",
              "params": {
                "mb": "2.0",
                "requests": 105
              }
            },
            "name": "Total Page Weight",
            "value": "2.0 MB, 105 requests (optimal: <1.5 MB, <50 req)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Reduce page weight: compress images to WebP (saves 30-50%), enable text compression (gzip/brotli), lazy load below-fold images, remove unused CSS/JS.",
            "whyMatters": "A 3 MB page takes 6+ seconds on 3G mobile. Most e-commerce traffic is mobile — heavy pages lose customers on poor connections."
          },
          {
            "i18n": {
              "key": "perf.js-budget.warning",
              "params": {
                "kb": 1014
              }
            },
            "name": "JavaScript Budget",
            "value": "1014 KB — over the 600 KB budget, but below the 1270 KB median of the award-winning shops we benchmarked",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab",
              "measured": "1014 KB JavaScript"
            },
            "howToFix": "Split the bundle so a product page doesn't load checkout and account code. Defer third-party scripts until interaction. Drop unused plugin bundles — on most shops these outweigh your own code.",
            "confidence": "high",
            "whyMatters": "Measured on a first load with no interaction, so scripts gated behind cookie consent don't count against you here. The 600 KB bar is best practice, not the cohort average: the shops we benchmarked have a median of 1 270 KB, and the best of them (a category winner that won on mobile) ships 410 KB."
          },
          {
            "i18n": {
              "key": "perf.request-budget.warning",
              "params": {
                "count": 105
              }
            },
            "name": "Request Budget",
            "value": "105 requests — over the budget of 80, but at or below the median of the award-winning shops we benchmarked (140)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab",
              "measured": "105 requests"
            },
            "howToFix": "Bundle CSS/JS that always loads together, serve icons as a sprite or font rather than individual files, and lazy-load below-fold images so they aren't requested on load.",
            "confidence": "high",
            "whyMatters": "The 80-request bar is best practice; the benchmarked cohort median is 140 and the best shop manages 37. Being under the median is not the same as being fast."
          },
          {
            "i18n": {
              "key": "perf.third-party-budget.info"
            },
            "name": "Third-party Services",
            "value": "Not measured — PageSpeed did not return the third-party audit for this URL",
            "status": "info",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Re-run the scan, or check the third-party summary directly at PageSpeed Insights.",
            "whyMatters": "We report this as unmeasured rather than as zero third parties, because those are very different findings."
          },
          {
            "i18n": {
              "key": "perf.render-blocking.info"
            },
            "name": "Render-blocking Resources",
            "value": "Not measured — PageSpeed did not return the render-blocking audit for this URL",
            "status": "info",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Re-run the scan, or test directly at PageSpeed Insights. This metric needs a successful Lighthouse lab run."
          },
          {
            "i18n": {
              "key": "perf.unused-code.fail",
              "params": {
                "kb": 285
              }
            },
            "name": "Unused Code (CSS + JS)",
            "value": "285 KB wasted on unused code!",
            "status": "fail",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "You're loading 285 KB of code that isn't used on this page. 1) Audit plugins and remove unused ones, 2) Use code-splitting for page-specific JS, 3) Run PurgeCSS on your stylesheets.",
            "whyMatters": "Over 200 KB of unused code significantly slows parsing and execution. This is one of the easiest performance wins — removing dead code requires no trade-offs."
          },
          {
            "i18n": {
              "key": "perf.text-compression.pass"
            },
            "name": "Text Compression (gzip/brotli)",
            "value": "All text resources properly compressed",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "perf.resource-hints.warning"
            },
            "name": "Resource Hints (Preload/Preconnect)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add resource hints: <link rel='preconnect' href='https://fonts.googleapis.com'> for third-party origins, <link rel='preload' as='image' href='hero.webp'> for critical resources.",
            "whyMatters": "Preconnect saves 100-500ms per third-party origin by establishing connections early. Preload starts downloading critical resources before the browser discovers them in CSS/JS."
          },
          {
            "i18n": {
              "key": "perf.lazy-load.pass",
              "params": {
                "lazy": 109,
                "rate": 53,
                "total": 207
              }
            },
            "name": "Lazy Loading",
            "value": "53% of images use native lazy loading (109/207)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "perf.http3.pass"
            },
            "name": "HTTP/3 (QUIC) Support",
            "value": "HTTP/3 enabled via Alt-Svc header",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "perf.script-strategy.pass",
              "params": {
                "rate": 100,
                "async": 0,
                "defer": 13,
                "module": 0
              }
            },
            "name": "Script Loading Strategy",
            "value": "100% of scripts use async/defer/module (0 async, 13 defer, 0 module)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "perf.css-count.pass",
              "params": {
                "count": 6
              }
            },
            "name": "CSS File Count",
            "value": "6 CSS file(s) — well consolidated",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "perf.font-preload.warning"
            },
            "name": "Font Preloading",
            "value": "Custom fonts detected without preload hints",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Preload your primary font: <link rel='preload' href='/fonts/main.woff2' as='font' type='font/woff2' crossorigin>. For Google Fonts: preconnect to fonts.gstatic.com.",
            "whyMatters": "Fonts are discovered late in the render pipeline (after CSS is parsed). Preloading tells the browser to download them immediately, reducing Flash of Invisible Text (FOIT) by 200-500ms."
          }
        ]
      },
      "ai_readiness": {
        "score": 71,
        "checks": [
          {
            "i18n": {
              "key": "air.bot-access.pass",
              "params": {
                "detail": "No AI bot restrictions (allowed by default)"
              }
            },
            "name": "AI Bot Access Policy",
            "value": "No AI bot restrictions (allowed by default)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "air.agent-live.pass"
            },
            "name": "AI Agent Access (live)",
            "value": "ChatGPT-User and PerplexityBot get the same page as a browser",
            "status": "pass",
            "weight": 2,
            "evidence": {
              "source": "file-probe",
              "measured": "ChatGPT-User, PerplexityBot: same page as a browser",
              "probedUrl": "https://www.liveagent.sk"
            }
          },
          {
            "i18n": {
              "key": "air.llms-txt.fail"
            },
            "name": "llms.txt (AI Site Descriptor)",
            "value": "Not present — not required for AI visibility",
            "status": "info",
            "fixLink": {
              "url": "https://llmstxt.org",
              "label": "About llms.txt →"
            },
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Optional: /llms.txt (a Markdown site descriptor per llmstxt.org) is future-proofing, mainly consumed by coding/IDE agents. It does NOT affect whether ChatGPT/Perplexity/Gemini cite your store. Prioritize AI-crawler access, server-rendered content, statistics and cited sources instead.",
            "whyMatters": "No answer engine consumes llms.txt for AI-search citation today (2026) — adoption is ~8.7% and Google declined to support it. It's optional future-proofing, mainly read by coding/IDE agents. Prioritize AI-crawler access, server-rendered content, statistics and cited sources instead. See /ai-readiness-methodology.md."
          },
          {
            "i18n": {
              "key": "air.llms-full.warning"
            },
            "name": "llms-full.txt (Complete AI Content)",
            "value": "Not present — not required for AI visibility",
            "status": "info",
            "evidence": {
              "source": "file-probe"
            },
            "whyMatters": "No answer engine consumes llms.txt for AI-search citation today (2026) — adoption is ~8.7% and Google declined to support it. It's optional future-proofing, mainly read by coding/IDE agents. Prioritize AI-crawler access, server-rendered content, statistics and cited sources instead. See /ai-readiness-methodology.md."
          },
          {
            "i18n": {
              "key": "air.content-access.pass",
              "params": {
                "ratio": "3.9",
                "words": 1876
              }
            },
            "name": "Content Accessibility for AI",
            "value": "1876 words in raw HTML (3.9% text ratio) — readable by AI crawlers without executing JS",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.schema-foundation.warning-single",
              "params": {
                "note": "",
                "type": "Review"
              }
            },
            "name": "Structured Data Foundation",
            "value": "Only 1 distinct schema type (Review) — insufficient for AI visibility",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "One schema type is not enough. Add at minimum: Organization (identity), Product (commerce), BreadcrumbList (navigation), WebSite+SearchAction (discoverability), FAQPage (Q&A answering).",
            "whyMatters": "Single-schema sites get minimal AI coverage. AI models need multiple data signals to confidently recommend your store."
          },
          {
            "i18n": {
              "key": "air.org-schema.fail"
            },
            "name": "Organization Schema + Entity Linking",
            "status": "fail",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add Organization (or LocalBusiness for physical stores) schema with: name, logo, url, description, contactPoint, address, and sameAs linking to all your official profiles (LinkedIn, Facebook, Wikipedia if available).",
            "whyMatters": "Organization schema is the foundation of your AI identity. Without it, AI assistants can't confidently attribute information to your brand, verify your legitimacy, or show your Knowledge Panel."
          },
          {
            "i18n": {
              "key": "air.faq-schema.warning"
            },
            "name": "FAQ Schema (Direct AI Answers)",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add FAQPage schema to every product page and category page. Include 3-5 Q&As per page covering: product specifications, shipping, returns, usage instructions. Format: question (full sentence) + answer (75-150 words).",
            "whyMatters": "ChatGPT, Perplexity, and Google AI Overviews pull FAQ answers verbatim. FAQ schema is one of the fastest ways to get your content cited by AI."
          },
          {
            "i18n": {
              "key": "air.content-depth.pass",
              "params": {
                "words": 1876
              }
            },
            "name": "Content Depth for AI",
            "value": "1876 words — rich content for AI analysis and citation",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.answer-first.pass",
              "params": {
                "words": 45
              }
            },
            "name": "Answer-First Content Format",
            "value": "First paragraph: 45 words — good content density above the fold",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.headings.pass",
              "params": {
                "h2": 9,
                "h3": 32
              }
            },
            "name": "Heading Hierarchy for AI",
            "value": "Proper structure: 1 H1 → 9 H2s → 32 H3s — clear content outline",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.semantic-html.pass",
              "params": {
                "count": 5,
                "elements": "<article>, <nav>, <main>, <header>, <footer>"
              }
            },
            "name": "Semantic HTML Structure",
            "value": "5/6 semantic elements: <article>, <nav>, <main>, <header>, <footer>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.structured-content.warning-partial",
              "params": {
                "what": "21 lists",
                "missing": "comparison tables"
              }
            },
            "name": "Structured Content (Lists & Tables)",
            "value": "21 lists found — consider adding comparison tables",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add comparison tables to your content. Use <ul>/<ol> for feature lists, specifications, and benefits. Use <table> for product comparisons, pricing tiers, and specifications. AI extracts structured content much faster than paragraphs.",
            "whyMatters": "AI models are biased toward extracting data from HTML lists and tables. Perplexity and ChatGPT pull bullet points and table data with higher accuracy than paragraph text."
          },
          {
            "i18n": {
              "key": "air.freshness.warning-novisible"
            },
            "name": "Content Freshness Signals",
            "value": "Visible date found but not in structured data",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add both: 1) dateModified and datePublished in your Article/Product JSON-LD schema, 2) A visible 'Last updated: [date]' on the page. Both signals reinforce content freshness for AI.",
            "whyMatters": "AI models weight recency in their citation algorithms. Freshness signals tell AI your content is current and reliable."
          },
          {
            "i18n": {
              "key": "air.entity-clarity.warning-nosameAs",
              "params": {
                "count": 0
              }
            },
            "name": "Entity Clarity & Brand Signals",
            "value": "OG tags complete but no sameAs entity links",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "For full entity clarity: 1) Complete Open Graph tags (og:title, og:description, og:image, og:type), 2) Add sameAs in Organization schema linking to Wikipedia, LinkedIn, Facebook, and other profiles.",
            "whyMatters": "AI needs to confidently identify your brand entity. Open Graph and sameAs together create a cross-platform identity that AI models recognize."
          },
          {
            "i18n": {
              "key": "air.eeat.warning-noarticle"
            },
            "name": "Author Expertise Signals (E-E-A-T)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "For content pages (blog, guides, about): add Article/BlogPosting schema with author property linking to Person schema. Include the author's jobTitle, credentials, and social profiles.",
            "whyMatters": "AI models weight author expertise heavily. Pages from identified experts get cited more than anonymous content. This is especially important for product guides, reviews, and advice content."
          },
          {
            "i18n": {
              "key": "air.review-schema.pass"
            },
            "name": "Reviews & Ratings Schema",
            "value": "AggregateRating/Review data found — social proof for AI",
            "status": "pass",
            "evidence": {
              "source": "schema"
            }
          },
          {
            "i18n": {
              "key": "air.extractable.warning-short",
              "params": {
                "avg": 24,
                "count": 89
              }
            },
            "name": "Extractable Answer Blocks",
            "value": "89 paragraphs, avg 24 words — too short for citation",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Optimal paragraphs for AI citation are 40-80 words. Break long paragraphs into focused, self-contained answer blocks. Each should make one clear point that AI can extract and quote.",
            "whyMatters": "AI extracts individual paragraphs as answer snippets — dense walls of text get skipped. Focused 40-80 word paragraphs are the most citable."
          },
          {
            "i18n": {
              "key": "air.statistics.pass",
              "params": {
                "count": 13
              }
            },
            "name": "Statistics & Data Presence",
            "value": "13 data points found — strong citation magnet",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.section-length.warning",
              "params": {
                "avg": 69,
                "ratio": 7
              }
            },
            "name": "Section Length Optimization",
            "value": "Avg section: 69 words — only 7% in 80-200 word optimal range",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Restructure content into sections of 120-180 words between H2/H3 headings. Each section should cover one topic completely. Split sections over 300 words, expand sections under 80 words.",
            "whyMatters": "For Google AI Overviews, 100-150 words per section is the sweet spot — long sections get skipped and very short ones lack substance."
          },
          {
            "i18n": {
              "key": "air.qa-headings.warning-some",
              "params": {
                "count": 2
              }
            },
            "name": "Q&A Format Headings",
            "value": "2 question heading(s) — add more",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Phrase H2/H3 headings as questions: 'How does...?', 'What is...?', 'Why should...?' followed by a direct 1-2 sentence answer. This is a leading format AI assistants use to generate responses.",
            "whyMatters": "AI search engines like Perplexity and ChatGPT match user questions to heading-answer pairs. Q&A format headings are directly extractable by AI and trigger FAQ-style rich results."
          },
          {
            "i18n": {
              "key": "air.internal-links.pass",
              "params": {
                "rate": 15
              }
            },
            "name": "Internal Link Density",
            "value": "15 contextual internal links per 1,000 words — strong knowledge graph signal",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.canonical.fail"
            },
            "name": "Canonical Tag for AI Deduplication",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add <link rel='canonical' href='https://your-absolute-url'> to every page. This tells AI engines which URL is the authoritative version of this content.",
            "whyMatters": "Without a canonical tag, AI models may index multiple versions of the same page (with/without trailing slash, with parameters, etc.), diluting your AI visibility across duplicate URLs."
          },
          {
            "i18n": {
              "key": "air.kg-readiness.warning",
              "params": {
                "count": 2,
                "missing": "sameAs links (Wikipedia, LinkedIn), Organization schema"
              }
            },
            "name": "Knowledge Graph Readiness",
            "value": "2/4 signals — missing: sameAs links (Wikipedia, LinkedIn), Organization schema",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add: sameAs links (Wikipedia, LinkedIn), Organization schema. Use @id in JSON-LD to create a unique node identifier. Ensure your brand name is identical in title, schema, and OG tags. Link to Wikipedia/Wikidata via sameAs.",
            "whyMatters": "@id creates a persistent entity identifier that connects your schema across pages and platforms, which is how AI builds a verified brand entity."
          },
          {
            "i18n": {
              "key": "air.readability.warning-high-technical",
              "params": {
                "grade": 20
              }
            },
            "name": "Content Readability for AI",
            "value": "Grade 20 — too complex for broad AI citation (technical threshold: 14)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Simplify sentences (target 15-20 words average), use common words, break complex ideas into shorter paragraphs. AI extracts content for general audiences — if it's too academic, AI skips it.",
            "whyMatters": "Content above grade 12 readability is harder for AI to extract as clear, concise answers. Pages using clear headers and approachable language are cited more often."
          },
          {
            "i18n": {
              "key": "air.alt-text.warning",
              "params": {
                "pct": 76,
                "poor": 20,
                "missing": 3
              }
            },
            "name": "Image Alt Text Quality for AI",
            "value": "76% good, 20 poor, 3 missing",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Improve alt text: use 3-15 descriptive words per image. Include product name, key feature, and context. Bad: 'image1' or 'photo'. Good: 'Red leather wallet with RFID protection — front view'.",
            "whyMatters": "AI uses alt text to understand images for visual search (Google Lens, Bing Visual Search), product recommendations, and accessibility. Quality alt text opens more discovery channels."
          },
          {
            "i18n": {
              "key": "air.expert-quotes.warning-none"
            },
            "name": "Expert Quotations & Citations",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add 2-3 expert quotes or data citations per major page. Use <blockquote> for quotes and link to authoritative sources (.gov, .edu, Wikipedia, industry reports).",
            "whyMatters": "Content without citations or expert quotes appears unverified to AI. AI assistants prefer content backed by named sources, data references, and expert opinions."
          },
          {
            "i18n": {
              "key": "air.ai-txt.warning"
            },
            "name": "ai.txt (AI Permissions)",
            "value": "Not present — optional; AI-bot permissions are enforced via robots.txt, not ai.txt",
            "status": "info",
            "evidence": {
              "source": "file-probe"
            },
            "whyMatters": "ai.txt is an emerging fine-grained AI-permissions proposal not yet honored by the major engines. The robots.txt AI-bot rules are the signal that actually gates crawler access."
          },
          {
            "i18n": {
              "key": "air.webmcp.warning"
            },
            "name": "WebMCP Agentic Readiness",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "WebMCP (W3C Community Group standard, Chrome 146+) lets pages declare structured tools for AI agents. Add toolname and tooldescription attributes to <form> elements, or include a <script type='application/webmcp+json'> manifest.",
            "whyMatters": "WebMCP is how AI agents will interact with your store (search products, add to cart, check availability). Google and Microsoft are co-developing this standard."
          },
          {
            "i18n": {
              "key": "air.boilerplate.pass",
              "params": {
                "ratio": 68
              }
            },
            "name": "Content-to-Boilerplate Ratio",
            "value": "68% of text in <main>/<article> — clean content signal",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.social-proof.pass",
              "params": {
                "signals": "testimonials, case studies / portfolio"
              }
            },
            "name": "Social Proof (Testimonials / Case Studies)",
            "value": "Strong social proof: testimonials, case studies / portfolio",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          }
        ]
      },
      "phaseTimings": {
        "tail": 37,
        "total": 602,
        "phase1": 410,
        "preflight": 9,
        "phase1.dns": 149,
        "phase1.html": 150,
        "phase1.files": 408,
        "phase1.zbozi": 149,
        "phase1.headers": 26,
        "phase1.heureka": 149,
        "phase1.aiAgents": 28,
        "phase1.merchant": 84
      },
      "accessibility": {
        "score": 41,
        "checks": [
          {
            "i18n": {
              "key": "a11y.lang.fail"
            },
            "name": "Page Language",
            "value": "The <html> element has no lang attribute",
            "status": "fail",
            "weight": 2,
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Accessibility audit — Inger →"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a lang attribute to <html>, e.g. <html lang=\"sk\"> — matching the page's primary language.",
            "whyMatters": "Screen readers use the lang attribute to pick the right pronunciation engine. Without it, Slovak content may be read with English phonetics — unintelligible. Required by EN 301 549 § 9.3.1.1 (WCAG 3.1.1)."
          },
          {
            "i18n": {
              "key": "a11y.alt.warning",
              "params": {
                "total": 207,
                "missing": 3
              }
            },
            "name": "Image Alt Text",
            "value": "3 of 207 images missing alt text",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add alt text to the remaining images (alt=\"\" for decorative ones).",
            "whyMatters": "Every image missing alt text is content a screen-reader user cannot access (WCAG 1.1.1 / EN 301 549 § 9.1.1.1)."
          },
          {
            "i18n": {
              "key": "a11y.forms.fail",
              "params": {
                "total": 8,
                "unlabeled": 8
              }
            },
            "name": "Form Labels",
            "value": "8 of 8 form inputs have no associated label",
            "status": "fail",
            "weight": 2,
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Accessibility audit — Inger →"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Associate every input with a <label for> (or aria-label / aria-labelledby). Placeholders are not labels.",
            "whyMatters": "Unlabelled fields leave screen-reader users guessing what to type — search, newsletter and checkout forms become unusable. EN 301 549 § 9.1.3.1 / 9.4.1.2 (WCAG 1.3.1 / 4.1.2)."
          },
          {
            "i18n": {
              "key": "a11y.headings.pass"
            },
            "name": "Heading Structure",
            "value": "Single <h1> with a consistent heading outline",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "a11y.links.pass"
            },
            "name": "Link Text",
            "value": "Links use descriptive text",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "confidence": "low"
          },
          {
            "i18n": {
              "key": "a11y.landmarks.pass"
            },
            "name": "Landmark Regions",
            "value": "Semantic landmarks present (<main>, <nav>/<header>)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "a11y.skiplink.missing"
            },
            "name": "Skip Link",
            "value": "No skip-to-content link detected",
            "status": "warning",
            "weight": 1,
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a visually-hidden \"Skip to content\" link as the first focusable element, targeting <main id=\"main\">.",
            "confidence": "low",
            "whyMatters": "Keyboard and screen-reader users otherwise tab through the whole menu on every page. EN 301 549 § 9.2.4.1 (WCAG 2.4.1)."
          },
          {
            "i18n": {
              "key": "a11y.legal-basis"
            },
            "name": "EAA Legal Basis",
            "value": "In scope for the European Accessibility Act (in force 28.6.2025): SK zákon 351/2022 Z. z., CZ zákon 424/2023 Sb., Dir. (EU) 2019/882 — assessed against EN 301 549. Inger provides EAA remediation audits.",
            "status": "info",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Accessibility audit — Inger →"
            },
            "howToFix": "",
            "isUpsell": true,
            "whyMatters": ""
          }
        ]
      },
      "vulnerability": {
        "score": 90,
        "checks": [
          {
            "i18n": {
              "key": "vuln.cms-version.pass"
            },
            "name": "CMS Version Disclosure",
            "value": "No generator tag — CMS identity hidden",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "vuln.sensitive-files.pass"
            },
            "name": "Sensitive Files Exposed",
            "value": ".env, .git, composer.json — all properly blocked",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "vuln.install-script.pass"
            },
            "name": "Install Script Exposed",
            "value": "No /install/ or /setup/ paths accessible",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "vuln.directory-listing.pass"
            },
            "name": "Directory Listing",
            "value": "Disabled — file structure hidden",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "vuln.admin-url.pass"
            },
            "name": "Admin Panel at Default URL",
            "value": "Not found at common paths (/admin, /wp-admin, /administrator, /backoffice)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "vuln.debug-mode.pass"
            },
            "name": "Debug Mode / Error Exposure",
            "value": "No debug indicators found in page output",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "vuln.cors.warning"
            },
            "name": "CORS Configuration",
            "value": "Access-Control-Allow-Origin: * (allows any domain)",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Replace the wildcard CORS header with specific allowed origins. Avoid Access-Control-Allow-Origin: * on pages with authentication or sensitive data.",
            "whyMatters": "A wildcard CORS policy allows any website to make requests to your API/pages. Combined with Access-Control-Allow-Credentials, this enables cross-origin data theft."
          },
          {
            "i18n": {
              "key": "vuln.csrf.fail",
              "params": {
                "count": 1
              }
            },
            "name": "Form CSRF Protection",
            "value": "1 form(s) without CSRF tokens",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add CSRF token validation to every form. Most CMS frameworks have built-in CSRF protection — make sure it's enabled on all forms, including search and newsletter signup.",
            "confidence": "low",
            "whyMatters": "CSRF is in the OWASP Top 10. Without tokens, attackers can craft pages that automatically submit forms on your site as the victim's browser session."
          },
          {
            "i18n": {
              "key": "vuln.spf.pass",
              "params": {
                "record": "v=spf1 -all"
              }
            },
            "name": "SPF Record (Email Security)",
            "value": "SPF configured: v=spf1 -all",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "i18n": {
              "key": "vuln.dmarc.pass",
              "params": {
                "policy": "reject"
              }
            },
            "name": "DMARC Policy (Email Auth)",
            "value": "DMARC enforced: p=reject",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "i18n": {
              "key": "vuln.email-infra.info"
            },
            "name": "Email Infrastructure",
            "value": "No MX records — domain does not receive email",
            "status": "info",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "i18n": {
              "key": "vuln.cross-origin.warning"
            },
            "name": "Cross-Origin Isolation",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Resource-Policy: same-origin headers. These protect against Spectre-type side-channel attacks.",
            "whyMatters": "Without cross-origin isolation headers, your site is vulnerable to Spectre attacks that can leak sensitive data across browser tabs. These headers are required for SharedArrayBuffer and high-resolution timers."
          },
          {
            "i18n": {
              "key": "vuln.payment-page.pass"
            },
            "name": "Payment Page Security",
            "value": "All essential security headers present on payment page",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          }
        ]
      },
      "executive_summary": {
        "en": "Your site performs well overall, but needs refinement in key areas. Priority: add meta descriptions to pages for better search visibility. Strength: your security standards are excellent.",
        "sk": "Váš web funguje solidne, ale má priestor na zlepšenie. Urgentne pridajte popis stránky v meta tagy pre lepšie výsledky vyhľadávania. Pozitívum: vaša bezpečnosť je výborná."
      },
      "opendata_security": null,
      "platform_evidence": [],
      "maintenance_bypass": false,
      "scanner_token_sent": false
    },
    "created_at": "2026-10-07T22:22:39.819586+00:00",
    "status": "complete",
    "platform_detected": null,
    "company_ico": null,
    "company_name": null,
    "company_country": null,
    "company_nace": null,
    "company_size": null,
    "nis2_scope": null,
    "nis2_sector": null,
    "company_risk_score": null,
    "company_risk_level": null
  }
}