{
  "data": {
    "slug": "55908041",
    "url": "https://bidfood.sk",
    "domain": "bidfood.sk",
    "overall_score": 71,
    "scores_json": {
      "seo": {
        "score": 70,
        "checks": [
          {
            "name": "Meta Title",
            "value": "40 chars — \"Bidfood | Výrobca a distribútor potravín\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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. Custom descriptions can boost CTR by 5.8% (Backlinko study)."
          },
          {
            "name": "H1 Heading",
            "value": "\"Váš výrobca a distribútor potravín\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Content Structure (H2 Headings)",
            "value": "10 H2 subheadings found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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 ugly auto-generated previews. Proper OG tags increase social engagement by 2-3x."
          },
          {
            "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."
          },
          {
            "name": "Canonical URL",
            "value": "https://www.bidfood.sk/",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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 get rich snippets in Google — star ratings, prices, availability — increasing CTR by 20-30%."
          },
          {
            "name": "robots.txt",
            "value": "Present, references sitemap",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "XML Sitemap",
            "value": "Found with ~274+ URLs",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "HTML Language Attribute",
            "value": "lang=\"sk\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Hreflang Tags (Multilingual)",
            "value": "7 language(s): cs, sk, hu, de, en",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Image Alt Attributes",
            "value": "Only 87% of 54 images have alt text",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "7 images are missing alt attributes. Add descriptive, keyword-rich alt text to every image.",
            "whyMatters": "Missing alt text means zero visibility in Google Image Search (which drives 20%+ of total search traffic for e-commerce)."
          },
          {
            "name": "Text-to-HTML Ratio",
            "value": "2% — very thin content (422 words)",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your page is almost entirely HTML/CSS/JS with very little actual content. Add substantial product descriptions, content blocks, and informational text.",
            "whyMatters": "Google's Helpful Content Update specifically targets thin content pages. This significantly hurts your rankings."
          },
          {
            "name": "Favicon",
            "value": "Favicon detected",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "Image Format Optimization",
            "value": "Only 39% next-gen formats — 0 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 <picture> element for browser fallback.",
            "whyMatters": "WebP/AVIF images are 30-70% smaller than JPEG/PNG with the same quality. This directly improves page speed, LCP, and mobile experience."
          },
          {
            "name": "Semantic HTML Structure",
            "value": "5/6 semantic elements: <article>, <nav>, <main>, <header>, <footer>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Canonical URL Consistency",
            "value": "Canonical points to different URL: https://www.bidfood.sk/",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Your canonical URL doesn't match the current page URL. Ensure the canonical points to the preferred version (with or without trailing slash, www vs non-www). Inconsistent canonicals confuse search engines.",
            "whyMatters": "A mismatched canonical tells Google this page is a duplicate of another URL. If unintentional, Google may ignore this page entirely in favor of the canonical target."
          },
          {
            "name": "Content Depth",
            "value": "422 words — sufficient content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Deep Heading Hierarchy",
            "value": "H2: 10, H3: 8 — well-structured content",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Internal Linking",
            "value": "69 internal links — strong site navigation",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Empty/Dead Links",
            "value": "1 minor dead link(s) — acceptable",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Accessibility Fundamentals",
            "value": "4/4 a11y signals: 13 ARIA roles, 13 ARIA labels, skip link, lang=\"sk\"",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Image Dimension Attributes",
            "value": "Only 41% of images have width/height attributes",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add width and height attributes to all <img> tags. This prevents layout shifts (CLS) and helps browsers allocate space before images load.",
            "whyMatters": "Missing image dimensions are the #1 cause of Cumulative Layout Shift. Google explicitly uses CLS as a Core Web Vital ranking factor."
          },
          {
            "name": "Sitemap Freshness",
            "value": "Newest <lastmod> 1 day(s) ago",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Sitemap Host Consistency",
            "value": "robots.txt Sitemap points to www.bidfood.cz (page is bidfood.sk)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Update the Sitemap: line in robots.txt to your canonical host. A staging/dev hostname (new., staging., dev.) leaks pre-production to Google and feeds crawlers URLs that 404 or duplicate the live site.",
            "whyMatters": "Google fetches the sitemap from the host declared in robots.txt. A staging domain there either exposes an environment that must not be indexed, or sends every crawl to the wrong host — splitting ranking signals and burning crawl budget."
          }
        ]
      },
      "gdpr": {
        "score": 77,
        "checks": [
          {
            "name": "Cookie Consent Banner (CMP)",
            "value": "Cookiebot detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "legalRefs": {
              "gdpr": [
                "Art. 6(1)(a)",
                "Art. 7"
              ],
              "skLaw": [
                "§ 14"
              ],
              "verified": [
                {
                  "title": "Zákonnosť spracúvania",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 6 — Zákonnosť spracúvania 1. Spracúvanie je zákonné iba vtedy a iba v tom rozsahu, keď je splnená aspoň jedna z týchto podmienok: Písmeno f) prvého pododseku sa nevzťahuje na spracúvanie vykonávané orgánmi verejnej moci pri výkone i",
                  "citation": "čl. 6 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky vyjadrenia súhlasu",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 7 — Podmienky vyjadrenia súhlasu 1. Ak je spracúvanie založené na súhlase, prevádzkovateľ musí vedieť preukázať, že dotknutá osoba vyjadrila súhlas so spracúvaním svojich osobných údajov. 2. Ak dá dotknutá osoba súhlas v rámci písom",
                  "citation": "čl. 7 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Podmienky poskytnutia súhlasu so spracúvaním osobných údajov",
                  "excerpt": "§ 14 Podmienky poskytnutia súhlasu so spracúvaním osobných údajov (1) Ak je spracúvanie osobných údajov založené na súhlase dotknutej osoby, prevádzkovateľ je povinný kedykoľvek vedieť preukázať, že dotknutá osoba poskytla súhlas so spracúv",
                  "citation": "§14 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            }
          },
          {
            "name": "Tracking Scripts & Consent",
            "value": "1 tracker(s) detected with CMP: Google Analytics/GTM",
            "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"
                }
              ]
            }
          },
          {
            "name": "Google Consent Mode v2",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Implement Google Consent Mode v2 with gtag('consent', 'default', { ad_storage: 'denied', analytics_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied' }). Required since March 2024 for EU audiences.",
            "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": "Google requires Consent Mode v2 for all EU traffic since March 2024. Without it, Google Ads remarketing and conversion data will not function, and you lose measurement data."
          },
          {
            "name": "Privacy Policy Page",
            "value": "https://www.freeprivacypolicy.com/free-privacy-policy-generator/",
            "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"
                }
              ]
            }
          },
          {
            "name": "Cookie Policy",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Create a separate cookie policy page listing every cookie by: name, provider, purpose, category (necessary/analytics/marketing), and expiration. Most CMPs auto-generate this.",
            "legalRefs": {
              "gdpr": [
                "Art. 12",
                "Art. 13(1)(c)-(e)"
              ],
              "skLaw": [
                "§ 19"
              ],
              "verified": [
                {
                  "title": "Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 12 — Transparentnosť informácií, oznámenia a postupy výkonu práv dotknutej osoby 3. Prevádzkovateľ poskytne dotknutej osobe informácie o opatreniach, ktoré sa prijali na základe žiadosti podľa článkov 15 až 22, bez zbytočného odklad",
                  "citation": "čl. 12 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby",
                  "source": "Zdroj: EUR-Lex (eur-lex.europa.eu), © Európska únia, 1998–2026. Autentické je iba znenie publikované v elektronickom Úradnom vestníku Európskej únie.",
                  "excerpt": "Article 13 — Informácie, ktoré sa majú poskytovať pri získavaní osobných údajov od dotknutej osoby 2. Okrem informácií, ktoré sa uvádzajú v odseku 1, prevádzkovateľ poskytne dotknutej osobe pri získavaní osobných údajov tieto ďalšie informá",
                  "citation": "čl. 13 nariadenia (EÚ) 2016/679",
                  "jurisdiction": "eu"
                },
                {
                  "title": "Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby",
                  "excerpt": "§ 19 Poskytované informácie, ak osobné údaje sú získané od dotknutej osoby (4) Odseky 1 až 3 sa neuplatňujú v rozsahu, v akom boli informácie dotknutej osobe poskytnuté pred spracúvaním osobných údajov.",
                  "citation": "§19 ods. 4 zákona č. 18/2018 Z.z.",
                  "jurisdiction": "sk"
                }
              ]
            },
            "whyMatters": "The ePrivacy Directive requires transparent cookie disclosure. Vague statements like 'we use cookies for functionality' don't meet the specificity requirement."
          },
          {
            "name": "Legal Contact / Imprint Page",
            "value": "/o-nas",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Terms & Conditions Page",
            "value": "/dodavatel/obchodne-podmienky",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Data Encryption (No Mixed Content)",
            "value": "All resources loaded over HTTPS",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Third-party Data Sharing",
            "value": "2 third-party domain(s)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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. Italian DPA fined companies €20M+ for obstructing erasure requests."
          },
          {
            "name": "Data Protection Officer Contact",
            "value": "DPO / data protection contact found",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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."
          }
        ]
      },
      "nis2": {
        "score": -1,
        "checks": [
          {
            "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": 77,
        "checks": [
          {
            "name": "Viewport Configuration",
            "value": "width=device-width, initial-scale=1",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Mobile Performance Score",
            "value": "79/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 3-5x slower than desktop — what's fast on desktop is slow on mobile.",
            "whyMatters": "Over 65% of e-commerce traffic is mobile (Statista 2024). Google ranks based on mobile performance, not desktop. Mobile score <50 means you're penalized in mobile search."
          },
          {
            "name": "Touch Target Size",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "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 37% more mis-taps on mobile (Google UX research). In e-commerce, a mis-tap on 'Remove from cart' instead of 'Checkout' directly loses revenue."
          },
          {
            "name": "Font Size Readability",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Set minimum 16px font size for body text. Use relative units (rem/em) instead of px for scalability. Product titles: 18px+, prices: 20px+, CTAs: 16px+ with bold.",
            "whyMatters": "Text smaller than 16px forces mobile users to pinch-zoom. This breaks the responsive layout and creates a frustrating experience. Users over 40 are especially affected — and they have the highest purchasing power."
          },
          {
            "name": "Content Fits Viewport",
            "value": "No horizontal scrolling needed",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Responsive Design Techniques",
            "value": "Flexbox, Media queries detected",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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 — small detail, big perception impact."
          },
          {
            "name": "Mobile Navigation (Semantic)",
            "value": "<nav> element present — proper navigation landmark",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Inline CSS Size",
            "value": "77 KB of inline CSS",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Extract inline styles to external CSS files. Inline CSS larger than 50 KB increases HTML payload and cannot be cached separately. Keep only critical above-the-fold CSS inline.",
            "whyMatters": "Large inline CSS blocks increase initial HTML download and parsing time — especially painful on mobile with limited CPU and slower connections."
          },
          {
            "name": "Responsive Images (srcset)",
            "value": "28 image(s) use srcset for responsive sizing",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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. 45% of mobile shoppers use iOS — a polished home screen presence increases return visits."
          },
          {
            "name": "Form Input Types",
            "value": "Optimized: 1 search",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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."
          },
          {
            "name": "Fixed Width Elements",
            "value": "Large fixed-width elements detected — may cause horizontal scroll",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Replace fixed pixel widths with max-width: 100% or use relative units (%, vw). Add 'overflow-x: hidden' to body as a safety net.",
            "whyMatters": "Fixed-width elements wider than the viewport cause horizontal scrolling on mobile. Google's mobile-friendly test specifically checks for this."
          },
          {
            "name": "Form Input Labels (WCAG 3.3.2)",
            "value": "1/1 inputs majú label",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Heading Hierarchy (WCAG 1.3.1)",
            "value": "Preskočené úrovne: h1→h3, h2→h6",
            "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é."
          },
          {
            "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": 14050271,
          "profit": 9928682,
          "turnover": 192155398
        },
        "percentile": {
          "metrics": {
            "equity": 40,
            "turnover": 32,
            "net_profit": 40,
            "credit_limit": 41,
            "credit_score": 88,
            "total_assets": 40,
            "debt_to_equity": 7,
            "employee_count": 100
          },
          "nace_section": "G",
          "peer_group_size": 117540
        },
        "in_insolvency": false,
        "credit_grade_full": "A+"
      },
      "modules": [],
      "security": {
        "score": 74,
        "checks": [
          {
            "name": "SSL/TLS Certificate",
            "value": "Valid HTTPS connection established",
            "status": "pass",
            "evidence": {
              "source": "SSL"
            }
          },
          {
            "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."
          },
          {
            "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)."
          },
          {
            "name": "HTTP → HTTPS Redirect",
            "value": "HTTP properly redirects to HTTPS",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "name": "HSTS (Strict-Transport-Security)",
            "value": "max-age=31536000, includeSubDomains",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "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 the most powerful defense against XSS attacks. Without it, any injected script runs with full privileges. CSP blocks inline script injection, the #1 web attack vector."
          },
          {
            "name": "Clickjacking Protection",
            "value": "X-Frame-Options: SAMEORIGIN",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "name": "X-Content-Type-Options",
            "value": "nosniff",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "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."
          },
          {
            "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."
          },
          {
            "name": "Cookie Security Flags",
            "value": "No cookies set on initial response",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "name": "Technology Disclosure",
            "value": "X-Powered-By: PHP/8.4.13",
            "status": "warning",
            "evidence": {
              "source": "HTTP-header"
            },
            "howToFix": "Hide server version: set ServerTokens Prod (Apache) or server_tokens off (Nginx). Remove X-Powered-By header completely.",
            "whyMatters": "Exposing exact server/PHP versions lets attackers search CVE databases for specific exploits. This is the first step in most automated attacks."
          },
          {
            "name": "Subresource Integrity (SRI)",
            "value": "Only 0/1 SRI-eligible third-party scripts have integrity hashes (1 auto-updating provider script(s) excluded — SRI not applicable)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add integrity='sha384-...' and crossorigin='anonymous' to version-pinned third-party <script> tags (use srihash.org). Auto-updating provider scripts (analytics, payment SDKs, consent tools) are correctly excluded — they can't use SRI.",
            "whyMatters": "Without SRI, if a version-pinned third-party CDN is compromised, attackers can inject malicious code into your site. The British Airways breach (£20M fine) was exactly this attack vector."
          },
          {
            "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. Required by ISO 27001 and SOC 2."
          },
          {
            "name": "Server Version Disclosure",
            "value": "openresty — version hidden",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "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. Cloudflare blocks 150+ billion daily threats."
          }
        ]
      },
      "tech_stack": [
        {
          "eol": false,
          "name": "Magento",
          "category": "cms"
        },
        {
          "name": "Swiper",
          "category": "js-library"
        },
        {
          "name": "openresty",
          "category": "server"
        },
        {
          "eol": false,
          "name": "PHP",
          "version": "8.4.13",
          "category": "language",
          "outdated": false
        }
      ],
      "performance": {
        "score": 71,
        "checks": [
          {
            "name": "Server Response Time (TTFB)",
            "value": "37ms",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "First Contentful Paint (FCP)",
            "value": "0.48s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "Largest Contentful Paint (LCP)",
            "value": "0.96s — Core Web Vital ✓",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "Total Blocking Time (TBT)",
            "value": "0ms",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "Cumulative Layout Shift (CLS)",
            "value": "0.792 (good: <0.1) — Core Web Vital FAILING",
            "status": "fail",
            "evidence": {
              "source": "PSI-lab"
            },
            "howToFix": "Urgent layout stability issues. 1) Add width/height to all <img> and <video>, 2) Reserve space for ads with min-height, 3) Use font-display: swap for web fonts, 4) Don't dynamically inject content above visible area.",
            "whyMatters": "CLS >0.25 fails Core Web Vitals. Users experience constant content jumping — extremely frustrating on mobile where accidental clicks lead to unwanted purchases or page changes."
          },
          {
            "name": "Speed Index",
            "value": "2.59s",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "Total Page Weight",
            "value": "7.3 MB, 60 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 2.2 MB — you're well above that. Amazon found every 100ms of latency costs 1% of sales."
          },
          {
            "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."
          },
          {
            "name": "Unused Code (CSS + JS)",
            "value": "Only 28 KB of unused code — well optimized",
            "status": "pass",
            "evidence": {
              "source": "PSI-lab"
            }
          },
          {
            "name": "Text Compression (gzip/brotli)",
            "value": "All text resources properly compressed",
            "status": "pass",
            "evidence": {
              "source": "HTTP-header"
            }
          },
          {
            "name": "Resource Hints (Preload/Preconnect)",
            "value": "1 preload, 2 preconnect hint(s)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Lazy Loading",
            "value": "91% of images use native lazy loading (49/54)",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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."
          },
          {
            "name": "Script Loading Strategy",
            "value": "Only 33% of 3 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 the #1 cause of slow FCP. Defer maintains execution order, async does not.",
            "whyMatters": "2 render-blocking scripts can add 1-3 seconds to page load. Each synchronous script creates a sequential download-parse-execute chain."
          },
          {
            "name": "CSS File Count",
            "value": "3 CSS file(s) — well consolidated",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Font Preloading",
            "value": "Custom fonts detected without preload hints",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Preload your primary font: <link rel='preload' href='/fonts/main.woff2' as='font' type='font/woff2' crossorigin>. For Google Fonts: preconnect to fonts.gstatic.com.",
            "whyMatters": "Fonts are discovered late in the render pipeline (after CSS is parsed). Preloading tells the browser to download them immediately, reducing Flash of Invisible Text (FOIT) by 200-500ms."
          }
        ]
      },
      "ai_readiness": {
        "score": 53,
        "checks": [
          {
            "name": "AI Bot Access Policy",
            "value": "No AI bot restrictions (allowed by default)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "llms.txt (AI Site Descriptor)",
            "status": "fail",
            "fixLink": {
              "url": "https://llmstxt.org",
              "label": "Learn about llms.txt →"
            },
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Create /llms.txt in Markdown format:\n# Your Store Name\n> One-line summary of your business and key offerings.\n\nDetailed description paragraph.\n\n## Products\n- [Product Category](URL): Description\n\n## About\n- [About Us](URL): Company history and values\n\nSee llmstxt.org for the full specification.",
            "whyMatters": "llms.txt is the emerging standard for AI-readable site descriptions — like robots.txt was for search engines. Early adopters (Yoast, Cloudflare, Stripe) are already using it. Without it, AI assistants have no guided overview of your store."
          },
          {
            "name": "llms-full.txt (Complete AI Content)",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Create /llms-full.txt containing your complete site documentation in a single Markdown file — product catalog summaries, FAQs, policies, brand story. This gives AI models maximum context about your store.",
            "whyMatters": "llms-full.txt provides AI models with your entire site content in one parseable file. It's the difference between an AI having a brief overview vs. deep knowledge of your products and services."
          },
          {
            "name": "Content Accessibility for AI",
            "value": "422 words in raw HTML (2.1% text ratio) — readable by AI crawlers without executing JS",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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."
          },
          {
            "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."
          },
          {
            "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": "FAQ schema provides 30% higher AI citation rates (LLMClicks research). ChatGPT, Perplexity, and Google AI Overviews pull FAQ answers verbatim. It's the fastest way to get your content cited by AI."
          },
          {
            "name": "Content Depth for AI",
            "value": "422 words — add more for better AI citations",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Expand to 500+ words: add detailed product descriptions, use cases, benefits, specifications, comparison info, and buying guides. AI needs substantial content to summarize and cite.",
            "whyMatters": "76.4% of ChatGPT's top 1000 cited pages have 500+ words. AI assistants skip thin pages in favor of content-rich competitors. Aim for the depth that makes your page the definitive resource."
          },
          {
            "name": "Answer-First Content Format",
            "value": "First paragraph: 144 words — good content density above the fold",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Heading Hierarchy for AI",
            "value": "Proper structure: 1 H1 → 10 H2s → 8 H3s — clear content outline",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Semantic HTML Structure",
            "value": "5/6 semantic elements: <article>, <nav>, <main>, <header>, <footer>",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Structured Content (Lists & Tables)",
            "value": "19 lists found — consider adding comparison tables",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add comparison tables to your content. Use <ul>/<ol> for feature lists, specifications, and benefits. Use <table> for product comparisons, pricing tiers, and specifications. AI extracts structured content exponentially faster than paragraphs.",
            "whyMatters": "AI models are biased toward extracting data from HTML lists and tables. Perplexity and ChatGPT pull bullet points and table data with much higher accuracy than paragraph text. Structured content = more AI citations."
          },
          {
            "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": "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."
          },
          {
            "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. This is a fundamental AI visibility requirement."
          },
          {
            "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 3x more than anonymous content. This is especially important for product guides, reviews, and advice content."
          },
          {
            "name": "Extractable Answer Blocks",
            "value": "10 paragraphs, avg 35 words — optimal for AI extraction",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "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 41% less likely to be cited by AI. Perplexity and ChatGPT specifically seek pages with quantified claims and verifiable statistics."
          },
          {
            "name": "Section Length Optimization",
            "value": "Avg section: 28 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": "Pages with 120-180 word sections earn 70% more AI citations (Otterly Citation Economy 2026). For Google AI Overviews specifically, 100-150 words per section is the sweet spot."
          },
          {
            "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."
          },
          {
            "name": "Internal Link Density",
            "value": "164 contextual internal links per 1,000 words — strong knowledge graph signal",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Canonical Tag for AI Deduplication",
            "value": "Canonical points to different URL: https://www.bidfood.sk/",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Verify this canonical is intentional. AI models cluster near-duplicate URLs and choose one representative page. If canonical points to a different URL, AI will only index that target URL, not this page.",
            "whyMatters": "AI search engines (ChatGPT, Perplexity, Bing Copilot) use canonicals to deduplicate content. A wrong canonical means AI may cite the wrong page version or ignore this page entirely."
          },
          {
            "name": "Knowledge Graph Readiness",
            "value": "1/4 signals — missing: @id in JSON-LD, sameAs links (Wikipedia, LinkedIn), Organization schema",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add: @id in JSON-LD, sameAs links (Wikipedia, LinkedIn), Organization schema. Use @id in JSON-LD to create a unique node identifier. Ensure your brand name is identical in title, schema, and OG tags. Link to Wikipedia/Wikidata via sameAs.",
            "whyMatters": "Brands with verified Knowledge Graph presence receive 3.1x more AI citations. @id creates a persistent entity identifier that connects your schema across pages and platforms."
          },
          {
            "name": "Content Readability for AI",
            "value": "Grade 20 — too complex for broad AI citation",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Simplify sentences (target 15-20 words average), use common words, break complex ideas into shorter paragraphs. AI extracts content for general audiences — if it's too academic, AI skips it.",
            "whyMatters": "Content above grade 12 readability is harder for AI to extract as clear, concise answers. Pages using clear headers and approachable language are 28% more likely to be cited by AI."
          },
          {
            "name": "Image Alt Text Quality for AI",
            "value": "Only 48% quality alt text — 7 missing, 21 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."
          },
          {
            "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."
          },
          {
            "name": "ai.txt (AI Permissions)",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Create /ai.txt or /.well-known/ai.txt to declare granular AI permissions per content type: which AI actions (summarization, training, extraction) are allowed for which content sections.",
            "whyMatters": "ai.txt is an emerging standard (proposed May 2025) for fine-grained AI permissions beyond robots.txt. Early adoption signals AI-forward thinking and gives you control over how AI uses your content."
          },
          {
            "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 called 'the new Schema.org moment' — it's how AI agents will interact with your store (search products, add to cart, check availability). Google and Microsoft are co-developing this standard."
          },
          {
            "name": "Content-to-Boilerplate Ratio",
            "value": "69% of text in <main>/<article> — clean content signal",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Social Proof (Testimonials / Case Studies)",
            "status": "warning",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add at least one form of social proof: 1) Client testimonials as <blockquote> with attribution, 2) Case study / portfolio section with past work, 3) 'Trusted by' client logo strip. For B2B, this is the #1 credibility lever.",
            "whyMatters": "Without visible social proof, B2B prospects can't verify your track record before reaching out. Missing testimonials/case studies is the #1 reason consultancy sites lose qualified leads at the contact stage."
          }
        ]
      },
      "phaseTimings": {
        "total": 10336,
        "phase1": 9604,
        "enrichment": 328,
        "sourceMaps": 0,
        "catalogDump": 1
      },
      "vulnerability": {
        "score": 78,
        "checks": [
          {
            "name": "CMS Version Disclosure",
            "value": "\"Drupal 11 (https://www.drupal.org)\" 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."
          },
          {
            "name": "Sensitive Files Exposed",
            "value": ".env, .git, composer.json — all properly blocked",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "Install Script Exposed",
            "value": "No /install/ or /setup/ paths accessible",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "Directory Listing",
            "value": "Disabled — file structure hidden",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "Admin Panel at Default URL",
            "value": "Not found at common paths (/admin, /wp-admin, /administrator, /backoffice)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "Debug Mode / Error Exposure",
            "value": "No debug indicators found in page output",
            "status": "pass",
            "evidence": {
              "source": "HTML-heuristic"
            }
          },
          {
            "name": "Form CSRF Protection",
            "value": "1 form(s) without CSRF tokens",
            "status": "fail",
            "evidence": {
              "source": "HTML-heuristic"
            },
            "howToFix": "Add CSRF token validation to every form. Most CMS frameworks have built-in CSRF protection — make sure it's enabled on all forms, including search and newsletter signup.",
            "confidence": "low",
            "whyMatters": "CSRF is in the OWASP Top 10. Without tokens, attackers can craft pages that automatically submit forms on your site as the victim's browser session."
          },
          {
            "name": "X-Powered-By Header",
            "value": "PHP/8.4.13",
            "status": "warning",
            "evidence": {
              "source": "file-probe"
            },
            "howToFix": "Remove the X-Powered-By header. PHP: add 'expose_php = Off' to php.ini. Express.js: app.disable('x-powered-by').",
            "whyMatters": "\"PHP/8.4.13\" reveals your server technology and version. Attackers use this to find matching CVEs."
          },
          {
            "name": "PHP Version",
            "value": "PHP 8.4.13 — current",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "name": "SPF Record (Email Security)",
            "value": "SPF configured: v=spf1 mx -all",
            "status": "pass",
            "evidence": {
              "source": "DNS"
            }
          },
          {
            "name": "DMARC Policy (Email Auth)",
            "value": "DMARC set to p=none (monitoring only, no enforcement)",
            "status": "warning",
            "evidence": {
              "source": "DNS"
            },
            "howToFix": "Upgrade DMARC policy from p=none to p=quarantine or p=reject. p=none only monitors — it doesn't block spoofed emails. Start with quarantine, then move to reject after verifying legitimate emails pass.",
            "whyMatters": "DMARC p=none provides zero protection against email spoofing. It only generates reports. Move to p=quarantine to actually block forged emails from reaching your customers' inboxes."
          },
          {
            "name": "DKIM Signing (Email Auth)",
            "value": "DKIM configured (selectors: mail)",
            "status": "pass",
            "evidence": {
              "source": "file-probe"
            }
          },
          {
            "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."
          }
        ]
      },
      "opendata_security": {
        "ico": "34152199",
        "name": "Bidfood Slovakia s. r. o.",
        "counts": {
          "low": 2,
          "high": 2,
          "info": 0,
          "total": 7,
          "medium": 3
        },
        "summary": {
          "spf": true,
          "ssl": null,
          "dmarc": "none",
          "dnssec": true,
          "cveHigh": 3,
          "cveCount": 6,
          "mxProvider": null,
          "cveCritical": 1,
          "ctDomainsCount": 0,
          "httpSecurityScore": 0
        },
        "website": "https://www.bidfood.sk",
        "findings": [
          {
            "code": "LOW_SECURITY_SCORE",
            "title": "HTTP security score je nízke: 0/100",
            "detail": "Implementuj HSTS, CSP, X-Frame-Options a ďalšie security headers.",
            "category": "http",
            "severity": "high"
          },
          {
            "code": "KNOWN_CVES",
            "title": "Detekovaných 6 CVE v tech stacku",
            "detail": "Critical: 1, High: 3",
            "category": "cve",
            "severity": "high"
          },
          {
            "code": "SSL_NOT_AUDITED",
            "title": "SSL certifikát nebol overený",
            "detail": "Website je známy, ale DNS/SSL audit ešte neprebehol.",
            "category": "ssl",
            "severity": "medium"
          },
          {
            "code": "NO_HSTS",
            "title": "Chýba HSTS hlavička",
            "detail": "Strict-Transport-Security vynúti HTTPS pre klientov.",
            "category": "http",
            "severity": "medium"
          },
          {
            "code": "NO_CSP",
            "title": "Chýba Content-Security-Policy",
            "detail": "CSP znižuje XSS riziko.",
            "category": "http",
            "severity": "medium"
          },
          {
            "code": "DMARC_NONE",
            "title": "DMARC policy je 'none' (iba monitoring)",
            "detail": "record: v=DMARC1; p=none",
            "category": "dns",
            "severity": "low"
          },
          {
            "code": "NO_X_FRAME_OPTIONS",
            "title": "Chýba X-Frame-Options (clickjacking risk)",
            "detail": null,
            "category": "http",
            "severity": "low"
          }
        ],
        "cyberScore": {
          "band": "E",
          "score": 36,
          "buckets": {
            "ct": 100,
            "cve": 39,
            "ssl": null,
            "http": 0
          },
          "computedAt": "2026-06-15T14:39:22.996Z"
        },
        "overallScore": 14
      }
    },
    "created_at": "2026-07-02T13:03:33.666082+00:00",
    "status": "complete",
    "platform_detected": "Magento",
    "company_ico": "34152199",
    "company_name": "Bidfood Slovakia s. r. o.",
    "company_country": "SK",
    "company_nace": "4638",
    "company_size": "large",
    "nis2_scope": "none",
    "nis2_sector": null,
    "company_risk_score": 10,
    "company_risk_level": "low"
  }
}