{
  "data": {
    "slug": "f2adf42e",
    "url": "https://kelo.sk/",
    "domain": "kelo.sk",
    "overall_score": 64,
    "scores_json": {
      "seo": {
        "score": 64,
        "checks": [
          {
            "i18n": {
              "key": "seo.meta-title.warning-short",
              "params": {
                "chars": 7
              }
            },
            "name": "Meta Title",
            "value": "7 chars (optimal: 30-60)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your title is very short. Add descriptive keywords and your brand name for better ranking signals.",
            "whyMatters": "Short titles waste valuable ranking real estate in search results."
          },
          {
            "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.fail"
            },
            "name": "H1 Heading",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add exactly one H1 tag containing your primary keyword. It should be the most prominent heading on the page.",
            "whyMatters": "The H1 is a primary content signal for search engines. Pages without an H1 rank lower for target keywords."
          },
          {
            "i18n": {
              "key": "seo.h2.pass",
              "params": {
                "count": 10
              }
            },
            "name": "Content Structure (H2 Headings)",
            "value": "10 H2 subheadings found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.og.fail"
            },
            "name": "Open Graph Tags",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add og:title, og:description, og:image (1200×630px), and og:type meta tags to every page.",
            "whyMatters": "Without OG tags, social platforms show auto-generated previews. Proper OG tags produce clean, clickable link cards."
          },
          {
            "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.pass",
              "params": {
                "url": "https://kelo.sk/"
              }
            },
            "name": "Canonical URL",
            "value": "https://kelo.sk/",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.jsonld.fail"
            },
            "name": "Structured Data (JSON-LD)",
            "status": "fail",
            "fixLink": {
              "url": "https://zulien.sk",
              "label": "Add with Schema module →"
            },
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add JSON-LD structured data: Product (with price, availability, reviews), Organization, BreadcrumbList, and WebSite schemas.",
            "whyMatters": "Pages with structured data can earn rich snippets in Google — star ratings, prices, availability — which lift click-through."
          },
          {
            "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": 7
              }
            },
            "name": "XML Sitemap",
            "value": "Found with ~7+ URLs",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "seo.html-lang.pass",
              "params": {
                "lang": "sk-SK"
              }
            },
            "name": "HTML Language Attribute",
            "value": "lang=\"sk-SK\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.img-alt.pass",
              "params": {
                "rate": 100,
                "total": 29
              }
            },
            "name": "Image Alt Attributes",
            "value": "100% of 29 images have alt text",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.meta-robots.pass",
              "params": {
                "value": "max-image-preview:large"
              }
            },
            "name": "Meta Robots Tag",
            "value": "max-image-preview:large",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.text-ratio.info",
              "params": {
                "ratio": 2,
                "words": 665
              }
            },
            "name": "Text-to-HTML Ratio",
            "value": "2% ratio but 665 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.warning-partial",
              "params": {
                "rate": 14,
                "legacy": 10
              }
            },
            "name": "Image Format Optimization",
            "value": "Only 14% next-gen formats — 10 legacy images remain",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Convert remaining JPEG/PNG images to WebP (30-50% smaller) or AVIF (50-70% smaller). Use the <picture> element for browser fallback.",
            "whyMatters": "WebP/AVIF images are 30-70% smaller than JPEG/PNG at the same quality. This directly improves page speed, LCP, and mobile experience."
          },
          {
            "i18n": {
              "key": "seo.semantic.pass",
              "params": {
                "used": "<article>, <header>, <footer>, <aside>",
                "count": 4
              }
            },
            "name": "Semantic HTML Structure",
            "value": "4/6 semantic elements: <article>, <header>, <footer>, <aside>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.content-depth.pass",
              "params": {
                "words": 665
              }
            },
            "name": "Content Depth",
            "value": "665 words — sufficient content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.deep-heading.pass",
              "params": {
                "h2": 10,
                "h3": 17
              }
            },
            "name": "Deep Heading Hierarchy",
            "value": "H2: 10, H3: 17 — well-structured content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.internal-links.pass",
              "params": {
                "count": 19
              }
            },
            "name": "Internal Linking",
            "value": "19 internal links — strong site navigation",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.dead-links.warning",
              "params": {
                "hash": 8,
                "empty": 1,
                "total": 9,
                "jsvoid": 0
              }
            },
            "name": "Empty/Dead Links",
            "value": "9 dead links (1 empty, 8 hash-only, 0 javascript:void)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Replace empty href='', href='#', and href='javascript:void(0)' with actual URLs. If interactive, use <button> instead of <a>.",
            "whyMatters": "Dead links waste crawl budget and confuse search engines. They also create poor user experience — users click expecting navigation and nothing happens."
          },
          {
            "i18n": {
              "key": "seo.a11y.pass",
              "params": {
                "detail": "54 ARIA roles, 18 ARIA labels, lang=\"sk-SK\"",
                "signals": 3
              }
            },
            "name": "Accessibility Fundamentals",
            "value": "3/4 a11y signals: 54 ARIA roles, 18 ARIA labels, lang=\"sk-SK\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "seo.product-schema.warning",
              "params": {
                "missing": "brand, aggregateRating, review, gtin"
              }
            },
            "name": "Product Schema Richness",
            "value": "Missing recommended: brand, aggregateRating, review, gtin",
            "status": "warning",
            "evidence": {
              "source": "schema",
              "probedUrl": "https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny"
            },
            "howToFix": "Add brand, aggregateRating, review, gtin to your Product schema. These fields enable rich snippets with star ratings, price, availability, and brand in search results.",
            "confidence": "medium",
            "whyMatters": "Complete product schema enables rich snippets that lift organic click-through. Products with reviews/ratings in search results see meaningfully higher CTR."
          },
          {
            "i18n": {
              "key": "seo.excessive-resources.warning",
              "params": {
                "js": 37,
                "css": 19,
                "total": 56
              }
            },
            "name": "Excessive Resource Requests",
            "value": "37 JS + 19 CSS = 56 external requests",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Reduce to under 50 external resources by bundling JS/CSS files, removing unused plugins, and consolidating third-party scripts.",
            "whyMatters": "Google's crawl budget is limited. Sites with excessive resources get crawled less frequently and experience slower indexation of new content."
          }
        ]
      },
      "gdpr": {
        "score": 60,
        "checks": [
          {
            "i18n": {
              "key": "gdpr.cmp.fail"
            },
            "name": "Cookie Consent Banner (CMP)",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get GDPR Compliance →"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Install a certified consent management platform: Cookiebot, OneTrust, Usercentrics, or CookieYes. The CMP must block ALL non-essential cookies and scripts until explicit consent is given (opt-in, not opt-out).",
            "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"
                }
              ]
            },
            "whyMatters": "Since 2024, EU regulators actively enforce cookie consent. A non-compliant cookie banner is one of the most frequently fined GDPR offences."
          },
          {
            "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.pass",
              "params": {
                "url": "https://kelo.sk/zasady-osobnych-udajov-a-cookies"
              }
            },
            "name": "Privacy Policy Page",
            "value": "https://kelo.sk/zasady-osobnych-udajov-a-cookies",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "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"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.cookie-policy.pass"
            },
            "name": "Cookie Policy",
            "value": "Separate cookie policy detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "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"
                }
              ]
            }
          },
          {
            "i18n": {
              "key": "gdpr.imprint.pass",
              "params": {
                "url": "https://kelo.sk/o-nas"
              }
            },
            "name": "Legal Contact / Imprint Page",
            "value": "https://kelo.sk/o-nas",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "gdpr.terms.warning"
            },
            "name": "Terms & Conditions Page",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Create Terms & Conditions (AGB) covering: ordering process, payment, delivery, returns, warranty, and dispute resolution. Link it from the footer and checkout.",
            "whyMatters": "EU Consumer Rights Directive requires clear terms before purchase. Missing T&C means customers can claim they weren't informed, giving them extended cancellation rights."
          },
          {
            "i18n": {
              "key": "gdpr.mixed-content.warning"
            },
            "name": "Data Encryption (No Mixed Content)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Replace all http:// resource URLs with https://. Check images, scripts, stylesheets, and iframes. GDPR Article 32 requires 'appropriate technical measures' including encryption.",
            "whyMatters": "Mixed content means some data is transmitted unencrypted. This violates GDPR's data security requirements and triggers browser 'Not Secure' warnings that hurt conversions."
          },
          {
            "i18n": {
              "key": "gdpr.third-party.pass",
              "params": {
                "count": 1
              }
            },
            "name": "Third-party Data Sharing",
            "value": "1 third-party domain(s)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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.dpo.pass"
            },
            "name": "Data Protection Officer Contact",
            "value": "DPO / data protection contact found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "gdpr.withdrawal.warning"
            },
            "name": "Withdrawal of Consent Mechanism",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Provide a clear way to withdraw consent: an 'unsubscribe' link in emails, a 'cookie settings' button in the footer, and a 'revoke consent' section in your privacy policy.",
            "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"
                }
              ]
            },
            "whyMatters": "GDPR Article 7(3): 'It shall be as easy to withdraw as to give consent.' If users can subscribe in one click, unsubscribing must be equally simple. Missing this is a common regulatory finding."
          },
          {
            "i18n": {
              "key": "gdpr.dispute-resolution.fail"
            },
            "name": "Consumer Dispute Resolution Links",
            "value": "No EU ODR platform or supervisory-authority link found",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add the EU ODR platform link (https://ec.europa.eu/consumers/odr) and your national authority (SK: Slovenská obchodná inšpekcia / soi.sk, CZ: Česká obchodní inspekce / coi.cz) to the footer and Terms & Conditions.",
            "legalRefs": {
              "gdpr": [
                "Nariadenie (EÚ) 524/2013 (ODR)",
                "Smernica 2013/11/EÚ (ADR)"
              ],
              "czLaw": [
                "zák. 634/1992 Sb. § 14"
              ],
              "skLaw": [
                "zák. 391/2015 Z.z."
              ]
            },
            "whyMatters": "EU Regulation 524/2013 makes the ODR link mandatory for every online trader; national law requires naming the supervisory authority. ŠOI/ČOI inspect for exactly this, and its absence is a common consumer-law breach."
          },
          {
            "i18n": {
              "key": "gdpr.withdrawal-complaints.warning",
              "params": {
                "missing": "right of withdrawal (odstúpenie od zmluvy)"
              }
            },
            "name": "Withdrawal & Complaints Policy",
            "value": "Missing: right of withdrawal (odstúpenie od zmluvy)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Publish and footer-link a Withdrawal policy (14-day right of withdrawal + model withdrawal form) and a Complaints procedure (reklamačný poriadok / reklamační řád). Reference them at checkout.",
            "legalRefs": {
              "gdpr": [
                "Smernica 2011/83/EÚ čl. 6(1)(h),(9)"
              ],
              "czLaw": [
                "zák. 89/2012 Sb. § 1829"
              ],
              "skLaw": [
                "zák. 108/2024 Z.z."
              ]
            },
            "whyMatters": "The Consumer Rights Directive (2011/83/EU) and SK zák. 108/2024 / CZ zák. 89/2012 require pre-contractual disclosure of the 14-day withdrawal right and an accessible complaints procedure. Missing them extends customers' cancellation rights and is a standard ŠOI/ČOI finding."
          },
          {
            "i18n": {
              "key": "gdpr.withdrawal-function.warning"
            },
            "name": "Online Withdrawal Function",
            "value": "No online withdrawal function or withdrawal information detected",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a clearly labelled withdrawal function to your online interface (SK label: 'odstúpiť od zmluvy tu'), easy to find and continuously available during the 14-day withdrawal window — e.g. in the customer account / order detail plus a footer link. A logged-in customer must be able to submit a withdrawal declaration without re-identifying.",
            "confidence": "low",
            "whyMatters": "Directive (EU) 2023/2673 (amending 2011/83/EU), transposed in SK as § 20a zák. 108/2024, requires online traders to provide an easy-to-use withdrawal function — a clearly labelled button, continuously available during the withdrawal period — effective 19 June 2026 for all distance contracts with a right of withdrawal. Orientation only — verify placement manually."
          },
          {
            "i18n": {
              "key": "gdpr.gpsr-manufacturer.warning"
            },
            "name": "GPSR Manufacturer Info",
            "value": "No manufacturer/importer identification found on the sampled product page",
            "status": "warning",
            "evidence": {
              "sample": "",
              "source": "HTML-heuristic",
              "probedUrl": "https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny"
            },
            "howToFix": "On every product page state the manufacturer's name, postal address and an electronic contact (email or web form). For goods made outside the EU, also name the EU importer. Structured `manufacturer` in Product schema satisfies this cleanly and is machine-readable.",
            "confidence": "low",
            "whyMatters": "GPSR (Regulation (EU) 2023/988) has been enforceable since 13 December 2024 and requires the responsible economic operator to be identifiable on the offer. IMPORTANT: this is a text heuristic over ONE sampled product page — it is an orientation signal, not a legal assessment. Verify against your own catalogue before acting."
          }
        ]
      },
      "nis2": {
        "score": -1,
        "checks": [
          {
            "i18n": {
              "key": "nis2.scope.none"
            },
            "name": "NIS2 Compliance",
            "value": "Not in scope — your business is below NIS2 thresholds (Annex I/II sector + 50+ employees / €10M+ turnover).",
            "status": "info",
            "howToFix": "",
            "whyMatters": ""
          }
        ]
      },
      "mobile": {
        "score": 67,
        "checks": [
          {
            "i18n": {
              "key": "mob.viewport.pass"
            },
            "name": "Viewport Configuration",
            "value": "width=device-width, initial-scale=1",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.perf.warning",
              "params": {
                "score": 61
              }
            },
            "name": "Mobile Performance Score",
            "value": "61/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.pass",
              "params": {
                "techniques": "Flexbox, CSS Grid, Media queries"
              }
            },
            "name": "Responsive Design Techniques",
            "value": "Flexbox, CSS Grid, Media queries detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.pwa.warning"
            },
            "name": "PWA Features",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Consider adding Progressive Web App features: 1) Create manifest.json with app name, icons, and theme color, 2) Register a service worker for offline caching. This makes your store installable on mobile.",
            "whyMatters": "PWAs combine the best of web and native apps. For e-commerce, PWAs enable push notifications, offline browsing, and home screen access."
          },
          {
            "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.warning"
            },
            "name": "Mobile Navigation (Semantic)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Wrap your navigation in a <nav> element. This helps mobile screen readers offer 'skip to navigation' and improves voice navigation (e.g., 'Siri, show me the menu').",
            "whyMatters": "Semantic <nav> elements are essential for mobile accessibility. Screen readers use them to let users jump directly to navigation — critical on small screens where content is long."
          },
          {
            "i18n": {
              "key": "mob.srcset.pass",
              "params": {
                "count": 26
              }
            },
            "name": "Responsive Images (srcset)",
            "value": "26 image(s) use srcset for responsive sizing",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.apple.warning",
              "params": {
                "missing": "apple-mobile-web-app-capable, status-bar-style"
              }
            },
            "name": "Apple Mobile Web App",
            "value": "Missing: apple-mobile-web-app-capable, status-bar-style",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add: <meta name='apple-mobile-web-app-capable' content='yes'>, <meta name='apple-mobile-web-app-status-bar-style' content='default'>, <link rel='apple-touch-icon' href='/icon-180.png'>.",
            "whyMatters": "These tags enable 'Add to Home Screen' on iOS with a full-screen experience. A polished home screen presence increases return visits."
          },
          {
            "i18n": {
              "key": "mob.inputtypes.pass",
              "params": {
                "optimized": "4 search"
              }
            },
            "name": "Form Input Types",
            "value": "Optimized: 4 search",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.stickycta.warning"
            },
            "name": "Mobile Sticky CTA",
            "value": "Add-to-cart button found but no sticky/fixed positioning detected",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add a sticky add-to-cart bar at the bottom of mobile screens. Use position: sticky or position: fixed with bottom: 0. The CTA should always be visible without scrolling.",
            "whyMatters": "Mobile users scroll extensively. A sticky add-to-cart bar keeps the primary action visible. Without it, users must scroll back up to purchase — many won't."
          },
          {
            "i18n": {
              "key": "mob.print.warning"
            },
            "name": "Print Stylesheet",
            "value": "Order/invoice page without print styles",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add @media print CSS rules to hide navigation, ads, and non-essential elements. Ensure order details, prices, and company info are visible when printed.",
            "whyMatters": "Customers print order confirmations and invoices. Without print styles, they get navigation bars, cookie banners, and broken layouts. This is a common usability complaint for e-commerce."
          },
          {
            "i18n": {
              "key": "mob.payments.info"
            },
            "name": "Payment Methods Detected",
            "value": "Žiadna známa platobná brána nedetekovaná na homepage",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Payment gateway detection scanuje iba homepage. Ak sú platby na /checkout alebo sú načítané JS-om až po interakcii, neuvidíme ich. Zváž pridať platobné ikony do footer-u.",
            "whyMatters": "Viditeľné platobné ikony (Apple Pay, Google Pay, Klarna, Tatra Pay) v headeri/footeri zvyšujú conversion. Trust signal pred checkoutom."
          },
          {
            "i18n": {
              "key": "mob.express.info"
            },
            "name": "Express Checkout (Apple Pay + Google Pay)",
            "value": "Apple Pay / Google Pay nedetekované na homepage — express checkout sa zvyčajne zobrazí až v košíku/checkoute",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Ak express checkout nemáš, pridaj Apple Pay + Google Pay cez Stripe/Adyen/Mollie. Biometric auth = -1 click checkout = vyšší conversion.",
            "whyMatters": "Mobile conversion pri express checkout je vyšší oproti klasickej karte. V SK/CZ rastúci trend. (Sken vidí iba homepage, takže toto je hint, nie verdikt.)"
          },
          {
            "i18n": {
              "key": "mob.skczpay.info"
            },
            "name": "SK/CZ Local Payment Methods",
            "value": "Žiadna SK/CZ local payment metóda nedetekovaná na homepage — bankové tlačidlá/QR sa zvyčajne zobrazia až v checkoute",
            "status": "info",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Integrovať SK payments — Inger"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Ak SK/CZ local platby nemáš, integruj GoPay alebo ComGate — obe podporujú Tatra Pay, VÚB Pay, ČSOB Pay, Raiffeisen, QR platba v jednom API. Alternatívne Barion pre CZ trh.",
            "whyMatters": "SK/CZ shop bez bankových tlačidiel a QR platby = masívny cart abandonment. Priemerný SK e-shop má viacero payment metód. (Sken vidí iba homepage — over manuálne v checkoute.)"
          },
          {
            "i18n": {
              "key": "mob.wcaglabels.pass",
              "params": {
                "total": 4
              }
            },
            "name": "Form Input Labels (WCAG 3.3.2)",
            "value": "4/4 inputs majú label",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "mob.wcagheading.warning",
              "params": {
                "skips": "h2→h4, h2→h5"
              }
            },
            "name": "Heading Hierarchy (WCAG 1.3.1)",
            "value": "Preskočené úrovne: h2→h4, h2→h5",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Dodržuj poradie nadpisov h1 → h2 → h3 → h4 bez preskočenia. Screen readers používajú hierarchiu nadpisov na navigáciu. Ak potrebuješ menšie písmo ale rovnakú úroveň, použi CSS triedu, nie nižší heading tag.",
            "whyMatters": "Preskočené heading levely (napr. h1 priamo na h3) zlomia navigáciu pre screen reader používateľov a signalizujú Googlu zlú štruktúru dokumentu. Aj SEO je negatívne ovplyvnené."
          },
          {
            "i18n": {
              "key": "mob.wcaglinks.pass"
            },
            "name": "Link Text Quality (WCAG 2.4.4)",
            "value": "Všetky odkazy majú popisný text",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          }
        ]
      },
      "company": {
        "nis2": {
          "annex": null,
          "sector": null,
          "category": "none",
          "in_scope": false,
          "priority_tier": null,
          "priority_score": null
        },
        "financials": {
          "year": 2025,
          "equity": 18967,
          "profit": 7119,
          "turnover": 492885
        },
        "percentile": {
          "metrics": {
            "equity": 25,
            "turnover": 34,
            "net_profit": 31,
            "credit_limit": 30,
            "credit_score": 50,
            "total_assets": 40,
            "debt_to_equity": 2,
            "employee_count": 0
          },
          "nace_section": "M",
          "peer_group_size": 131170
        },
        "in_insolvency": false,
        "credit_grade_full": "A"
      },
      "modules": [
        "WooCommerce (woocommerce)",
        "Contact Form 7 (contact-form-7)",
        "conditional-payments",
        "ajax-search-for-woocommerce",
        "uncode-js_composer",
        "WooPayments (woocommerce-payments)",
        "Popup Maker (popup-maker)"
      ],
      "security": {
        "score": 59,
        "checks": [
          {
            "i18n": {
              "key": "sec.ssl.pass"
            },
            "name": "SSL/TLS Certificate",
            "value": "Valid HTTPS connection established",
            "status": "pass",
            "evidence": {
              "source": "SSL"
            }
          },
          {
            "i18n": {
              "key": "sec.dnssec.pass"
            },
            "name": "DNSSEC",
            "value": "Zone is DNSSEC-signed (DNSKEY published)",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            },
            "whyMatters": "DNSSEC protects against DNS cache poisoning and on-path attackers redirecting your domain. Required by some sector regulators for NIS2 essential/important entities."
          },
          {
            "i18n": {
              "key": "sec.caa.warning"
            },
            "name": "CAA DNS Record",
            "value": "No CAA records — any CA can issue certificates for this domain",
            "status": "warning",
            "evidence": {
              "source": "DNS"
            },
            "howToFix": "Publish CAA TXT records pinning your CA. For Let's Encrypt: `0 issue \"letsencrypt.org\"`. For multiple CAs add additional `0 issue \"...\"` records. Add `0 iodef \"mailto:security@yourdomain.tld\"` for misissuance reports.",
            "whyMatters": "CAA records limit which Certificate Authorities can issue certificates for your domain. Without CAA, a compromised or rogue CA can issue valid certs that browsers will trust — a documented breach pattern (DigiNotar 2011, Symantec 2017)."
          },
          {
            "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.fail"
            },
            "name": "HSTS (Strict-Transport-Security)",
            "status": "fail",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add header: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload — then submit to hstspreload.org.",
            "whyMatters": "Without HSTS, attackers can intercept the first HTTP request and downgrade the connection to steal session cookies on public WiFi."
          },
          {
            "i18n": {
              "key": "sec.csp.fail"
            },
            "name": "Content-Security-Policy (CSP)",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Security Hardening →"
            },
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Implement a CSP header. Start with: Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: — then gradually tighten.",
            "whyMatters": "CSP is a strong defense against XSS attacks. Without it, any injected script runs with full privileges. CSP blocks inline script injection."
          },
          {
            "i18n": {
              "key": "sec.clickjacking.fail"
            },
            "name": "Clickjacking Protection",
            "status": "fail",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add X-Frame-Options: DENY (or SAMEORIGIN if iframes are needed). Better: use CSP frame-ancestors 'self'.",
            "whyMatters": "Clickjacking overlays your site in a hidden iframe. Attackers trick users into clicking buttons (like 'Confirm Purchase') without knowing it."
          },
          {
            "i18n": {
              "key": "sec.x-content-type.warning"
            },
            "name": "X-Content-Type-Options",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Add header: X-Content-Type-Options: nosniff",
            "whyMatters": "Without nosniff, browsers may execute uploaded files as scripts. An attacker could upload a .jpg that's actually JavaScript and trick the browser into running it."
          },
          {
            "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.pass",
              "params": {
                "detail": "openresty"
              }
            },
            "name": "Technology Disclosure",
            "value": "Server: openresty (no version)",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "i18n": {
              "key": "sec.sri.pass-exempt"
            },
            "name": "Subresource Integrity (SRI)",
            "value": "All cross-origin scripts are auto-updating provider scripts where SRI does not apply",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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": "openresty"
              }
            },
            "name": "Server Version Disclosure",
            "value": "openresty — 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."
          }
        ]
      },
      "tech_stack": [
        {
          "eol": false,
          "name": "WordPress",
          "version": "7.0.2",
          "category": "cms",
          "outdated": false
        },
        {
          "name": "WooCommerce",
          "category": "cms"
        },
        {
          "name": "jQuery",
          "category": "js-library"
        },
        {
          "name": "Font Awesome",
          "category": "js-library"
        },
        {
          "name": "Owl Carousel",
          "category": "js-library"
        },
        {
          "name": "Video.js",
          "category": "js-library"
        },
        {
          "name": "reCAPTCHA",
          "category": "js-library"
        },
        {
          "name": "Vite",
          "category": "js-library"
        },
        {
          "name": "openresty",
          "category": "server"
        }
      ],
      "performance": {
        "score": 71,
        "checks": [
          {
            "i18n": {
              "key": "perf.ttfb.pass",
              "params": {
                "ms": 47
              }
            },
            "name": "Server Response Time (TTFB)",
            "value": "47ms",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.fcp.pass",
              "params": {
                "s": "0.79"
              }
            },
            "name": "First Contentful Paint (FCP)",
            "value": "0.79s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.lcp.pass",
              "params": {
                "s": "1.80"
              }
            },
            "name": "Largest Contentful Paint (LCP)",
            "value": "1.80s — Core Web Vital ✓",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.tbt.warning",
              "params": {
                "ms": 370
              }
            },
            "name": "Total Blocking Time (TBT)",
            "value": "370ms (good: <200ms)",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Reduce JavaScript execution: defer non-critical scripts, code-split large bundles, remove unused plugins. Third-party scripts (analytics, chat, ads) are often the biggest offenders.",
            "whyMatters": "TBT measures how long the main thread is blocked. During this time, clicks and taps don't respond — your store feels frozen. This directly impacts perceived quality."
          },
          {
            "i18n": {
              "key": "perf.cls.pass",
              "params": {
                "cls": "0.013"
              }
            },
            "name": "Cumulative Layout Shift (CLS)",
            "value": "0.013 — Core Web Vital ✓",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.speed-index.pass",
              "params": {
                "s": "1.65"
              }
            },
            "name": "Speed Index",
            "value": "1.65s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "i18n": {
              "key": "perf.page-weight.fail",
              "params": {
                "mb": "4.7",
                "requests": 80
              }
            },
            "name": "Total Page Weight",
            "value": "4.7 MB, 80 requests — too heavy!",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Performance Optimization →"
            },
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Critical: your page is over 3 MB. 1) Convert all images to WebP/AVIF, 2) Lazy load everything below the fold, 3) Remove unused plugins, 4) Combine and minify CSS/JS, 5) Enable brotli compression.",
            "whyMatters": "Pages over 3 MB take 12+ seconds on 3G. The average e-commerce page is around 2 MB — you're well above that. Even small latency increases measurably reduce sales."
          },
          {
            "i18n": {
              "key": "perf.js-budget.fail",
              "params": {
                "kb": 1414
              }
            },
            "name": "JavaScript Budget",
            "value": "1414 KB — more than double the 600 KB budget",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Performance Optimization →"
            },
            "evidence": {
              "source": "PSI-lab",
              "measured": "1414 KB JavaScript"
            },
            "howToFix": "Audit what ships on a product page: split the bundle by route, defer every third-party tag until interaction or consent, and remove plugins whose bundle you cannot account for. Measure again after each removal.",
            "confidence": "high",
            "whyMatters": "Above 1 200 KB the parse and execute cost alone stalls mid-range phones for seconds before anything is interactive. For reference, the best shop in our benchmark ships 410 KB and won its award on mobile experience."
          },
          {
            "i18n": {
              "key": "perf.request-budget.pass",
              "params": {
                "count": 80
              }
            },
            "name": "Request Budget",
            "value": "80 requests — within the budget of 80",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab",
              "measured": "80 requests"
            },
            "confidence": "high",
            "whyMatters": "Every request costs a round trip. Under HTTP/2 they share a connection, but each still has to be discovered, queued and parsed."
          },
          {
            "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": 897
              }
            },
            "name": "Unused Code (CSS + JS)",
            "value": "897 KB wasted on unused code!",
            "status": "fail",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "You're loading 897 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": 14,
                "rate": 48,
                "total": 29
              }
            },
            "name": "Lazy Loading",
            "value": "48% of images use native lazy loading (14/29)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "perf.font-display.google-fonts"
            },
            "name": "Font Loading Strategy",
            "value": "Google Fonts detected without font-display",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add &display=swap to your Google Fonts URL, or add font-display: swap to your @font-face declarations.",
            "whyMatters": "Without font-display, custom fonts cause Flash of Invisible Text (FOIT) — text is completely hidden during font download. On slow connections this can last 3+ seconds."
          },
          {
            "i18n": {
              "key": "perf.cache-control.warning",
              "params": {
                "header": "max-age=0, no-cache, no-store, must-revalidate"
              }
            },
            "name": "Cache-Control Strategy",
            "value": "max-age=0, no-cache, no-store, must-revalidate",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Set appropriate cache headers: static assets should have max-age=31536000 with versioned filenames. HTML pages can use max-age=0 with ETag for revalidation.",
            "whyMatters": "no-cache/no-store forces browsers to re-download resources on every visit. Repeat visitors load your entire site from scratch every time."
          },
          {
            "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.fail",
              "params": {
                "rate": 24,
                "total": 37,
                "blocking": 28
              }
            },
            "name": "Script Loading Strategy",
            "value": "Only 24% of 37 scripts optimized — most are render-blocking",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Performance Optimization →"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add defer or async to all <script src='...'> tags. Render-blocking scripts are a leading cause of slow FCP. Defer maintains execution order, async does not.",
            "whyMatters": "28 render-blocking scripts can add 1-3 seconds to page load. Each synchronous script creates a sequential download-parse-execute chain."
          },
          {
            "i18n": {
              "key": "perf.css-count.fail",
              "params": {
                "count": 19
              }
            },
            "name": "CSS File Count",
            "value": "19 CSS files — too many!",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Bundle your CSS files into 1-3 files maximum. Use a build tool (Webpack, Vite, Gulp) to concatenate and minify. Critical CSS should be inlined, the rest deferred.",
            "whyMatters": "Each CSS file blocks rendering. With 19 files, the browser must download all of them before painting anything. This can add 1-2+ seconds on mobile networks."
          },
          {
            "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."
          },
          {
            "i18n": {
              "key": "perf.critical-css.warning",
              "params": {
                "count": 19
              }
            },
            "name": "Critical CSS Strategy",
            "value": "19 CSS files without critical CSS extraction",
            "status": "warning",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Extract critical above-the-fold CSS and inline it in <head>. Load remaining CSS asynchronously: <link rel='preload' href='styles.css' as='style' onload='this.rel=\"stylesheet\"'>.",
            "whyMatters": "Render-blocking CSS delays first paint. Inlining critical CSS eliminates the render-blocking round trip — the biggest FCP improvement for CSS-heavy sites."
          }
        ]
      },
      "ai_readiness": {
        "score": 49,
        "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.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": "2.2",
                "words": 665
              }
            },
            "name": "Content Accessibility for AI",
            "value": "665 words in raw HTML (2.2% text ratio) — readable by AI crawlers without executing JS",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.schema-foundation.fail"
            },
            "name": "Structured Data Foundation",
            "status": "fail",
            "fixLink": {
              "url": "https://zulien.sk",
              "label": "Add structured data →"
            },
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add JSON-LD structured data immediately. Priority order: 1) Organization, 2) Product (with offers), 3) BreadcrumbList, 4) WebSite+SearchAction, 5) FAQPage. Use JSON-LD format exclusively — not Microdata or RDFa.",
            "whyMatters": "Without structured data, your store is invisible to AI commerce. Google AI Overviews, ChatGPT Shopping, Perplexity, and Bing Copilot all rely on schema markup to understand and recommend products."
          },
          {
            "i18n": {
              "key": "air.product-schema.warning",
              "params": {
                "pct": 71,
                "missing": "brand, aggregateRating, itemCondition, gtin/mpn"
              }
            },
            "name": "Product Schema Completeness",
            "value": "71% complete — missing: brand, aggregateRating, itemCondition, gtin/mpn (sampled product page: https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny)",
            "status": "warning",
            "evidence": {
              "source": "schema",
              "probedUrl": "https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny"
            },
            "howToFix": "Add missing Product schema fields: brand, aggregateRating, itemCondition, gtin/mpn. Each field improves how AI presents your products. Especially add aggregateRating, since products with ratings show more prominently in AI shopping results.",
            "confidence": "medium",
            "whyMatters": "Incomplete Product schema means AI shows partial product info. Google Shopping and AI assistants skip products missing price, availability, or images — your competitors with complete schemas win."
          },
          {
            "i18n": {
              "key": "air.variant-modelling.info"
            },
            "name": "Variant Modelling (ProductGroup)",
            "value": "Variant selectors visible on the page — check whether variants are modelled as a ProductGroup",
            "status": "info",
            "evidence": {
              "source": "schema",
              "probedUrl": "https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny"
            },
            "howToFix": "If this product has real variants (size, colour), express them as ProductGroup + hasVariant + variesBy rather than one flat Product.",
            "confidence": "medium",
            "whyMatters": "ProductGroup keeps ratings and pricing consolidated on one product entity, which is how AI shopping surfaces compare products."
          },
          {
            "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.breadcrumb.warning"
            },
            "name": "Breadcrumb Schema",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add BreadcrumbList schema reflecting your category hierarchy: Home → Category → Subcategory → Product. Each item needs name and URL.",
            "whyMatters": "AI assistants use breadcrumbs to understand product categorization and site structure. Without it, AI can't contextualize where products fit in your catalog — e.g., 'Running Shoes' under 'Sports > Footwear > Running'."
          },
          {
            "i18n": {
              "key": "air.sitesearch.warning"
            },
            "name": "Site Search Schema (SearchAction)",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add WebSite schema with potentialAction: SearchAction. Define your search URL template so AI assistants and Google can search your store programmatically.",
            "whyMatters": "SearchAction enables Google's sitelinks search box and allows AI shopping assistants to search your catalog directly. It's how AI agents find specific products in your store."
          },
          {
            "i18n": {
              "key": "air.content-depth.pass",
              "params": {
                "words": 665
              }
            },
            "name": "Content Depth for AI",
            "value": "665 words — rich content for AI analysis and citation",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.answer-first.warning"
            },
            "name": "Answer-First Content Format",
            "value": "Content doesn't start with a strong summary paragraph",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Place your most important information in the first 100 words of the page. Use the BLUF method (Bottom Line Up Front): start with what the product IS and why it matters, then elaborate.",
            "whyMatters": "AI assistants extract content from the first 100 words to generate summaries. Most AI systems read top-down, so answer-first pages get cited more often."
          },
          {
            "i18n": {
              "key": "air.headings.fail",
              "params": {
                "h1": 0,
                "h2": 10,
                "h3": 17
              }
            },
            "name": "Heading Hierarchy for AI",
            "value": "0 H1, 10 H2, 17 H3 — poor structure",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Use exactly 1 H1 (page title), then organize content with H2 sections and H3 subsections. Each heading should describe the content that follows. Never skip heading levels (H1→H3 without H2).",
            "whyMatters": "AI extracts information based on heading structure. Pages with proper H1→H2→H3 hierarchy are parsed more accurately by ChatGPT, Perplexity, and Google AI Overviews. Without it, AI may misinterpret your content."
          },
          {
            "i18n": {
              "key": "air.semantic-html.pass",
              "params": {
                "count": 4,
                "elements": "<article>, <header>, <footer>, <aside>"
              }
            },
            "name": "Semantic HTML Structure",
            "value": "4/6 semantic elements: <article>, <header>, <footer>, <aside>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.structured-content.pass",
              "params": {
                "lists": 10,
                "tables": 10
              }
            },
            "name": "Structured Content (Lists & Tables)",
            "value": "10 lists + 10 tables — AI-friendly structured content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.freshness.fail"
            },
            "name": "Content Freshness Signals",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add dateModified and datePublished to your JSON-LD schema, and display a visible 'Last updated' date on the page. Update content quarterly at minimum. AI heavily favors fresh, maintained content.",
            "whyMatters": "With no freshness signals, AI assumes your content is stale. ChatGPT and Perplexity both weight recency in their citation algorithms. Competitors who show recent updates will be cited instead of your static pages."
          },
          {
            "i18n": {
              "key": "air.entity-clarity.fail"
            },
            "name": "Entity Clarity & Brand Signals",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your brand has weak entity signals. Add: 1) Complete OG meta tags, 2) Organization schema with sameAs linking to all official profiles, 3) Consistent NAP (Name, Address, Phone) across the web.",
            "whyMatters": "AI assistants must be confident about entity identity before making recommendations. Without clear brand signals, AI defaults to better-known competitors."
          },
          {
            "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.info",
              "params": {
                "pageType": "homepage"
              }
            },
            "name": "Reviews & Ratings Schema",
            "value": "No review schema on this homepage — review/rating schema typically lives on product pages",
            "status": "info",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Scan a product URL to audit review schema. On product pages add AggregateRating (ratingValue, reviewCount, bestRating) and individual Review schemas.",
            "whyMatters": "Review schema is product-page-specific, so its absence here is expected, not a defect."
          },
          {
            "i18n": {
              "key": "air.ai-plugin.warning"
            },
            "name": "AI Plugin Manifest",
            "value": "Not present — not required (the ChatGPT-plugins manifest was retired in 2024)",
            "status": "info",
            "evidence": {
              "source": "file-probe"
            },
            "whyMatters": "ai-plugin.json belonged to the retired ChatGPT-plugins system. Modern agent integration uses MCP / tool APIs — see the WebMCP / Agent-Commerce Readiness signals instead."
          },
          {
            "i18n": {
              "key": "air.product-feed.warning"
            },
            "name": "Product Feed (AI Commerce)",
            "status": "warning",
            "fixLink": {
              "url": "https://audit.mergado.com/",
              "label": "Free feed audit — Mergado"
            },
            "evidence": {
              "sample": "probed /feed/products.xml, /google-shopping.xml, /export/google-shopping.xml — none returned a product feed",
              "source": "file-probe"
            },
            "howToFix": "Create a Google Merchant Center / product feed (XML or CSV). Expose it at a consistent URL and reference it in your sitemap. AI shopping assistants and comparison engines use product feeds for catalog discovery. Tip: validate your Heureka / Zboží / Glami / Merchant feeds for free with Mergado's audit.",
            "whyMatters": "Product feeds power Google Shopping, Bing Shopping, and increasingly AI commerce. Without a structured product feed, AI agents can't efficiently index your full catalog for product recommendations."
          },
          {
            "i18n": {
              "key": "air.gtin-coverage.info-nofeed"
            },
            "name": "GTIN/EAN Coverage",
            "value": "No product feed was sampled — GTIN/EAN coverage could not be verified",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Publish a Google Merchant or Heureka product feed with GTIN/EAN populated, then re-scan to measure coverage.",
            "whyMatters": "GTIN is how an AI shopping agent matches your product to the same product in other shops. Without a feed we cannot measure it — this is not a finding against you."
          },
          {
            "i18n": {
              "key": "air.heureka-feed.warning-missing"
            },
            "name": "Heureka XML Feed",
            "status": "warning",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Setup Heureka Feed — Inger"
            },
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Vygeneruj Heureka XML feed na /feed/heureka.xml (alebo /export/heureka.xml). PrestaShop má modul Heureka.cz, WooCommerce má pluginy. Štruktúra: <SHOP><SHOPITEM>...</SHOPITEM></SHOP> s ITEM_ID/PRODUCTNAME/URL/PRICE_VAT/CATEGORYTEXT (povinné) + EAN/PARAM/DELIVERY_DATE (highly recommended pre ranking).",
            "whyMatters": "Heureka.sk a Heureka.cz sú dominantné cenové porovnávače na SK/CZ trhu. Bez XML feedu nie ste viditeľní na hlavnom trhovisku. Žiaden generický audit tool toto nekontroluje."
          },
          {
            "i18n": {
              "key": "air.speakable.warning"
            },
            "name": "Speakable Content (Voice AI)",
            "value": "Not present — optional; SpeakableSpecification has limited assistant adoption",
            "status": "info",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.extractable.warning-short",
              "params": {
                "avg": 6,
                "count": 3
              }
            },
            "name": "Extractable Answer Blocks",
            "value": "3 paragraphs, avg 6 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.warning-none"
            },
            "name": "Statistics & Data Presence",
            "value": "No statistical data found in content",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add numbers: pricing comparisons, performance metrics, customer statistics, industry benchmarks. Specific data (e.g., '99.9% uptime', '4.8/5 rating from 2,400 reviews') is what AI quotes most.",
            "whyMatters": "Content without data is harder to cite. Perplexity and ChatGPT specifically seek pages with quantified claims and verifiable statistics."
          },
          {
            "i18n": {
              "key": "air.section-length.warning",
              "params": {
                "avg": 101,
                "ratio": 0
              }
            },
            "name": "Section Length Optimization",
            "value": "Avg section: 101 words — only 0% 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-none"
            },
            "name": "Q&A Format Headings",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add H2/H3 headings phrased as questions your customers ask: 'How much does shipping cost?', 'What sizes are available?', 'How do I return an item?' Follow each with a direct, concise answer.",
            "whyMatters": "Q&A content format matches how people query AI assistants. Without question-format headings, your content is harder for AI to map to user queries."
          },
          {
            "i18n": {
              "key": "air.question-coverage.fail",
              "params": {
                "n": 1,
                "labels": ": shipping"
              }
            },
            "name": "Common Question Coverage",
            "value": "Answers only 1/5 key shopper questions: shipping",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your page barely addresses core shopper questions. Add sections covering price, shipping (options + cost), returns/refunds, availability, and payment methods — as visible text, not just in schema. Link to a dedicated FAQ, Shipping, and Returns page.",
            "whyMatters": "AI assistants answer shopping queries by fanning out into price/shipping/returns/availability/payment sub-questions. A page that answers none of them is invisible in AI shopping answers and reads as untrustworthy to buyers."
          },
          {
            "i18n": {
              "key": "air.internal-links.pass",
              "params": {
                "rate": 29
              }
            },
            "name": "Internal Link Density",
            "value": "29 contextual internal links per 1,000 words — strong knowledge graph signal",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.canonical.pass"
            },
            "name": "Canonical Tag for AI Deduplication",
            "value": "Self-referencing canonical — clean signal for AI",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.return-policy.warning"
            },
            "name": "Return Policy Schema",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add MerchantReturnPolicy schema with: returnPolicyCategory (e.g., MerchantReturnFiniteReturnWindow), merchantReturnDays, returnMethod, returnFees. Link it from Product/Offer via hasMerchantReturnPolicy.",
            "whyMatters": "AI shopping agents (Google Shopping, ChatGPT, Bing Copilot) filter by return flexibility. Products with return policy schema get priority placement in AI product comparisons."
          },
          {
            "i18n": {
              "key": "air.delivery-promise.info"
            },
            "name": "Delivery Promise",
            "value": "No delivery timing was found in the text of the sampled product page",
            "status": "info",
            "evidence": {
              "sample": "",
              "source": "HTML-heuristic",
              "probedUrl": "https://kelo.sk/produkt/damsky-unisuit-x-tmavozeleny"
            },
            "howToFix": "Show expected delivery on the product page itself, not only in the shipping-terms page: a weekday or date plus the order cut-off time.",
            "confidence": "low",
            "whyMatters": "Customers decide at the product page. Timing that only lives in a terms page is not part of that decision. Note: this reads page text, so unusual phrasing can be missed — verify before acting."
          },
          {
            "i18n": {
              "key": "air.shipping-schema.warning"
            },
            "name": "Shipping Details Schema",
            "status": "warning",
            "evidence": {
              "source": "schema"
            },
            "howToFix": "Add OfferShippingDetails schema with: shippingRate, shippingDestination, deliveryTime (handlingTime + transitTime). AI agents deprioritize products without shipping info.",
            "whyMatters": "Fulfillment speed factors into AI product recommendations. Complete shipping schema means AI can show 'Free shipping, delivers in 2-3 days' — a strong conversion driver."
          },
          {
            "i18n": {
              "key": "air.kg-readiness.fail"
            },
            "name": "Knowledge Graph Readiness",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Build your Knowledge Graph entity: 1) Add @id to Organization JSON-LD, 2) Use identical brand name in title, schema, and OG, 3) Add sameAs to Wikipedia/Wikidata/LinkedIn, 4) Use multiple corroborating schema types.",
            "whyMatters": "Without Knowledge Graph signals, AI treats your brand as unverified. You won't get a Google Knowledge Panel, and AI assistants can't confidently attribute information to your brand."
          },
          {
            "i18n": {
              "key": "air.readability.pass-technical",
              "params": {
                "grade": 8
              }
            },
            "name": "Content Readability for AI",
            "value": "Flesch-Kincaid Grade 8 — appropriate for technical/B2B audience",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "i18n": {
              "key": "air.alt-text.fail",
              "params": {
                "pct": 0,
                "poor": 2,
                "missing": 0
              }
            },
            "name": "Image Alt Text Quality for AI",
            "value": "Only 0% quality alt text — 0 missing, 2 poor",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Audit all images: add descriptive alt text (3-15 words) to every <img>. Include product names, features, materials, colors. This is critical for visual AI search and accessibility compliance.",
            "whyMatters": "Poor alt text means your product images are invisible to AI visual search (Google Lens, Bing Visual Search). This is also an accessibility requirement (WCAG 2.1 AA) — many regions enforce this legally."
          },
          {
            "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.fail",
              "params": {
                "ratio": 20
              }
            },
            "name": "Content-to-Boilerplate Ratio",
            "value": "Only 20% in main content — mostly boilerplate",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Wrap your primary content in <main> or <article> tags. AI extracts content from these semantic containers — without them, your product descriptions are mixed with navigation and footer text.",
            "whyMatters": "Token density measures useful content vs noise. Pages with under 30% content ratio are hard for AI to parse — it can't find your content in the boilerplate."
          },
          {
            "i18n": {
              "key": "air.trust-widget.warning"
            },
            "name": "Trust Widget",
            "value": "Žiaden trust widget (Heureka / Trustpilot / AggregateRating) nedetekovaný",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Pre SK/CZ shopy: inštaluj Heureka Ověřeno zákazníky widget (zadarmo pre overených predajcov — https://sluzby.heureka.sk). Alternatívne: Trustpilot, Google Reviews s AggregateRating schema. Trust widget na product + kategória + footer.",
            "whyMatters": "SK/CZ kupujúci majú vyššiu dôveru k Heureka Ověřeno ako k iným trust signálom. LLM-y (ChatGPT, Perplexity) a Google SGE citujú shopy s AggregateRating schema prednostne."
          },
          {
            "name": "Agent-Commerce Readiness",
            "value": "54/100 — čiastočne pripravené (Prístup 100 · Porozumenie 17 · Objaviteľnosť 50 · Transakcia 50)",
            "status": "info",
            "whyMatters": "Či dokáže autonómny nákupný AI agent (ChatGPT operator, Perplexity, budúce agentické asistenty) na vašom obchode: prísť dnu, prečítať a porozumieť produktom, objaviť celý katalóg a konať (kôš, podmienky). Toto meria málokto — a pre SK/CZ shopy nikto. Skóre spája AI-bot prístup, Product schema, produktové feedy (Merchant/Heureka/Zboží), WebMCP a nákupné podmienky do jedného agent-first pohľadu. Nadväzuje na pripravovaný verejný MCP konektor (\"naskenuj tento obchod\")."
          },
          {
            "name": "Agent: Prístup — dostane sa agent dnu",
            "value": "100/100 (2 signály/-ov)",
            "status": "info"
          },
          {
            "name": "Agent: Porozumenie — rozumie produktom",
            "value": "17/100 (3 signály/-ov)",
            "status": "info"
          },
          {
            "name": "Agent: Objaviteľnosť — nájde celý katalóg",
            "value": "50/100 (3 signály/-ov)",
            "status": "info"
          },
          {
            "name": "Agent: Transakcia — vie konať (kôš/podmienky)",
            "value": "50/100 (3 signály/-ov)",
            "status": "info"
          }
        ]
      },
      "phaseTimings": {
        "tail": 746,
        "total": 5412,
        "phase1": 4323,
        "preflight": 146,
        "phase1.dns": 280,
        "phase1.html": 170,
        "phase1.files": 4321,
        "phase1.zbozi": 3375,
        "phase1.headers": 907,
        "phase1.heureka": 2569,
        "phase1.merchant": 3390
      },
      "accessibility": {
        "score": -1,
        "checks": [
          {
            "i18n": {
              "key": "a11y.scope.micro-exempt"
            },
            "name": "EAA Scope",
            "value": "Not legally required yet — the European Accessibility Act (SK 351/2022 Z. z. § 2 ods. 3, CZ 424/2023 Sb., Dir. 2019/882) exempts micro-enterprises (< 10 staff & ≤ €2M). Your registry data indicates a micro-enterprise, so accessibility is optional for now — but it still lifts SEO, conversions, and reaches the ~15% of shoppers with a disability.",
            "status": "info",
            "howToFix": "",
            "whyMatters": ""
          }
        ]
      },
      "vulnerability": {
        "score": 70,
        "checks": [
          {
            "i18n": {
              "key": "vuln.cms-version.fail",
              "params": {
                "generator": "WordPress 7.0.2"
              }
            },
            "name": "CMS Version Disclosure",
            "value": "\"WordPress 7.0.2\" exposed in meta generator",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Security Hardening →"
            },
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Remove the meta generator tag entirely. In PrestaShop: remove from header.tpl. In WordPress: add remove_action('wp_head', 'wp_generator') to functions.php.",
            "whyMatters": "Knowing your exact CMS version lets attackers search CVE databases instantly. E.g., PrestaShop 1.7.8.x is associated with known SQL injection CVEs. Hiding the version forces attackers to guess."
          },
          {
            "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.cms-info-files.warning",
              "params": {
                "filesAnd": "readme.html",
                "filesList": "readme.html"
              }
            },
            "name": "CMS Information Files",
            "value": "readme.html accessible — reveals version details",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Delete or block access to readme.html. These files reveal your exact CMS version and update history.",
            "whyMatters": "Even if you hide the generator tag, readme.html and CHANGELOG.txt reveal exact version numbers. Attackers check these as a fallback."
          },
          {
            "i18n": {
              "key": "vuln.csrf.fail",
              "params": {
                "count": 4
              }
            },
            "name": "Form CSRF Protection",
            "value": "4 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.open-redirect.warning"
            },
            "name": "Open Redirect Detection",
            "value": "URL redirect parameter found in page links",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Validate all redirect URLs server-side against a whitelist. Never allow user-controlled redirect targets without validation.",
            "confidence": "low",
            "whyMatters": "Open redirects are used in phishing attacks — attackers craft URLs that appear to be your domain but redirect to a malicious site. This abuses your domain's trust."
          },
          {
            "i18n": {
              "key": "vuln.magecart.fail",
              "params": {
                "patterns": "Dynamic script injection"
              }
            },
            "name": "Suspicious Inline Script Patterns",
            "value": "Detected: Dynamic script injection",
            "status": "fail",
            "fixLink": {
              "url": "https://www.inger.sk/#contact",
              "label": "Get Malware Scan →"
            },
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Review all inline scripts for obfuscated code. Magecart attackers inject payment skimmers disguised as analytics or GTM scripts. Compare your current HTML with a known-good version. Consider using CSP with strict nonces.",
            "whyMatters": "These patterns (Base64 decode, eval with encoding, dynamic script injection) are hallmarks of Magecart payment skimmers. Skimmers are commonly disguised as Google Tag Manager on e-commerce sites."
          },
          {
            "i18n": {
              "key": "vuln.wp-user-enum.warning"
            },
            "name": "WordPress User Enumeration",
            "value": "/wp-json/wp/v2/users exposes user accounts",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Restrict the REST API users endpoint. Add to functions.php: add_filter('rest_endpoints', function($endpoints) { unset($endpoints['/wp/v2/users']); return $endpoints; }); Or use a security plugin.",
            "whyMatters": "Exposed usernames are the first step in brute force attacks. Attackers get valid usernames, then target them with password attacks. Combined with xmlrpc.php, this is a common WordPress attack chain."
          },
          {
            "i18n": {
              "key": "vuln.spf.pass",
              "params": {
                "record": "v=spf1 a mx include:_spf.m1.websupport.sk -all"
              }
            },
            "name": "SPF Record (Email Security)",
            "value": "SPF configured: v=spf1 a mx include:_spf.m1.websupport.sk -all",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "i18n": {
              "key": "vuln.dmarc.pass",
              "params": {
                "policy": "quarantine"
              }
            },
            "name": "DMARC Policy (Email Auth)",
            "value": "DMARC enforced: p=quarantine",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "i18n": {
              "key": "vuln.dkim.pass",
              "params": {
                "selectors": "selector1, selector2, mail"
              }
            },
            "name": "DKIM Signing (Email Auth)",
            "value": "DKIM configured (selectors: selector1, selector2, mail)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "i18n": {
              "key": "vuln.bimi.info"
            },
            "name": "BIMI Brand Indicators",
            "status": "info",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Once DMARC is set to p=quarantine or p=reject with 100% enforcement, publish a BIMI record: v=BIMI1; l=https://yourdomain.com/logo.svg — adds your brand logo to recipient inboxes in Gmail and Yahoo.",
            "whyMatters": "BIMI requires a VMC (Verified Mark Certificate) but adds your brand logo to recipient inboxes as a trust signal. Optional but high-impact for brand-focused shops."
          },
          {
            "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.mixed-content.warning",
              "params": {
                "urls": "http://gmpg.org/xfn/11",
                "count": 1
              }
            },
            "name": "Mixed Content Resources",
            "value": "1 HTTP resource(s) on HTTPS page",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Replace HTTP URLs with HTTPS: http://gmpg.org/xfn/11",
            "whyMatters": "Mixed content allows man-in-the-middle attacks on specific resources. Browsers increasingly block mixed content, breaking images and scripts on your site."
          }
        ]
      },
      "executive_summary": {
        "en": "Your store works but has significant room for improvement. Start by adding meta descriptions and H1 headings to all product pages—they're essential for search engines and customers. Your security foundation is solid and your server setup is functional.",
        "sk": "Váš obchod funguje, ale má veľký priestor na zlepšenie. Okamžite pridajte meta popisy a H1 nadpisy na všetky produktové stránky — sú dôležité pre vyhľadávače a kupujúcich. Vaša bezpečnosť je na dobrej úrovni a serverová konfigurácia je funkcná."
      },
      "opendata_security": null
    },
    "created_at": "2026-08-03T19:06:03.585381+00:00",
    "status": "complete",
    "platform_detected": "WooCommerce (WP 7.0.2)",
    "company_ico": "46290036",
    "company_name": "jachta.sk s.r.o.",
    "company_country": "SK",
    "company_nace": "7020",
    "company_size": "micro",
    "nis2_scope": "none",
    "nis2_sector": null,
    "company_risk_score": 25,
    "company_risk_level": "low"
  }
}