1<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"><!-- Sprint 4 (#192): early country/currency detection. Runs before paint to 2 avoid flash of EUR for non-EU visitors. Reads cookie first (zero RTT 3 for repeat visitors), otherwise fetches /api/whereami.php (1 RTT, then 4 cached for 30 days). Sets <html data-country>/<html data-currency>; 5 downstream wl-currency.js listens for the wl-currency-ready event. -->
5<script> 6 (function () { 7 var html = document.documentElement; 8 // Sprint 4 + Phase 1 (#192/#194) â country/currency/locale resolution. 9 var COUNTRY_TO_CURRENCY = { US: 'USD', CA: 'CAD', CA_QC: 'CAD', BR: 'BRL', GB: 'GBP', AU: 'AUD', MX: 'MXN' }; 10 // (country, baseLang) â locale URL. Mirror src/config/locales.ts entries that 11 // have a country_iso different from their default lang. Used for auto-redirect 12 // from base lang URLs (/pt/, /fr/, /en/) to locale URLs (/pt-br/, /fr-ca/, ...) 13 // when a non-default country is detected. Avoids the user's reported bug 14 // (/pt/?country=br showing RGPD content for a Brazilian visitor). 15 // Mirror of public_html/index.php $countryToLocales â keep them in sync. Both 16 // are tested by the same flow: server-side index.php fires on weblegal.ai/ 17 // root hits, this client-side fires on deep-link arrivals. 18 var COUNTRY_TO_LOCALE = { 19 'BR|pt': '/pt-br/', 20 'CA|fr': '/fr-ca/', 21 'CA|en': '/en-ca/', 22 'US|en': '/en-us/', 23 'GB|en': '/en-gb/', 24 'AU|en': '/en-au/', 25 'MX|es': '/es-mx/', 26 'BE|fr': '/fr-be/', 27 'BE|nl': '/nl/', 28 'CH|fr': '/fr-ch/', 29 'CH|de': '/de-ch/', 30 'CH|it': '/it/', 31 'AT|de': '/de-at/' 32 }; 33 function readCookie(n) { 34 var m = document.cookie.match('(^|;)\\s*' + n + '\\s*=\\s*([^;]+)'); 35 return m ? decodeURIComponent(m.pop()) : null; 36 } 37 // Detect base lang from URL path (/pt/foo/ â "pt", /pt-br/foo/ â null since locale URL) 38 function getBaseLangFromPath() { 39 var m = window.location.pathname.match(/^\/([a-z]{2})(?:\/|$)/); 40 return m ? m[1] : null; 41 } 42 // Should we redirect? ONLY the base-language HOMEPAGE (/fr/, /en/â¦), and only 43 // on an arrival from outside the site. 44 // 45 // Why not deep pages (audit 2026-09-18, WL-A01): the regional variants of deep 46 // pages either do not exist (blog articles â .htaccess 301s /fr-be/blog/x/ back 47 // to /fr/blog/x/) or canonicalize to the base language (form, scan, pressâ¦). 48 // Redirecting them produced an infinite /fr/ â /fr-be/ loop on every article for 49 // a Belgian visitor, and at best moved people to a non-canonical copy. Only the 50 // regional homepages are self-canonical, so they are the only legitimate target. 51 // 52 // Why not on internal navigation or after an explicit choice: a visitor who 53 // clicked "Français (France)" in the language switcher, or followed one of our 54 // own links to /fr/, must be able to stay there (Google: don't force a variant). 55 function isOwnNavigation() { 56 try { 57 if (document.cookie.indexOf('wl_locale_pin=1') !== -1) return true; 58 return !!document.referrer && new URL(document.referrer).host === window.location.host; 59 } catch (e) { return false; } 60 } 61 function maybeRedirectToLocale(country) { 62 if (!country) return false; 63 var m = window.location.pathname.match(/^\/([a-z]{2})\/?$/); // homepage only 64 if (!m) return false; 65 var baseLang = m[1]; 66 var targetPath = COUNTRY_TO_LOCALE[country.toUpperCase() + '|' + baseLang]; 67 if (!targetPath || targetPath === '/' + baseLang + '/') return false; 68 if (isOwnNavigation()) return false; 69 // Preserve query string (minus ?country=, now encoded in the path) and hash. 70 var url = new URL(window.location.href); 71 url.pathname = targetPath; 72 url.searchParams.delete('country'); 73 window.location.replace(url.pathname + url.search + url.hash); 74 return true; 75 } 76 var urlParams = new URLSearchParams(window.location.search); 77 var forced = urlParams.get('country') || urlParams.get('currency'); 78 var country = readCookie('wl_country'); 79 if (forced && /^[a-zA-Z_]{2,5}$/.test(forced)) { 80 // Allow ?country=br or ?currency=brl as override 81 country = forced.toUpperCase(); 82 // Persist explicit choice 83 document.cookie = 'wl_country=' + encodeURIComponent(country) + '; max-age=2592000; path=/; samesite=lax'; 84 } 85 // redirect base-lang URL to the matching locale URL when applicable 86 if (country && maybeRedirectToLocale(country)) return; 87 if (country) { 88 html.dataset.country = country; 89 html.dataset.currency = COUNTRY_TO_CURRENCY[country] || 'EUR'; 90 // Fire event so wl-currency.js can swap displayed prices 91 document.addEventListener('DOMContentLoaded', function () { 92 document.dispatchEvent(new CustomEvent('wl-currency-ready', { 93 detail: { country: country, currency: html.dataset.currency } 94 })); 95 }); 96 return; 97 } 98 // No cookie/URL hint â fetch /api/whereami.php (production only path; localhost is no-op for now) 99 try { 100 fetch('/api/whereami.php', { credentials: 'same-origin' }) 101 .then(function (r) { return r.json(); }) 102 .then(function (d) { 103 if (d && d.country) { 104 document.cookie = 'wl_country=' + encodeURIComponent(d.country) + '; max-age=2592000; path=/; samesite=lax'; 105 // auto-redirect on first IP detection too 106 if (maybeRedirectToLocale(d.country)) return; 107 } 108 html.dataset.country = (d && d.country) || ''; 109 html.dataset.currency = (d && d.currency) || 'EUR'; 110 document.dispatchEvent(new CustomEvent('wl-currency-ready', { detail: d || { currency: 'EUR' } })); 111 }) 112 .catch(function () { 113 html.dataset.currency = 'EUR'; 114 }); 115 } catch (e) { 116 html.dataset.currency = 'EUR'; 117 } 118 })(); 119 </script>
119<!-- SEO Meta Tags --><title>Free GDPR Scan + AI Legal Documents in 5 min</title><meta name="description" content="Free GDPR + CCPA scan, then generate Privacy Policy, Terms & Cookies in 5 min with AI. 12 languages, 7 legal frameworks. From â¬19.90."><meta name="robots" content="max-image-preview:large"><!-- Canonical --><link rel="canonical" href="https://weblegal.ai/en/"><!-- Alternate Language Links --><link rel="alternate" hreflang="fr" href="https://weblegal.ai/fr/"><link rel="alternate" hreflang="fr-BE" href="https://weblegal.ai/fr-be/"><link rel="alternate" hreflang="fr-CH" href="https://weblegal.ai/fr-ch/"><link rel="alternate" hreflang="de" href="https://weblegal.ai/de/"><link rel="alternate" hreflang="de-AT" href="https://weblegal.ai/de-at/"><link rel="alternate" hreflang="de-CH" href="https://weblegal.ai/de-ch/"><link rel="alternate" hreflang="en" href="https://weblegal.ai/en/"><link rel="alternate" hreflang="en-GB" href="https://weblegal.ai/en-gb/"><link rel="alternate" hreflang="es" href="https://weblegal.ai/es/"><link rel="alternate" hreflang="es-MX" href="https://weblegal.ai/es-mx/"><link rel="alternate" hreflang="it" href="https://weblegal.ai/it/"><link rel="alternate" hreflang="pt" href="https://weblegal.ai/pt/"><link rel="alternate" hreflang="nl" href="https://weblegal.ai/nl/"><link rel="alternate" hreflang="pl" href="https://weblegal.ai/pl/"><link rel="alternate" hreflang="sv" href="https://weblegal.ai/sv/"><link rel="alternate" hreflang="ro" href="https://weblegal.ai/ro/"><link rel="alternate" hreflang="el" href="https://weblegal.ai/el/"><link rel="alternate" hreflang="cs" href="https://weblegal.ai/cs/"><link rel="alternate" hreflang="hu" href="https://weblegal.ai/hu/"><link rel="alternate" hreflang="da" href="https://weblegal.ai/da/"><link rel="alternate" hreflang="en-US" href="https://weblegal.ai/en-us/"><link rel="alternate" hreflang="en-CA" href="https://weblegal.ai/en-ca/"><link rel="alternate" hreflang="fr-CA" href="https://weblegal.ai/fr-ca/"><link rel="alternate" hreflang="pt-BR" href="https://weblegal.ai/pt-br/"><link rel="alternate" hreflang="en-AU" href="https://weblegal.ai/en-au/"><link rel="alternate" hreflang="x-default" href="https://weblegal.ai/en/"><!-- Open Graph / Facebook --><meta property="og:type" content="website"><meta property="og:url" content="https://weblegal.ai/en/"><meta property="og:title" content="Free GDPR Scan + AI Legal Documents in 5 min"><meta property="og:description" content="Free GDPR + CCPA scan, then generate Privacy Policy, Terms & Cookies in 5 min with AI. 12 languages, 7 legal frameworks. From â¬19.90."><meta property="og:image" content="https://weblegal.ai/assets/og-default-DliLAxtt_1aTMj5.jpg"><meta property="og:site_name" content="WebLegal.ai"><meta property="og:locale" content="en_US"><meta property="og:locale:alternate" content="fr_FR"><meta property="og:locale:alternate" content="es_ES"><meta property="og:locale:alternate" content="de_DE"><meta property="og:locale:alternate" content="it_IT"><meta property="og:locale:alternate" content="pt_PT"><meta property="og:locale:alternate" content="nl_NL"><meta property="og:locale:alternate" content="pl_PL"><meta property="og:locale:alternate" content="sv_SE"><meta property="og:locale:alternate" content="ro_RO"><meta property="og:locale:alternate" content="cs_CZ"><meta property="og:locale:alternate" content="el_GR"><meta property="og:locale:alternate" content="hu_HU"><meta property="og:locale:alternate" content="da_DK"><meta property="og:locale:alternate" content="en_GB"><meta property="og:locale:alternate" content="en_CA"><meta property="og:locale:alternate" content="en_AU"><meta property="og:locale:alternate" content="pt_BR"><meta property="og:locale:alternate" content="fr_CA"><meta property="og:locale:alternate" content="fr_BE"><meta property="og:locale:alternate" content="fr_CH"><meta property="og:locale:alternate" content="de_CH"><meta property="og:locale:alternate" content="de_AT"><meta property="og:locale:alternate" content="es_MX"><!-- Twitter --><meta property="twitter:card" content="summary_large_image"><meta property="twitter:site" content="@WebLegalAI"><meta property="twitter:url" content="https://weblegal.ai/en/"><meta property="twitter:title" content="Free GDPR Scan + AI Legal Documents in 5 min"><meta property="twitter:description" content="Free GDPR + CCPA scan, then generate Privacy Policy, Terms & Cookies in 5 min with AI. 12 languages, 7 legal frameworks. From â¬
11919.90."><meta property="twitter:image" content="https://weblegal.ai/assets/og-default-DliLAxtt_1aTMj5.jpg"><!-- Favicon --><link rel="icon" type="image/png" href="/img/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/svg+xml" href="/img/favicon.svg"><link rel="shortcut icon" href="/img/favicon.ico"><link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><!-- Fonts: preconnect + async load (non-render-blocking) --><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;900&family=Open+Sans:wght@400;500;600&display=swap" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;900&family=Open+Sans:wght@400;500;600&display=swap"></noscript><!-- Preconnect + dns-prefetch for Google Analytics --><link rel="preconnect" href="https://www.googletagmanager.com"><link rel="dns-prefetch" href="https://www.google-analytics.com"><!-- Stylesheets --><link rel="stylesheet" href="/css/styles.css"><!-- UrlScanner used across hero + /blog/ + /scan/ + /cookie-banner/ + /form/ (#163) --><link rel="stylesheet" href="/css/url-scanner.css"><!-- JSON-LD Organization + WebSite (all pages) -->
119<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://weblegal.ai/#organization","name":"WebLegal.ai","alternateName":["WebLegal AI","weblegal.ai"],"legalName":"LAUYAN SOFTWARE","url":"https://weblegal.ai","logo":{"@type":"ImageObject","url":"https://weblegal.ai/img/weblegal-logo.png","width":512,"height":512},"description":"WebLegal.ai is an AI platform that generates GDPR, CCPA and LGPD-compliant legal documents â privacy policy, cookie policy, terms of use and terms of sale â plus a free cookie-consent banner, with a website compliance scanner, in 25 languages.","email":"[email protected]","taxID":"48280615500024","vatID":"FR24482806155","parentOrganization":{"@type":"Organization","name":"Lauyan Software","legalName":"LAUYAN SOFTWARE","url":"https://www.lauyan.com","foundingDate":"2005-07-01","sameAs":["https://fr.linkedin.com/company/lauyan-software","https://www.youtube.com/LauyanSoftwareEN","https://github.com/lauyan-software","https://www.crunchbase.com/organization/lauyan-software"]},"sameAs":["https://x.com/WebLegalAI","https://github.com/lauyan-software","https://fr.linkedin.com/company/lauyan-software","https://www.youtube.com/LauyanSoftwareEN","https://www.crunchbase.com/organization/weblegal-ai"],"knowsAbout":["GDPR","CCPA","CPRA","LGPD","UK GDPR","ePrivacy Directive","Cookie Consent","Privacy Policy","Terms of Service","Legal Document Generation","Global Privacy Control"],"areaServed":[{"@type":"Country","name":"France"},{"@type":"Country","name":"Germany"},{"@type":"Country","name":"United Kingdom"},{"@type":"Country","name":"United States"},{"@type":"Country","name":"Spain"},{"@type":"Country","name":"Italy"},{"@type":"Country","name":"Portugal"},{"@type":"Country","name":"Netherlands"},{"@type":"Country","name":"Poland"},{"@type":"Country","name":"Sweden"},{"@type":"Country","name":"Canada"},{"@type":"Country","name":"Brazil"},{"@type":"Country","name":"Australia"}],"address":{"@type":"PostalAddress","streetAddress":"16 rue du Général de Gaulle","addressLocality":"Rambouillet","postalCode":"78120","addressCountry":"FR"},"founder":{"@type":"Person","name":"Yann Guichard"},"foundingDate":"2005-07-01","contactPoint":{"@type":"ContactPoint","email":"[email protected]","contactType":"customer service"}},{"@type":"WebSite","@id":"https://weblegal.ai/#website","url":"https://weblegal.ai","name":"WebLegal.ai","alternateName":["WebLegal AI","WebLegal","weblegal.ai"],"publisher":{"@id":"https://weblegal.ai/#organization"},"inLanguage":["fr-FR","en-US","es-ES","de-DE","it-IT","pt-PT","nl-NL","pl-PL","sv-SE","ro-RO","cs-CZ","el-GR","hu-HU","da-DK"],"potentialAction":{"@type":"SearchAction","target":"https://weblegal.ai/en/blog/?search={search_term_string}","query-input":"required name=search_term_string"}}]}</script>
119<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","url":"https://weblegal.ai/en/","name":"Free GDPR Scan + AI Legal Documents in 5 min","description":"Free GDPR + CCPA scan, then generate Privacy Policy, Terms & Cookies in 5 min with AI. 12 languages, 7 legal frameworks. From â¬19.90.","inLanguage":"en","speakable":{"@type":"SpeakableSpecification","cssSelector":["h1","meta[name='description']"]},"isPartOf":{"@id":"https://weblegal.ai/#website"},"publisher":{"@id":"https://weblegal.ai/#organization"}}</script>
119<!-- color-scheme meta: tells browser we support both (prevents flash) --><meta name="color-scheme" content="light dark"><!-- Inline theme init (prevent flash) -->
119<script> 120 // 3-state: 'light' | 'dark' | null (auto = OS via color-scheme) 121 (function() { 122 var root = document.documentElement; 123 var saved = localStorage.getItem('theme'); 124 var mq = window.matchMedia('(prefers-color-scheme: dark)'); 125 126 function applyTheme(mode) { 127 if (mode === 'dark') { 128 root.style.colorScheme = 'dark'; 129 root.classList.add('dark-theme'); 130 root.setAttribute('data-theme', 'dark'); 131 } else if (mode === 'light') { 132 root.style.colorScheme = 'light'; 133 root.classList.remove('dark-theme'); 134 root.setAttribute('data-theme', 'light'); 135 } else { 136 // Auto: native color-scheme + sync .dark-theme from OS 137 root.style.colorScheme = 'light dark'; 138 root.setAttribute('data-theme', 'auto'); 139 root.classList.toggle('dark-theme', mq.matches); 140 } 141 } 142 143 applyTheme(saved); 144 145 // Listen for OS theme changes (auto mode reacts in real-time) 146 mq.addEventListener('change', function() { 147 if (!localStorage.getItem('theme')) applyTheme(null); 148 }); 149 150 // Expose for toggle handler 151 window.__applyTheme = applyTheme; 152 })(); 153 </script>
153<!-- Google Analytics - Lazy Loading for Performance 154 Note: wl-cookie-consent.js may create window.gtag itself to init 155 Consent Mode v2 default. We use our own __gaLoaded flag so we don't 156 skip loading when gtag already exists from the CCB. -->
156<script> 157 var __gaLoaded = false; 158 function loadGoogleAnalytics() { 159 // Same automation guard as trackGA4Event in core-critical.js, and it has to 160 // be here too: users and sessions are minted by the page_view that 161 // gtag('config') fires below, not by our custom events. Guarding only the 162 // custom events would leave a crawler wave inflating users while the funnel 163 // stayed clean, which reads as a traffic surge with a conversion collapse. 164 // Four such days carried 65% of a month's users before this (audit 2026-07-26). 165 try { if (navigator.webdriver === true) return; } catch (e) {} 166 if (__gaLoaded) return; 167 __gaLoaded = true; 168 window.dataLayer = window.dataLayer || []; 169 if (typeof window.gtag !== 'function') { 170 window.gtag = function() { window.dataLayer.push(arguments); }; 171 } 172 gtag('js', new Date()); 173 // WL-B04 : jamais de donnee personnelle dans page_location. La page de succes 174 // porte l'email de l'acheteur (success_url Stripe), le formulaire l'URL du 175 // site client (?url=), le generateur de bandeau un domaine. Retires ici, pour 176 // la page vue initiale comme pour tous les evenements qui suivent. 177 var _loc = window.location.href; 178 try { 179 var _u = new URL(window.location.href); 180 ['email', 'url', 'domain', 'session_id', 'token'].forEach(function (k) { _u.searchParams.delete(k); }); 181 _loc = _u.toString(); 182 } catch (e) { _loc = window.location.origin + window.location.pathname; } 183 // Le referent suit la meme regle (revue Fable) : sinon la page precedente, par 184 // exemple /en/scan/?url=<site du client>, repartait dans page_referrer. Un referent 185 // externe se reduit a son origine, ce que les navigateurs envoient deja. Et le 186 // retour de la page de paiement n'est pas une source : sans ignore_referrer, GA4 187 // ouvrait une session « checkout.stripe.com / referral » a chaque achat (#350). 188 var _cfg = { page_location: _loc }; 189 try { 190 if (document.referrer) { 191 var _r = new URL(document.referrer); 192 if (_r.host === window.location.host) { 193 ['email', 'url', 'domain', 'session_id', 'token'].forEach(function (k) { _r.searchParams.delete(k); }); 194 _cfg.page_referrer = _r.toString(); 195 } else { 196 _cfg.page_referrer = _r.origin + '/'; 197 if (/(^|\.)(stripe\.com|paypal\.com)$/i.test(_r.hostname)) _cfg.ignore_referrer = 'true'; 198 } 199 } 200 } catch (e) { /* referent illisible : rien a transmettre */ } 201 gtag('config', 'G-0ETDMZLREG', _cfg); 202 var script = document.createElement('script'); 203 script.async = true; 204 script.src = 'https://www.googletagmanager.com/gtag/js?id=G-0ETDMZLREG'; 205 document.head.appendChild(script); 206 } 207 var loadAnalytics = function() { 208 loadGoogleAnalytics(); 209 document.removeEventListener('scroll', loadAnalytics); 210 document.removeEventListener('click', loadAnalytics); 211 document.removeEventListener('mousemove', loadAnalytics); 212 document.removeEventListener('touchstart', loadAnalytics); 213 }; 214 document.addEventListener('scroll', loadAnalytics, { once: true, passive: true }); 215 document.addEventListener('click', loadAnalytics, { once: true, passive: true }); 216 document.addEventListener('mousemove', loadAnalytics, { once: true, passive: true }); 217 document.addEventListener('touchstart', loadAnalytics, { once: true, passive: true }); 218 setTimeout(loadAnalytics, 3000); 219 </script>
219<script type="module" src="/assets/page-BT_9kWGp.js"></script>
219</head> <body id="top" class> <!-- Header Navigation --> <header class="site-header"> <div class="container"> <a href="/en/" class="logo"> <svg fill="none" height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"> <path d="m14.5 4.5h19c5.5228 0 10 4.47715 10 10v19c0 5.5228-4.4772 10-10 10h-19c-5.52285 0-10-4.4771-10-10v-19c0-5.52285 4.47715-10 10-10z" fill="#10b981"></path> <path d="m40.29 16.6145c-.2825.0274-.5651.0889-.8476.1846-.2826.0957-.5606.2165-.834.3623-.4193.237-.7178.4967-.8955.7793-.1777.2825-.3395.6243-.4854 1.0254-.5013 1.3854-1.2737 3.6048-2.3173 6.6582-1.0437 3.0534-2.1306 6.2252-3.2608 9.5156h-2.748l-5.127-14.4238-4.6211 14.4238h-2.748c-1.5222-4.4297-2.6888-7.8408-3.5-10.2334s-1.4948-4.4001-2.0508-6.0224c-.1732-.4922-.3691-.85-.5879-1.0733-.2187-.2233-.5013-.4489-.84765-.6767-.2461-.1641-.50814-.2849-.78614-.3624-.27799-.0774-.59928-.139-.96386-.1845v-1.0664h10.34965v1.039c-.6107.0729-1.0665.1436-1.3672.2119-.3008.0684-.5378.139-.711.212-.164.0729-.2643.1504-.3008.2324-.0364.082-.0546.1549-.0546.2187 0 .1276.0159.2507.0478.3692s.0661.2552.1026.4101c.2187.711.6608 2.0599 1.3261 4.0469.6654 1.987 1.4857 4.4525 2.461 7.3965l4.416-14.1367h2.8984l5.127 14.5742c.7565-2.3425 1.3603-4.2565 1.8115-5.7422s.8317-2.7572 1.1416-3.8145c.1823-.6471.3281-1.1894.4375-1.6269s.1641-.8158.1641-1.1348c0-.1914-.0889-.3554-.2666-.4922-.1778-.1367-.417-.2552-.7178-.3554-.2552-.0821-.5856-.1481-.9912-.1983-.4056-.0501-.7588-.0888-1.0596-.1162v-1.0937h7.8066z" fill="#fff"></path> </svg> <div class="logo-content"> <span class="logo-text logo-text-green">Web<em>Legal</em>.ai</span> </div> </a> <nav class="main-navigation"> <ul class="nav-menu"> <li> <a href="/en/#sample-documents" class="nav-link"> Documents </a> </li> <li> <a href="/en/scan/" class="nav-link"> Scanner </a> </li> <li> <a href="/en/cookie-banner/" class="nav-link"> 220Cookies 221</a> </li> <li> <a href="/en/blog/" class="nav-link"> Blog </a> </li> <li> <a href="/en/#pricing" class="nav-link"> Pricing </a> </li> <li> <a href="/en/docs/" class="nav-link"> Docs </a> </li> <li> <a href="/en/form/" class="btn-primary"> Protect my website </a> </li> </ul> <button class="mobile-menu-toggle" aria-label="Toggle menu"> <span></span> <span></span> <span></span> </button> </nav> <div class="header-controls"> <div class="lang-dropdown" id="langDropdown"> <button type="button" class="lang-dropdown-toggle" id="langDropdownToggle" aria-label="Select country" aria-expanded="false"> <img src="/img/flags/eu.svg" width="20" height="20" alt="Europe (EN)" style="border-radius:50%;object-fit:cover;width:20px;height:20px"> <span style="font-size:12px">Europe (EN)</span> <svg class="lang-chevron" width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> <path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path> </svg> </button> <div class="lang-dropdown-menu" id="langDropdownMenu" style="width:420px;padding:8px"> <div style="display:flex;flex-direction:column"> <a href="/fr/" class="lang-option" data-lang="fr" data-path="/fr/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/fr.svg" width="18" height="18" alt="France" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>France</span> </a><a href="/fr-be/" class="lang-option" data-lang="fr" data-path="/fr-be/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/be.svg" width="18" height="18" alt="Belgique" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Belgique</span> </a><a href="/fr-ch/" class="lang-option" data-lang="fr" data-path="/fr-ch/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ch.svg" width="18" height="18" alt="Suisse FR" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Suisse FR</span> </a><a href="/de/" class="lang-option" data-lang="de" data-path="/de/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/de.svg" width="18" height="18" alt="Deutschland" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Deutschland</span> </a><a href="/de-at/" class="lang-option" data-lang="de" data-path="/de-at/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/at.svg" width="18" height="18" alt="Ãsterreich" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Ãsterreich</span> </a><a href="/de-ch/" class="lang-option" data-lang="de" data-path="/de-ch/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ch.svg" width="18" height="18" alt="Schweiz DE" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Schweiz DE</span> </a><a href="/pl/" class="lang-option" data-lang="pl" data-path="/pl/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/pl.svg" width="18" height="18" alt="Polska" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Polska</span> </a><a href="/sv/" class="lang-option" data-lang="sv" data-path="/sv/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/se.svg" width="18" height="18" alt="Sverige" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Sverige</span> </a><a href="/cs/" class="lang-option" data-lang="cs" data-path="/cs/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/cz.svg" width="18" height="18" alt="Äesko" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Äesko</span> </a><a href="/hu/" class="lang-option" data-lang="hu" data-path="/hu/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/hu.svg" width="18" height="18" alt="Magyarország" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Magyarország</span> </a> </div><div style="display:flex;flex-direction:column"> <a href="/en/" class="lang-option active" data-lang="en" data-path="/en/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/eu.svg" width="18" height="18" alt="Europe (EN)" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Europe (EN)</span> </a><a href="/en-gb/" class="lang-option" data-lang="en" data-path="/en-gb/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/gb.svg" width="18" height="18" alt="United Kingdom" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>
221United Kingdom</span> </a><a href="/es/" class="lang-option" data-lang="es" data-path="/es/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/es.svg" width="18" height="18" alt="España" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>España</span> </a><a href="/es-mx/" class="lang-option" data-lang="es" data-path="/es-mx/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/mx.svg" width="18" height="18" alt="México" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>México</span> </a><a href="/it/" class="lang-option" data-lang="it" data-path="/it/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/it.svg" width="18" height="18" alt="Italia" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Italia</span> </a><a href="/pt/" class="lang-option" data-lang="pt" data-path="/pt/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/pt.svg" width="18" height="18" alt="Portugal" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Portugal</span> </a><a href="/nl/" class="lang-option" data-lang="nl" data-path="/nl/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/nl.svg" width="18" height="18" alt="Nederland" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Nederland</span> </a><a href="/ro/" class="lang-option" data-lang="ro" data-path="/ro/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ro.svg" width="18" height="18" alt="România" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>România</span> </a><a href="/el/" class="lang-option" data-lang="el" data-path="/el/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/gr.svg" width="18" height="18" alt="Îλλάδα" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Îλλάδα</span> </a><a href="/da/" class="lang-option" data-lang="da" data-path="/da/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/dk.svg" width="18" height="18" alt="Danmark" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Danmark</span> </a> </div><div style="display:flex;flex-direction:column"> <a href="/en-us/" class="lang-option" data-lang="en" data-path="/en-us/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/us.svg" width="18" height="18" alt="United States" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>United States</span> </a><a href="/en-ca/" class="lang-option" data-lang="en" data-path="/en-ca/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ca.svg" width="18" height="18" alt="Canada EN" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Canada EN</span> </a><a href="/fr-ca/" class="lang-option" data-lang="fr" data-path="/fr-ca/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ca.svg" width="18" height="18" alt="Canada FR" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Canada FR</span> </a><a href="/pt-br/" class="lang-option" data-lang="pt" data-path="/pt-br/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/br.svg" width="18" height="18" alt="Brasil" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Brasil</span> </a><a href="/en-au/" class="lang-option" data-lang="en" data-path="/en-au/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/au.svg" width="18" height="18" alt="Australia" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Australia</span> </a> </div> </div> </div> <button id="themeSwitcher" class="theme-switcher" aria-label="Switch theme" title="Switch theme"> <span class="icon sun-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </span> <span class="icon moon-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> </span> <span class="icon auto-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="4"></circle> <path d="M12 2v2"></path> <path d="M12 20v2"></path> <path d="M4.93 4.93l1.41 1.41"></path> <path d="M17.66 17.66l1.41 1.41"></path> <path d="M2 12h2"></path> <path d="M20 12h2"></path> <path d="M6.34 17.66l-1.41 1.41"></path> <path d="M19.07 4.93l-1.41 1.41"></path> <path d="M16 12a4 4 0 0 0-4-4v8a4 4 0 0 0 4-4z" fill="currentColor"></path> </svg> </span> </button> </div> </div> </header> <!-- Main Content --> <main> <!-- ============================================================ 222 1. HERO SECTION (unchanged) 223 ============================================================ --> <section id="hero" class="hero-section"> <div class="hero-container"> <div class="hero-text fade-on-scroll hero-stagger"> <h1 class="hero-title" id="hero-h1" data-b-part1="Discover your" data-b-part2="GDPR score" data-b-part3>
223Is your website <span class="gradient-highlight">GDPR compliant</span> ?</h1> <p class="subtitle" id="hero-subtitle" data-b-subtitle="Fines up to â¬20M or 4% of revenue. Check your compliance in 30 seconds â <strong>free, no signup.</strong>">Get your compliance score in 30 seconds â <strong>free, no signup.</strong></p> <div class="hero-url-scanner"> <div class="url-scanner url-scanner-lg"> <div class="url-scanner-row"> <input type="text" id="hero-url-input" class="url-scanner-input" placeholder="your-website.com" spellcheck="false" autocorrect="off" autocapitalize="off" autocomplete="url" aria-label="URL"> <button type="button" id="hero-url-btn" class="url-scanner-btn url-scanner-btn-primary"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg> <span>Analyze my site</span> </button> </div> </div>
223<script type="module">document.querySelectorAll(".url-scanner-input").forEach(e=>{e.addEventListener("input",()=>{const a=e.value.replace(/^https?:\/\//i,"");if(a!==e.value){const l=(e.selectionStart||0)-(e.value.length-a.length);e.value=a,e.setSelectionRange(Math.max(0,l),Math.max(0,l))}})});</script>
223 <p class="hero-url-hint"> No signup · No commitment · Instant result 224 · 225<a href="#" class="hero-calc-toggle" id="hero-calc-toggle"> Calculate my fine risk </a> </p> </div> <div class="hero-action-group hero-calculator-collapsed" id="hero-calculator-group" style="display:none"> <label for="hero-revenue" class="hero-action-label">Enter your annual revenue to calculate your risk:</label> <div class="hero-action-bar"> <input type="number" id="hero-revenue" class="hero-action-input" placeholder="e.g. 50000" min="0" step="10000" aria-label="Your annual revenue (â¬)"> <button type="button" class="btn-secondary hero-action-calc" id="hero-calc-btn" aria-label="Calculate My Risk"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="4" y="2" width="16" height="20" rx="2"></rect><line x1="8" y1="6" x2="16" y2="6"></line><line x1="8" y1="10" x2="10" y2="10"></line><line x1="14" y1="10" x2="16" y2="10"></line><line x1="8" y1="14" x2="10" y2="14"></line><line x1="14" y1="14" x2="16" y2="14"></line><line x1="8" y1="18" x2="10" y2="18"></line><line x1="14" y1="18" x2="16" y2="18"></line></svg> </button> <a href="/en/form/" class="btn-primary hero-action-cta">Get Protected Now</a> </div> <div class="hero-calc-result" id="hero-calc-result"> <p class="hero-calc-result-title"> <span class="hero-calc-result-label">Potential fine:</span> <span class="hero-calc-result-amount" id="hero-risk-amount"></span> <span class="hero-calc-result-separator">—</span> <span class="hero-calc-result-protect"> Protect yourself from <strong id="hero-protect-price"></strong> </span> </p> </div> <p class="hero-calc-result-disclaimer">Based on GDPR Art. 83 maximum penalty of <strong>4% of annual turnover or â¬20 million</strong>, whichever is higher.</p> </div> <div class="hero-trust-line"> <div class="trust-indicators"> <div class="trust-item"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path> </svg> <span>3-minute setup</span> </div> </div> </div> </div> <!-- A/B Test: Carousel (A) vs Animation variants (B-E) --> <div id="hero-visual-carousel" class="hero-carousel-link"> <a href="#sample-documents"> <div class="hero-visual"> <div class="document-container" id="documentContainer"> <!-- Document 1: Terms of Use in visitor's language --> <div class="document-mockup active"> <div class="doc-header"> <div class="doc-logo">Legal Document</div> <div class="doc-date">Generated in 2026</div> </div> <div class="doc-title">Terms of Use</div> <div class="doc-section"> <div class="doc-section-title">1. Acceptance of Terms</div> <p>By accessing and using this website, you agree to be bound by the terms and provisions of this agreement. If you do not agree to abide by the above, please do not use this service.</p> </div><div class="doc-section"> <div class="doc-section-title">2. Use License</div> <p>Permission is granted to temporarily download one copy of the documents on our website for personal, non-commercial transitory viewing only. This is the grant of a license, not a transfer of title, and under this license you may not:</p> <ul class="doc-list"> <li>modify or copy the documents</li><li>use the documents for any commercial purpose</li><li>attempt to decompile any software</li> </ul> </div><div class="doc-section"> <div class="doc-section-title">3. Disclaimer</div> <p>The documents on our website are provided on an 'as is' basis. We make no warranties, expressed or implied, and hereby disclaim all other warranties including, without limitation, implied warranties or conditions of merchantability.</p> </div> </div> <!-- Document 2: Privacy Policy in visitor's language --> <div class="document-mockup"> <div class="doc-header"> <div class="doc-logo">Legal Document</div> <div class="doc-date">Generated in 2026</div> </div> <div class="doc-title">Privacy Policy</div> <div class="doc-section"> <div class="doc-section-title">1. Data Collection</div> <p>We collect information you provide directly, such as your name, email address, and payment information. Technical data like your IP address and cookies are also collected automatically in compliance with GDPR.</p> </div><div class="doc-section"> <div class="doc-section-title">2. Use of Data</div> <p>Your personal data is used to provide and improve our services, process your transactions, send account-related communications, and ensure the security of our platform.</p> <ul class="doc-list"> <li>provide and maintain our services</li><li>process transactions and payments</li><li>send technical notifications</li> </ul> </div><div class="doc-section"> <div class="doc-section-title">3. Your Rights</div> <p>Under GDPR, you have the right to access, rectify, erase, restrict processing, port, and object to the processing of your personal data.</p> </div> </div> <!-- Document 3: Cookie Policy in visitor's language --> <div class="document-mockup"> <div class="doc-header"> <div class="doc-logo">Legal Document</div> <div class="doc-date">Generated in 2026</div> </div> <div class="doc-title">Cookie Policy</div> <div class="doc-section"> <div class="doc-section-title">1. What Are Cookies?</div> <p>
225Cookies are small text files placed on your device when you visit a website. They are widely used to make websites work efficiently and to provide information to site owners.</p> </div><div class="doc-section"> <div class="doc-section-title">2. Types of Cookies Used</div> <p>We use different categories of cookies to ensure our site functions properly and to improve your experience:</p> <ul class="doc-list"> <li>Essential cookies: required for site functionality</li><li>Analytics cookies: help us understand site usage</li><li>Preference cookies: remember your settings</li> </ul> </div><div class="doc-section"> <div class="doc-section-title">3. Managing Cookies</div> <p>You can control and manage cookies through your browser settings. You can also use our cookie preference center to customize your choices. Withdrawing consent does not affect the lawfulness of prior processing.</p> </div> </div> <!-- Document 4: Terms of Sale in visitor's language --> <div class="document-mockup"> <div class="doc-header"> <div class="doc-logo">Legal Document</div> <div class="doc-date">Generated in 2026</div> </div> <div class="doc-title">Terms of Sale</div> <div class="doc-section"> <div class="doc-section-title">1. Products & Services</div> <p>We offer AI-generated legal documents including terms of use, privacy policies, cookie policies, and terms of sale. All documents are tailored to your specific business needs and jurisdiction.</p> </div><div class="doc-section"> <div class="doc-section-title">2. Pricing & Payment</div> <p>All prices are clearly displayed on our website and include applicable taxes. Payment must be made in full at the time of purchase through our secure payment providers.</p> </div><div class="doc-section"> <div class="doc-section-title">3. Delivery & Refunds</div> <p>Digital documents are delivered instantly via email. You have a 14-day right of withdrawal under EU consumer law, except for customized documents where the service has been fully performed.</p> </div> </div> </div> <div class="document-info"> <div class="document-title" id="documentTitle">Terms of Use</div> <div class="document-description" id="documentDescription">Legal framework for website use and user obligations</div> </div> </div> </a> </div> <div id="hero-visual-animation" style="display:none"> <div id="hero-anim-privacy"><link rel="stylesheet" href="/css/hero-demo.css"><!-- JS mode: live animation --> 226 <div class="hero-demo-container" id="hd-privacy-er6ff1" data-config="{"id":"hd-privacy-er6ff1","speed":1.25,"showCta":false,"ctaUrl":"/en/scan/","basePhases":{"URL_TYPE":{"start":0,"duration":1500},"SCAN_CLICK":{"start":1500,"duration":400},"SCANNING":{"start":1900,"duration":3200},"SCORE":{"start":5100,"duration":3000},"DOCUMENT":{"start":8100,"duration":3000},"RESULT":{"start":11100,"duration":3200},"PAUSE":{"start":14300,"duration":1000}},"baseTotal":15300,"internal":{"URL_TYPE_DURATION":1200,"SCORE_ANIMATE_DURATION":1500,"SCORE_DETAIL_START":1200,"SCORE_DETAIL_STAGGER":150,"DOC_TYPE_DURATION":2800,"DOC_DELIVERED_DELAY":3000,"RESULT_ANIMATE_DURATION":1200},"scoreConfig":{"TARGET_SCORE":42,"FINAL_SCORE":100,"GAUGE_ARC":236},"content":{"heroTitle":"Analyze your site in 30 seconds","urlPlaceholder":"acme-store.com","btnLabel":"Analyze","trustItems":["No signup","Instant result","100% free"],"scanMessages":["Connecting to site...","Analyzing structure...","Detecting cookies...","Checking GDPR compliance...","Analyzing legal documents...","Verifying business registry...","Calculating compliance score..."],"docLogo":"Legal Document","docDate":"Generated in 2026","emailSent":"Document sent to [email protected]","resultLabel":"Excellent compliance","resultWarning":"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!","ctaText":"Protect my site now","scanItems":[{"check":true,"text":"Valid SSL certificate"},{"check":false,"text":"Privacy policy missing"},{"check":false,"text":"No DPO or privacy contact identified"},{"check":false,"text":"No information about data collected"},{"check":false,"text":"User rights not mentioned (GDPR Art. 13)"},{"check":true,"text":"Partial legal notices"},{"check":true,"text":"
226Business registration verified"}],"scoreLabel":"â Privacy policy missing","docTitle":"Privacy Policy","docSections":[{"title":"1. Data Collection","text":"We collect information you provide directly, such as your name, email address, and payment information. Technical data is also collected automatically in compliance with GDPR."},{"title":"2. Use of Data","text":"Your personal data is used to provide and improve our services, process your transactions, send account-related communications, and ensure the security of our platform."},{"title":"3. Your GDPR Rights","text":"Under the General Data Protection Regulation, you have the right to access, rectify, erase, restrict, and port your personal data."}]}}"><div class="hd-browser-bar"><div class="hd-dots"><span></span><span></span><span></span></div><div class="hd-url"><span class="hd-lock">🔒</span><span class="hd-url-text">weblegal.ai</span></div></div><div class="hd-content"><!-- Phase 1: URL --><div class="hd-phase hd-phase-url hd-active"><h3 class="hd-subtitle">Analyze your site in 30 seconds</h3><div class="hd-url-input"><div class="hd-url-field"><span class="hd-typed"></span><span class="hd-cursor"></span></div><button class="hd-btn">🔍 Analyze</button></div><div class="hd-trust"><span>✔ No signup</span><span>✔ Instant result</span><span>✔ 100% free</span></div></div><!-- Phase 2: Scan --><div class="hd-phase hd-phase-scan"><div class="hd-scan-header"><div class="hd-spinner"></div><span class="hd-scan-status">Connecting to site...</span></div><div class="hd-progress"><div class="hd-progress-fill"></div></div><div class="hd-scan-items"><div class="hd-scan-item"><span class="hd-check">â</span>Valid SSL certificate</div><div class="hd-scan-item"><span class="hd-cross">â</span>Privacy policy missing</div><div class="hd-scan-item"><span class="hd-cross">â</span>No DPO or privacy contact identified</div><div class="hd-scan-item"><span class="hd-cross">â</span>No information about data collected</div><div class="hd-scan-item"><span class="hd-cross">â</span>User rights not mentioned (GDPR Art. 13)</div><div class="hd-scan-item"><span class="hd-check">â</span>Partial legal notices</div><div class="hd-scan-item"><span class="hd-check">â</span>Business registration verified</div></div></div><!-- Phase 3: Score --><div class="hd-phase hd-phase-score"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad-privacy" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url(#hd-grad-privacy)"></path></svg><span class="hd-gauge-num">0</span></div><span class="hd-score-label">â Privacy policy missing</span></div><div class="hd-score-details"><div class="hd-detail"><span class="hd-dl">Company</span><span class="hd-dv">ACME BOUTIQUE LTD</span></div><div class="hd-detail"><span class="hd-dl">Registration</span><span class="hd-dv">Company No: 12345678</span></div><div class="hd-detail"><span class="hd-dl">Country</span><span class="hd-dv">United Kingdom / English</span></div><div class="hd-detail"><span class="hd-dl">CMS</span><span class="hd-dv">WordPress / Google Analytics</span></div><div class="hd-detail"><span class="hd-dl">Consent</span><span class="hd-dv">No CMP detected</span></div></div></div><!-- Phase 4: Document --><div class="hd-phase hd-phase-doc"><div class="hd-doc-preview"><div class="hd-doc-header"><span>Legal Document</span><span>Generated in 2026</span></div><h4>Privacy Policy</h4><div class="hd-doc-body"></div><div class="hd-doc-fade"></div></div><div class="hd-doc-sent">Document sent to [email protected]</div></div><!-- Phase 5: Result --><div class="hd-phase hd-phase-result"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad2-privacy" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill2" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url
226(#hd-grad2-privacy)"></path></svg><span class="hd-gauge-num2">47</span></div><div class="hd-confetti"><span></span><span></span><span></span><span></span><span></span><span></span></div><span class="hd-result-label">✅ Excellent compliance</span></div><div class="hd-result-warning">Avoid fines up to <strong>â¬20,000</strong> â get compliant now!</div></div></div><div class="hd-restart"><div class="hd-restart-fill"></div></div></div> 227
227<script>(function(){const config = "{\"id\":\"hd-privacy-er6ff1\",\"speed\":1.25,\"showCta\":false,\"ctaUrl\":\"/en/scan/\",\"basePhases\":{\"URL_TYPE\":{\"start\":0,\"duration\":1500},\"SCAN_CLICK\":{\"start\":1500,\"duration\":400},\"SCANNING\":{\"start\":1900,\"duration\":3200},\"SCORE\":{\"start\":5100,\"duration\":3000},\"DOCUMENT\":{\"start\":8100,\"duration\":3000},\"RESULT\":{\"start\":11100,\"duration\":3200},\"PAUSE\":{\"start\":14300,\"duration\":1000}},\"baseTotal\":15300,\"internal\":{\"URL_TYPE_DURATION\":1200,\"SCORE_ANIMATE_DURATION\":1500,\"SCORE_DETAIL_START\":1200,\"SCORE_DETAIL_STAGGER\":150,\"DOC_TYPE_DURATION\":2800,\"DOC_DELIVERED_DELAY\":3000,\"RESULT_ANIMATE_DURATION\":1200},\"scoreConfig\":{\"TARGET_SCORE\":42,\"FINAL_SCORE\":100,\"GAUGE_ARC\":236},\"content\":{\"heroTitle\":\"Analyze your site in 30 seconds\",\"urlPlaceholder\":\"acme-store.com\",\"btnLabel\":\"Analyze\",\"trustItems\":[\"No signup\",\"Instant result\",\"100% free\"],\"scanMessages\":[\"Connecting to site...\",\"Analyzing structure...\",\"Detecting cookies...\",\"Checking GDPR compliance...\",\"Analyzing legal documents...\",\"Verifying business registry...\",\"Calculating compliance score...\"],\"docLogo\":\"Legal Document\",\"docDate\":\"Generated in 2026\",\"emailSent\":\"Document sent to [email protected]\",\"resultLabel\":\"Excellent compliance\",\"resultWarning\":\"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!\",\"ctaText\":\"Protect my site now\",\"scanItems\":[{\"check\":true,\"text\":\"Valid SSL certificate\"},{\"check\":false,\"text\":\"Privacy policy missing\"},{\"check\":false,\"text\":\"No DPO or privacy contact identified\"},{\"check\":false,\"text\":\"No information about data collected\"},{\"check\":false,\"text\":\"User rights not mentioned (GDPR Art. 13)\"},{\"check\":true,\"text\":\"Partial legal notices\"},{\"check\":true,\"text\":\"Business registration verified\"}],\"scoreLabel\":\"â Privacy policy missing\",\"docTitle\":\"Privacy Policy\",\"docSections\":[{\"title\":\"1. Data Collection\",\"text\":\"We collect information you provide directly, such as your name, email address, and payment information. Technical data is also collected automatically in compliance with GDPR.\"},{\"title\":\"2. Use of Data\",\"text\":\"Your personal data is used to provide and improve our services, process your transactions, send account-related communications, and ensure the security of our platform.\"},{\"title\":\"3. Your GDPR Rights\",\"text\":\"Under the General Data Protection Regulation, you have the right to access, rectify, erase, restrict, and port your personal data.\"}]}}"; 228 229 // HeroDemo animation â see hero-demo/animation.ts for config docs 230 (function() { 231 const cfg = JSON.parse(config); 232 const el = document.getElementById(cfg.id); 233 if (!el) return; 234 235 const s = (ms) => Math.round(ms / cfg.speed); 236 const PHASES = {}; 237 for (const [k, v] of Object.entries(cfg.basePhases)) { 238 PHASES[k] = { start: s(v.start), duration: s(v.duration) }; 239 } 240 const TOTAL = s(cfg.baseTotal); 241 const I = {}; 242 for (const [k, v] of Object.entries(cfg.internal)) I[k] = s(v); 243 const SC = cfg.scoreConfig; 244 const t = cfg.content; 245 246 function easeOut(x) { return 1 - Math.pow(1 - x, 3); } 247 248 // CTA 249 if (!cfg.showCta) { const cta = el.querySelector('.hd-result-cta'); if (cta) cta.style.display = 'none'; } 250 251 const phaseEls = el.querySelectorAll('.hd-phase'); 252 let startTime, prevPhase = -1; 253 254 function animate(ts) { 255 if (!startTime) startTime = ts; 256 const elapsed = (ts - startTime) % TOTAL; 257 258 // Determine target phase 259 let target = -1; 260 if (elapsed < PHASES.SCANNING.start) target = 0; 261 else if (elapsed < PHASES.SCORE.start) target = 1; 262 else if (elapsed < PHASES.DOCUMENT.start) target = 2; 263 else if (elapsed < PHASES.RESULT.start) target = 3; 264 else if (elapsed < PHASES.PAUSE.start + PHASES.PAUSE.duration) target = 4; 265 266 // Transition phases 267 if (target !== prevPhase) {
268 phaseEls.forEach((p, i) => { 269 if (i === prevPhase) { p.classList.remove('hd-active'); p.classList.add('hd-exiting'); setTimeout(() => p.classList.remove('hd-exiting'), 400); } 270 else p.classList.remove('hd-active', 'hd-exiting'); 271 }); 272 if (target >= 0) phaseEls[target].classList.add('hd-active'); 273 prevPhase = target; 274 } 275 276 // Phase 1: URL typing 277 if (target === 0) { 278 const typed = el.querySelector('.hd-typed'); 279 const cursor = el.querySelector('.hd-cursor'); 280 const btn = el.querySelector('.hd-btn'); 281 if (elapsed < PHASES.SCAN_CLICK.start) { 282 const pct = Math.min(elapsed / I.URL_TYPE_DURATION, 1); 283 const chars = Math.floor(pct * t.urlPlaceholder.length); 284 typed.textContent = t.urlPlaceholder.substring(0, chars); 285 cursor.style.display = chars < t.urlPlaceholder.length ? 'inline-block' : 'none'; 286 btn.classList.remove('hd-pressed'); 287 } else { 288 typed.textContent = t.urlPlaceholder; 289 cursor.style.display = 'none'; 290 btn.classList.add('hd-pressed'); 291 } 292 } 293 294 // Phase 2: Scanning 295 if (target === 1) { 296 const pct = (elapsed - PHASES.SCANNING.start) / PHASES.SCANNING.duration; 297 el.querySelector('.hd-progress-fill').style.width = (pct * 100) + '%'; 298 const msgIdx = Math.min(Math.floor(pct * t.scanMessages.length), t.scanMessages.length - 1); 299 el.querySelector('.hd-scan-status').textContent = t.scanMessages[msgIdx]; 300 el.querySelectorAll('.hd-scan-item').forEach((item, i) => { 301 item.classList.toggle('hd-visible', pct > (i + 1) * 0.12); 302 }); 303 // Recap bounce: highlight cross items one by one before transitioning 304 const timeLeft = PHASES.SCORE.start - elapsed; 305 if (timeLeft < s(800)) { 306 const crossItems = Array.from(el.querySelectorAll('.hd-scan-item')).filter(item => item.querySelector('.hd-cross')); 307 const recapPct = 1 - (timeLeft / s(800)); 308 crossItems.forEach((item, i) => { 309 item.classList.toggle('hd-recap', recapPct > i / crossItems.length); 310 }); 311 } 312 } else { 313 el.querySelector('.hd-progress-fill').style.width = '0%'; 314 el.querySelectorAll('.hd-scan-item').forEach(item => { item.classList.remove('hd-visible', 'hd-flash', 'hd-recap'); }); 315 } 316 317 // Phase 3: Score 318 if (target === 2) { 319 const pct = Math.min(easeOut((elapsed - PHASES.SCORE.start) / I.SCORE_ANIMATE_DURATION), 1); 320 const score = Math.floor(pct * SC.TARGET_SCORE); 321 el.querySelector('.hd-gauge-num').textContent = score; 322 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 323 const se = elapsed - PHASES.SCORE.start; 324 el.querySelectorAll('.hd-detail').forEach((d, i) => { 325 d.classList.toggle('hd-visible', se > I.SCORE_DETAIL_START + i * I.SCORE_DETAIL_STAGGER); 326 }); 327 } else { 328 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC; 329 el.querySelector('.hd-gauge-num').textContent = '0'; 330 el.querySelectorAll('.hd-detail').forEach(d => d.classList.remove('hd-visible')); 331 } 332 333 // Phase 4: Document 334 if (target === 3) { 335 const de = elapsed - PHASES.DOCUMENT.start; 336 const pct = Math.min(de / I.DOC_TYPE_DURATION, 1); 337 const full = t.docSections.map(s => s.title + ' ' + s.text).join(' '); 338 const totalChars = Math.floor(pct * full.length); 339 let html = '', remaining = totalChars; 340 for (const sec of t.docSections) { 341 if (remaining <= 0) break; 342 const chars = Math.min(remaining, sec.title.length + sec.text.length); 343 if (chars <= sec.title.length) { 344 html += '<div class="hd-sec-title">' + sec.title.substring(0, chars) + '</div>'; 345 } else { 346 html += '<div class="hd-sec-title">' + sec.title + '</div><p>' + sec.text.substring(0, chars - sec.title.length) + '</p>'; 347 } 348 remaining -= chars; 349 } 350 if (pct < 1) html += '<span class="hd-tw-cursor"></span>'; 351 el.querySelector('.hd-doc-body').innerHTML = html;
352 el.querySelector('.hd-doc-sent').classList.toggle('hd-visible', de > I.DOC_DELIVERED_DELAY); 353 } else { 354 el.querySelector('.hd-doc-sent').classList.remove('hd-visible'); 355 } 356 357 // Phase 5: Result â score counter + confetti 358 if (target === 4) { 359 const re = elapsed - PHASES.RESULT.start; 360 const pct = Math.min(easeOut(re / I.RESULT_ANIMATE_DURATION), 1); 361 const score = Math.floor(SC.TARGET_SCORE + pct * (SC.FINAL_SCORE - SC.TARGET_SCORE)); 362 363 // Slot machine effect: briefly show random digits while animating 364 const numEl = el.querySelector('.hd-gauge-num2'); 365 if (pct < 0.85) { 366 const jitter = Math.random() > 0.3 ? score : score + Math.floor(Math.random() * 5 - 2); 367 numEl.textContent = Math.max(0, Math.min(100, jitter)); 368 } else { 369 numEl.textContent = score; 370 } 371 372 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 373 374 // Confetti burst when score reaches 100 375 const confetti = el.querySelector('.hd-confetti'); 376 if (score >= 100 && !confetti.classList.contains('hd-burst')) { 377 confetti.classList.add('hd-burst'); 378 } 379 } else { 380 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * SC.TARGET_SCORE / 100); 381 el.querySelector('.hd-gauge-num2').textContent = SC.TARGET_SCORE; 382 const confetti = el.querySelector('.hd-confetti'); 383 if (confetti) confetti.classList.remove('hd-burst'); 384 } 385 386 // Browser URL 387 const urlEl = el.querySelector('.hd-url-text'); 388 if (target <= 0) urlEl.textContent = 'weblegal.ai'; 389 else if (target === 1) urlEl.textContent = 'weblegal.ai/scan...'; 390 else if (target === 2) urlEl.textContent = 'weblegal.ai/score/' + SC.TARGET_SCORE; 391 else if (target === 3) urlEl.textContent = 'weblegal.ai/documents/...'; 392 else urlEl.textContent = 'weblegal.ai/score/100'; 393 394 // Restart bar 395 el.querySelector('.hd-restart-fill').style.transform = 'scaleX(' + (elapsed / TOTAL) + ')'; 396 397 requestAnimationFrame(animate); 398 } 399 requestAnimationFrame(animate); 400 })(); 401 })();</script>
401</div> <div id="hero-anim-terms" style="display:none"><link rel="stylesheet" href="/css/hero-demo.css"><!-- JS mode: live animation --> 402 <div class="hero-demo-container" id="hd-terms-qqwvwd" data-config="{"id":"hd-terms-qqwvwd","speed":1.25,"showCta":false,"ctaUrl":"/en/scan/","basePhases":{"URL_TYPE":{"start":0,"duration":1500},"SCAN_CLICK":{"start":1500,"duration":400},"SCANNING":{"start":1900,"duration":3200},"SCORE":{"start":5100,"duration":3000},"DOCUMENT":{"start":8100,"duration":3000},"RESULT":{"start":11100,"duration":3200},"PAUSE":{"start":14300,"duration":1000}},"baseTotal":15300,"internal":{"URL_TYPE_DURATION":1200,"SCORE_ANIMATE_DURATION":1500,"SCORE_DETAIL_START":1200,"SCORE_DETAIL_STAGGER":150,"DOC_TYPE_DURATION":2800,"DOC_DELIVERED_DELAY":3000,"RESULT_ANIMATE_DURATION":1200},"scoreConfig":{"TARGET_SCORE":51,"FINAL_SCORE":100,"GAUGE_ARC":236},"content":{"heroTitle":"Analyze your site in 30 seconds","urlPlaceholder":"acme-store.com","btnLabel":"Analyze","trustItems":["No signup","Instant result","100% free"],"scanMessages":["Connecting to site...","Analyzing structure...","Detecting cookies...","Checking GDPR compliance...","Analyzing legal documents...","Verifying business registry...","Calculating compliance score..."],"docLogo":"Legal Document","docDate":"Generated in 2026","emailSent":"Document sent to [email protected]","resultLabel":"Excellent compliance","resultWarning":"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!","ctaText":"Protect my site now","scanItems":[{"check":true,"text":"Valid SSL certificate"},{"check":false,"text":"Terms of use missing"},{"check":false,"text":"No intellectual property clause"},{"check":false,"text":"User responsibilities not defined"},{"check":false,"text":"No liability limitation clause"},{"check":true,"text":"Partial legal notices"},{"check":true,"text":"Business registration verified"}],"scoreLabel":"â Terms of use missing","docTitle":"Terms of Use","docSections":[{"title":"1. Purpose","text":"These terms of use define the conditions of access and use of the website. By accessing the site, users agree without reservation to these terms."},{"title":"2. Intellectual Property","text":"All content on the site (text, images, logos, software) is protected by intellectual property law. Any reproduction, even partial, is strictly prohibited without prior authorization."},{"title":"3. Liability","text":"The site publisher endeavors to ensure the accuracy of published information but cannot be held responsible for errors, omissions, or results obtained from the use of this information."}]}}"><div class="hd-browser-bar"><div class="hd-dots"><span></span><span></span><span></span></div><div class="hd-url"><span class="hd-lock">🔒</span><span class="hd-url-text">weblegal.ai</span></div></div><div class="hd-content"><!-- Phase 1: URL --><div class="hd-phase hd-phase-url hd-active"><h3 class="hd-subtitle">Analyze your site in 30 seconds</h3><div class="hd-url-input"><div class="hd-url-field"><span class="hd-typed"></span><span class="hd-cursor"></span></div><button class="hd-btn">🔍 Analyze</button></div><div class="hd-trust"><span>✔ No signup</span><span>✔ Instant result</span><span>✔ 100% free</span></div></div><!-- Phase 2: Scan --><div class="hd-phase hd-phase-scan"><div class="hd-scan-header"><div class="hd-spinner"></div><span class="hd-scan-status">Connecting to site...</span></div><div class="hd-progress"><div class="hd-progress-fill"></div></div><div class="hd-scan-items"><div class="hd-scan-item"><span class="hd-check">â</span>Valid SSL certificate</div><div class="hd-scan-item"><span class="hd-cross">â</span>Terms of use missing</div><div class="hd-scan-item"><span class="hd-cross">â</span>No intellectual property clause</div><div class="hd-scan-item"><span class="hd-cross">â</span>User responsibilities not defined</div><div class="hd-scan-item"><span class="hd-cross">â</span>No liability limitation clause</div><div class="hd-scan-item"><span class="hd-check">â</span>Partial legal notices</div><div class="hd-scan-item"><span class="hd-check">â</span>Business registration verified</div></div></div><!-- Phase 3: Score --><div class="hd-phase hd-phase-score"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad-terms" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url
402(#hd-grad-terms)"></path></svg><span class="hd-gauge-num">0</span></div><span class="hd-score-label">â Terms of use missing</span></div><div class="hd-score-details"><div class="hd-detail"><span class="hd-dl">Company</span><span class="hd-dv">ACME BOUTIQUE LTD</span></div><div class="hd-detail"><span class="hd-dl">Registration</span><span class="hd-dv">Company No: 12345678</span></div><div class="hd-detail"><span class="hd-dl">Country</span><span class="hd-dv">United Kingdom / English</span></div><div class="hd-detail"><span class="hd-dl">CMS</span><span class="hd-dv">WordPress / Google Analytics</span></div><div class="hd-detail"><span class="hd-dl">Consent</span><span class="hd-dv">No CMP detected</span></div></div></div><!-- Phase 4: Document --><div class="hd-phase hd-phase-doc"><div class="hd-doc-preview"><div class="hd-doc-header"><span>Legal Document</span><span>Generated in 2026</span></div><h4>Terms of Use</h4><div class="hd-doc-body"></div><div class="hd-doc-fade"></div></div><div class="hd-doc-sent">Document sent to [email protected]</div></div><!-- Phase 5: Result --><div class="hd-phase hd-phase-result"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad2-terms" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill2" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url(#hd-grad2-terms)"></path></svg><span class="hd-gauge-num2">47</span></div><div class="hd-confetti"><span></span><span></span><span></span><span></span><span></span><span></span></div><span class="hd-result-label">✅ Excellent compliance</span></div><div class="hd-result-warning">Avoid fines up to <strong>â¬20,000</strong> â get compliant now!</div></div></div><div class="hd-restart"><div class="hd-restart-fill"></div></div></div> 403
403<script>(function(){const config = "{\"id\":\"hd-terms-qqwvwd\",\"speed\":1.25,\"showCta\":false,\"ctaUrl\":\"/en/scan/\",\"basePhases\":{\"URL_TYPE\":{\"start\":0,\"duration\":1500},\"SCAN_CLICK\":{\"start\":1500,\"duration\":400},\"SCANNING\":{\"start\":1900,\"duration\":3200},\"SCORE\":{\"start\":5100,\"duration\":3000},\"DOCUMENT\":{\"start\":8100,\"duration\":3000},\"RESULT\":{\"start\":11100,\"duration\":3200},\"PAUSE\":{\"start\":14300,\"duration\":1000}},\"baseTotal\":15300,\"internal\":{\"URL_TYPE_DURATION\":1200,\"SCORE_ANIMATE_DURATION\":1500,\"SCORE_DETAIL_START\":1200,\"SCORE_DETAIL_STAGGER\":150,\"DOC_TYPE_DURATION\":2800,\"DOC_DELIVERED_DELAY\":3000,\"RESULT_ANIMATE_DURATION\":1200},\"scoreConfig\":{\"TARGET_SCORE\":51,\"FINAL_SCORE\":100,\"GAUGE_ARC\":236},\"content\":{\"heroTitle\":\"Analyze your site in 30 seconds\",\"urlPlaceholder\":\"acme-store.com\",\"btnLabel\":\"Analyze\",\"trustItems\":[\"No signup\",\"Instant result\",\"100% free\"],\"scanMessages\":[\"Connecting to site...\",\"Analyzing structure...\",\"Detecting cookies...\",\"Checking GDPR compliance...\",\"Analyzing legal documents...\",\"Verifying business registry...\",\"Calculating compliance score...\"],\"docLogo\":\"Legal Document\",\"docDate\":\"Generated in 2026\",\"emailSent\":\"Document sent to [email protected]\",\"resultLabel\":\"Excellent compliance\",\"resultWarning\":\"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!\",\"ctaText\":\"Protect my site now\",\"scanItems\":[{\"check\":true,\"text\":\"Valid SSL certificate\"},{\"check\":false,\"text\":\"Terms of use missing\"},{\"check\":false,\"text\":\"No intellectual property clause\"},{\"check\":false,\"text\":\"User responsibilities not defined\"},{\"check\":false,\"text\":\"No liability limitation clause\"},{\"check\":true,\"text\":\"Partial legal notices\"},{\"check\":true,\"text\":\"Business registration verified\"}],\"scoreLabel\":\"â Terms of use missing\",\"docTitle\":\"Terms of Use\",\"docSections\":[{\"title\":\"1. Purpose\",\"text\":\"These terms of use define the conditions of access and use of the website. By accessing the site, users agree without reservation to these terms.\"},{\"title\":\"2. Intellectual Property\",\"text\":\"All content on the site (text, images, logos, software) is protected by intellectual property law. Any reproduction, even partial, is strictly prohibited without prior authorization.\"},{\"title\":\"3. Liability\",\"text\":\"The site publisher endeavors to ensure the accuracy of published information but cannot be held responsible for errors, omissions, or results obtained from the use of this information.\"}]}}"; 404 405 // HeroDemo animation â see hero-demo/animation.ts for config docs 406 (function() { 407 const cfg = JSON.parse(config); 408 const el = document.getElementById(cfg.id); 409 if (!el) return; 410 411 const s = (ms) => Math.round(ms / cfg.speed); 412 const PHASES = {}; 413 for (const [k, v] of Object.entries(cfg.basePhases)) { 414 PHASES[k] = { start: s(v.start), duration: s(v.duration) }; 415 } 416 const TOTAL = s(cfg.baseTotal); 417 const I = {}; 418 for (const [k, v] of Object.entries(cfg.internal)) I[k] = s(v); 419 const SC = cfg.scoreConfig; 420 const t = cfg.content; 421 422 function easeOut(x) { return 1 - Math.pow(1 - x, 3); } 423 424 // CTA 425 if (!cfg.showCta) { const cta = el.querySelector('.hd-result-cta'); if (cta) cta.style.display = 'none'; } 426 427 const phaseEls = el.querySelectorAll('.hd-phase'); 428 let startTime, prevPhase = -1; 429 430 function animate(ts) { 431 if (!startTime) startTime = ts; 432 const elapsed = (ts - startTime) % TOTAL; 433 434 // Determine target phase 435 let target = -1; 436 if (elapsed < PHASES.SCANNING.start) target = 0; 437 else if (elapsed < PHASES.SCORE.start) target = 1; 438 else if (elapsed < PHASES.DOCUMENT.start) target = 2; 439 else if (elapsed < PHASES.RESULT.start) target = 3; 440 else if (elapsed < PHASES.PAUSE.start + PHASES.PAUSE.duration) target = 4; 441 442 // Transition phases 443 if (target !== prevPhase) {
444 phaseEls.forEach((p, i) => { 445 if (i === prevPhase) { p.classList.remove('hd-active'); p.classList.add('hd-exiting'); setTimeout(() => p.classList.remove('hd-exiting'), 400); } 446 else p.classList.remove('hd-active', 'hd-exiting'); 447 }); 448 if (target >= 0) phaseEls[target].classList.add('hd-active'); 449 prevPhase = target; 450 } 451 452 // Phase 1: URL typing 453 if (target === 0) { 454 const typed = el.querySelector('.hd-typed'); 455 const cursor = el.querySelector('.hd-cursor'); 456 const btn = el.querySelector('.hd-btn'); 457 if (elapsed < PHASES.SCAN_CLICK.start) { 458 const pct = Math.min(elapsed / I.URL_TYPE_DURATION, 1); 459 const chars = Math.floor(pct * t.urlPlaceholder.length); 460 typed.textContent = t.urlPlaceholder.substring(0, chars); 461 cursor.style.display = chars < t.urlPlaceholder.length ? 'inline-block' : 'none'; 462 btn.classList.remove('hd-pressed'); 463 } else { 464 typed.textContent = t.urlPlaceholder; 465 cursor.style.display = 'none'; 466 btn.classList.add('hd-pressed'); 467 } 468 } 469 470 // Phase 2: Scanning 471 if (target === 1) { 472 const pct = (elapsed - PHASES.SCANNING.start) / PHASES.SCANNING.duration; 473 el.querySelector('.hd-progress-fill').style.width = (pct * 100) + '%'; 474 const msgIdx = Math.min(Math.floor(pct * t.scanMessages.length), t.scanMessages.length - 1); 475 el.querySelector('.hd-scan-status').textContent = t.scanMessages[msgIdx]; 476 el.querySelectorAll('.hd-scan-item').forEach((item, i) => { 477 item.classList.toggle('hd-visible', pct > (i + 1) * 0.12); 478 }); 479 // Recap bounce: highlight cross items one by one before transitioning 480 const timeLeft = PHASES.SCORE.start - elapsed; 481 if (timeLeft < s(800)) { 482 const crossItems = Array.from(el.querySelectorAll('.hd-scan-item')).filter(item => item.querySelector('.hd-cross')); 483 const recapPct = 1 - (timeLeft / s(800)); 484 crossItems.forEach((item, i) => { 485 item.classList.toggle('hd-recap', recapPct > i / crossItems.length); 486 }); 487 } 488 } else { 489 el.querySelector('.hd-progress-fill').style.width = '0%'; 490 el.querySelectorAll('.hd-scan-item').forEach(item => { item.classList.remove('hd-visible', 'hd-flash', 'hd-recap'); }); 491 } 492 493 // Phase 3: Score 494 if (target === 2) { 495 const pct = Math.min(easeOut((elapsed - PHASES.SCORE.start) / I.SCORE_ANIMATE_DURATION), 1); 496 const score = Math.floor(pct * SC.TARGET_SCORE); 497 el.querySelector('.hd-gauge-num').textContent = score; 498 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 499 const se = elapsed - PHASES.SCORE.start; 500 el.querySelectorAll('.hd-detail').forEach((d, i) => { 501 d.classList.toggle('hd-visible', se > I.SCORE_DETAIL_START + i * I.SCORE_DETAIL_STAGGER); 502 }); 503 } else { 504 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC; 505 el.querySelector('.hd-gauge-num').textContent = '0'; 506 el.querySelectorAll('.hd-detail').forEach(d => d.classList.remove('hd-visible')); 507 } 508 509 // Phase 4: Document 510 if (target === 3) { 511 const de = elapsed - PHASES.DOCUMENT.start; 512 const pct = Math.min(de / I.DOC_TYPE_DURATION, 1); 513 const full = t.docSections.map(s => s.title + ' ' + s.text).join(' '); 514 const totalChars = Math.floor(pct * full.length); 515 let html = '', remaining = totalChars; 516 for (const sec of t.docSections) { 517 if (remaining <= 0) break; 518 const chars = Math.min(remaining, sec.title.length + sec.text.length); 519 if (chars <= sec.title.length) { 520 html += '<div class="hd-sec-title">' + sec.title.substring(0, chars) + '</div>'; 521 } else { 522 html += '<div class="hd-sec-title">' + sec.title + '</div><p>' + sec.text.substring(0, chars - sec.title.length) + '</p>'; 523 } 524 remaining -= chars; 525 } 526 if (pct < 1) html += '<span class="hd-tw-cursor"></span>'; 527 el.querySelector('.hd-doc-body').innerHTML = html;
528 el.querySelector('.hd-doc-sent').classList.toggle('hd-visible', de > I.DOC_DELIVERED_DELAY); 529 } else { 530 el.querySelector('.hd-doc-sent').classList.remove('hd-visible'); 531 } 532 533 // Phase 5: Result â score counter + confetti 534 if (target === 4) { 535 const re = elapsed - PHASES.RESULT.start; 536 const pct = Math.min(easeOut(re / I.RESULT_ANIMATE_DURATION), 1); 537 const score = Math.floor(SC.TARGET_SCORE + pct * (SC.FINAL_SCORE - SC.TARGET_SCORE)); 538 539 // Slot machine effect: briefly show random digits while animating 540 const numEl = el.querySelector('.hd-gauge-num2'); 541 if (pct < 0.85) { 542 const jitter = Math.random() > 0.3 ? score : score + Math.floor(Math.random() * 5 - 2); 543 numEl.textContent = Math.max(0, Math.min(100, jitter)); 544 } else { 545 numEl.textContent = score; 546 } 547 548 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 549 550 // Confetti burst when score reaches 100 551 const confetti = el.querySelector('.hd-confetti'); 552 if (score >= 100 && !confetti.classList.contains('hd-burst')) { 553 confetti.classList.add('hd-burst'); 554 } 555 } else { 556 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * SC.TARGET_SCORE / 100); 557 el.querySelector('.hd-gauge-num2').textContent = SC.TARGET_SCORE; 558 const confetti = el.querySelector('.hd-confetti'); 559 if (confetti) confetti.classList.remove('hd-burst'); 560 } 561 562 // Browser URL 563 const urlEl = el.querySelector('.hd-url-text'); 564 if (target <= 0) urlEl.textContent = 'weblegal.ai'; 565 else if (target === 1) urlEl.textContent = 'weblegal.ai/scan...'; 566 else if (target === 2) urlEl.textContent = 'weblegal.ai/score/' + SC.TARGET_SCORE; 567 else if (target === 3) urlEl.textContent = 'weblegal.ai/documents/...'; 568 else urlEl.textContent = 'weblegal.ai/score/100'; 569 570 // Restart bar 571 el.querySelector('.hd-restart-fill').style.transform = 'scaleX(' + (elapsed / TOTAL) + ')'; 572 573 requestAnimationFrame(animate); 574 } 575 requestAnimationFrame(animate); 576 })(); 577 })();</script>
577</div> <div id="hero-anim-cookies" style="display:none"><link rel="stylesheet" href="/css/hero-demo.css"><!-- JS mode: live animation --> 578 <div class="hero-demo-container" id="hd-cookies-gpon6b" data-config="{"id":"hd-cookies-gpon6b","speed":1.25,"showCta":false,"ctaUrl":"/en/scan/","basePhases":{"URL_TYPE":{"start":0,"duration":1500},"SCAN_CLICK":{"start":1500,"duration":400},"SCANNING":{"start":1900,"duration":3200},"SCORE":{"start":5100,"duration":3000},"DOCUMENT":{"start":8100,"duration":3000},"RESULT":{"start":11100,"duration":3200},"PAUSE":{"start":14300,"duration":1000}},"baseTotal":15300,"internal":{"URL_TYPE_DURATION":1200,"SCORE_ANIMATE_DURATION":1500,"SCORE_DETAIL_START":1200,"SCORE_DETAIL_STAGGER":150,"DOC_TYPE_DURATION":2800,"DOC_DELIVERED_DELAY":3000,"RESULT_ANIMATE_DURATION":1200},"scoreConfig":{"TARGET_SCORE":38,"FINAL_SCORE":100,"GAUGE_ARC":236},"content":{"heroTitle":"Analyze your site in 30 seconds","urlPlaceholder":"acme-store.com","btnLabel":"Analyze","trustItems":["No signup","Instant result","100% free"],"scanMessages":["Connecting to site...","Analyzing structure...","Detecting cookies...","Checking GDPR compliance...","Analyzing legal documents...","Verifying business registry...","Calculating compliance score..."],"docLogo":"Legal Document","docDate":"Generated in 2026","emailSent":"Document sent to [email protected]","resultLabel":"Excellent compliance","resultWarning":"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!","ctaText":"Protect my site now","scanItems":[{"check":true,"text":"Valid SSL certificate"},{"check":false,"text":"Cookie policy missing"},{"check":false,"text":"No consent banner detected"},{"check":false,"text":"Google Analytics without prior consent"},{"check":false,"text":"Third-party cookies set without notice"},{"check":true,"text":"Partial legal notices"},{"check":true,"text":"Business registration verified"}],"scoreLabel":"â Cookie policy missing","docTitle":"Cookie Policy","docSections":[{"title":"1. What are cookies?","text":"Cookies are small text files placed on your device when you visit a website. They are widely used to make websites work effectively and provide information to site owners."},{"title":"2. Types of cookies used","text":"We use essential cookies (necessary for operation), analytics cookies (to understand site usage), and preference cookies (to remember your settings)."},{"title":"3. Managing cookies","text":"You can control and manage cookies through your browser settings. You can also use our cookie preference center to customize your choices at any time."}]}}"><div class="hd-browser-bar"><div class="hd-dots"><span></span><span></span><span></span></div><div class="hd-url"><span class="hd-lock">🔒</span><span class="hd-url-text">weblegal.ai</span></div></div><div class="hd-content"><!-- Phase 1: URL --><div class="hd-phase hd-phase-url hd-active"><h3 class="hd-subtitle">Analyze your site in 30 seconds</h3><div class="hd-url-input"><div class="hd-url-field"><span class="hd-typed"></span><span class="hd-cursor"></span></div><button class="hd-btn">🔍 Analyze</button></div><div class="hd-trust"><span>✔ No signup</span><span>✔ Instant result</span><span>✔ 100% free</span></div></div><!-- Phase 2: Scan --><div class="hd-phase hd-phase-scan"><div class="hd-scan-header"><div class="hd-spinner"></div><span class="hd-scan-status">Connecting to site...</span></div><div class="hd-progress"><div class="hd-progress-fill"></div></div><div class="hd-scan-items"><div class="hd-scan-item"><span class="hd-check">â</span>Valid SSL certificate</div><div class="hd-scan-item"><span class="hd-cross">â</span>Cookie policy missing</div><div class="hd-scan-item"><span class="hd-cross">â</span>No consent banner detected</div><div class="hd-scan-item"><span class="hd-cross">â</span>
578Google Analytics without prior consent</div><div class="hd-scan-item"><span class="hd-cross">â</span>Third-party cookies set without notice</div><div class="hd-scan-item"><span class="hd-check">â</span>Partial legal notices</div><div class="hd-scan-item"><span class="hd-check">â</span>Business registration verified</div></div></div><!-- Phase 3: Score --><div class="hd-phase hd-phase-score"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad-cookies" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url(#hd-grad-cookies)"></path></svg><span class="hd-gauge-num">0</span></div><span class="hd-score-label">â Cookie policy missing</span></div><div class="hd-score-details"><div class="hd-detail"><span class="hd-dl">Company</span><span class="hd-dv">ACME BOUTIQUE LTD</span></div><div class="hd-detail"><span class="hd-dl">Registration</span><span class="hd-dv">Company No: 12345678</span></div><div class="hd-detail"><span class="hd-dl">Country</span><span class="hd-dv">United Kingdom / English</span></div><div class="hd-detail"><span class="hd-dl">CMS</span><span class="hd-dv">WordPress / Google Analytics</span></div><div class="hd-detail"><span class="hd-dl">Consent</span><span class="hd-dv">No CMP detected</span></div></div></div><!-- Phase 4: Document --><div class="hd-phase hd-phase-doc"><div class="hd-doc-preview"><div class="hd-doc-header"><span>Legal Document</span><span>Generated in 2026</span></div><h4>Cookie Policy</h4><div class="hd-doc-body"></div><div class="hd-doc-fade"></div></div><div class="hd-doc-sent">Document sent to [email protected]</div></div><!-- Phase 5: Result --><div class="hd-phase hd-phase-result"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad2-cookies" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill2" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url(#hd-grad2-cookies)"></path></svg><span class="hd-gauge-num2">47</span></div><div class="hd-confetti"><span></span><span></span><span></span><span></span><span></span><span></span></div><span class="hd-result-label">✅ Excellent compliance</span></div><div class="hd-result-warning">Avoid fines up to <strong>â¬20,000</strong> â get compliant now!</div></div></div><div class="hd-restart"><div class="hd-restart-fill"></div></div></div> 579
579<script>(function(){const config = "{\"id\":\"hd-cookies-gpon6b\",\"speed\":1.25,\"showCta\":false,\"ctaUrl\":\"/en/scan/\",\"basePhases\":{\"URL_TYPE\":{\"start\":0,\"duration\":1500},\"SCAN_CLICK\":{\"start\":1500,\"duration\":400},\"SCANNING\":{\"start\":1900,\"duration\":3200},\"SCORE\":{\"start\":5100,\"duration\":3000},\"DOCUMENT\":{\"start\":8100,\"duration\":3000},\"RESULT\":{\"start\":11100,\"duration\":3200},\"PAUSE\":{\"start\":14300,\"duration\":1000}},\"baseTotal\":15300,\"internal\":{\"URL_TYPE_DURATION\":1200,\"SCORE_ANIMATE_DURATION\":1500,\"SCORE_DETAIL_START\":1200,\"SCORE_DETAIL_STAGGER\":150,\"DOC_TYPE_DURATION\":2800,\"DOC_DELIVERED_DELAY\":3000,\"RESULT_ANIMATE_DURATION\":1200},\"scoreConfig\":{\"TARGET_SCORE\":38,\"FINAL_SCORE\":100,\"GAUGE_ARC\":236},\"content\":{\"heroTitle\":\"Analyze your site in 30 seconds\",\"urlPlaceholder\":\"acme-store.com\",\"btnLabel\":\"Analyze\",\"trustItems\":[\"No signup\",\"Instant result\",\"100% free\"],\"scanMessages\":[\"Connecting to site...\",\"Analyzing structure...\",\"Detecting cookies...\",\"Checking GDPR compliance...\",\"Analyzing legal documents...\",\"Verifying business registry...\",\"Calculating compliance score...\"],\"docLogo\":\"Legal Document\",\"docDate\":\"Generated in 2026\",\"emailSent\":\"Document sent to [email protected]\",\"resultLabel\":\"Excellent compliance\",\"resultWarning\":\"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!\",\"ctaText\":\"Protect my site now\",\"scanItems\":[{\"check\":true,\"text\":\"Valid SSL certificate\"},{\"check\":false,\"text\":\"Cookie policy missing\"},{\"check\":false,\"text\":\"No consent banner detected\"},{\"check\":false,\"text\":\"Google Analytics without prior consent\"},{\"check\":false,\"text\":\"Third-party cookies set without notice\"},{\"check\":true,\"text\":\"Partial legal notices\"},{\"check\":true,\"text\":\"Business registration verified\"}],\"scoreLabel\":\"â Cookie policy missing\",\"docTitle\":\"Cookie Policy\",\"docSections\":[{\"title\":\"1. What are cookies?\",\"text\":\"Cookies are small text files placed on your device when you visit a website. They are widely used to make websites work effectively and provide information to site owners.\"},{\"title\":\"2. Types of cookies used\",\"text\":\"We use essential cookies (necessary for operation), analytics cookies (to understand site usage), and preference cookies (to remember your settings).\"},{\"title\":\"3. Managing cookies\",\"text\":\"You can control and manage cookies through your browser settings. You can also use our cookie preference center to customize your choices at any time.\"}]}}"; 580 581 // HeroDemo animation â see hero-demo/animation.ts for config docs 582 (function() { 583 const cfg = JSON.parse(config); 584 const el = document.getElementById(cfg.id); 585 if (!el) return; 586 587 const s = (ms) => Math.round(ms / cfg.speed); 588 const PHASES = {}; 589 for (const [k, v] of Object.entries(cfg.basePhases)) { 590 PHASES[k] = { start: s(v.start), duration: s(v.duration) }; 591 } 592 const TOTAL = s(cfg.baseTotal); 593 const I = {}; 594 for (const [k, v] of Object.entries(cfg.internal)) I[k] = s(v); 595 const SC = cfg.scoreConfig; 596 const t = cfg.content; 597 598 function easeOut(x) { return 1 - Math.pow(1 - x, 3); } 599 600 // CTA 601 if (!cfg.showCta) { const cta = el.querySelector('.hd-result-cta'); if (cta) cta.style.display = 'none'; } 602 603 const phaseEls = el.querySelectorAll('.hd-phase'); 604 let startTime, prevPhase = -1; 605 606 function animate(ts) { 607 if (!startTime) startTime = ts; 608 const elapsed = (ts - startTime) % TOTAL; 609 610 // Determine target phase 611 let target = -1; 612 if (elapsed < PHASES.SCANNING.start) target = 0; 613 else if (elapsed < PHASES.SCORE.start) target = 1; 614 else if (elapsed < PHASES.DOCUMENT.start) target = 2; 615 else if (elapsed < PHASES.RESULT.start) target = 3; 616 else if (elapsed < PHASES.PAUSE.start + PHASES.PAUSE.duration) target = 4; 617 618 // Transition phases 619 if (target !== prevPhase) {
620 phaseEls.forEach((p, i) => { 621 if (i === prevPhase) { p.classList.remove('hd-active'); p.classList.add('hd-exiting'); setTimeout(() => p.classList.remove('hd-exiting'), 400); } 622 else p.classList.remove('hd-active', 'hd-exiting'); 623 }); 624 if (target >= 0) phaseEls[target].classList.add('hd-active'); 625 prevPhase = target; 626 } 627 628 // Phase 1: URL typing 629 if (target === 0) { 630 const typed = el.querySelector('.hd-typed'); 631 const cursor = el.querySelector('.hd-cursor'); 632 const btn = el.querySelector('.hd-btn'); 633 if (elapsed < PHASES.SCAN_CLICK.start) { 634 const pct = Math.min(elapsed / I.URL_TYPE_DURATION, 1); 635 const chars = Math.floor(pct * t.urlPlaceholder.length); 636 typed.textContent = t.urlPlaceholder.substring(0, chars); 637 cursor.style.display = chars < t.urlPlaceholder.length ? 'inline-block' : 'none'; 638 btn.classList.remove('hd-pressed'); 639 } else { 640 typed.textContent = t.urlPlaceholder; 641 cursor.style.display = 'none'; 642 btn.classList.add('hd-pressed'); 643 } 644 } 645 646 // Phase 2: Scanning 647 if (target === 1) { 648 const pct = (elapsed - PHASES.SCANNING.start) / PHASES.SCANNING.duration; 649 el.querySelector('.hd-progress-fill').style.width = (pct * 100) + '%'; 650 const msgIdx = Math.min(Math.floor(pct * t.scanMessages.length), t.scanMessages.length - 1); 651 el.querySelector('.hd-scan-status').textContent = t.scanMessages[msgIdx]; 652 el.querySelectorAll('.hd-scan-item').forEach((item, i) => { 653 item.classList.toggle('hd-visible', pct > (i + 1) * 0.12); 654 }); 655 // Recap bounce: highlight cross items one by one before transitioning 656 const timeLeft = PHASES.SCORE.start - elapsed; 657 if (timeLeft < s(800)) { 658 const crossItems = Array.from(el.querySelectorAll('.hd-scan-item')).filter(item => item.querySelector('.hd-cross')); 659 const recapPct = 1 - (timeLeft / s(800)); 660 crossItems.forEach((item, i) => { 661 item.classList.toggle('hd-recap', recapPct > i / crossItems.length); 662 }); 663 } 664 } else { 665 el.querySelector('.hd-progress-fill').style.width = '0%'; 666 el.querySelectorAll('.hd-scan-item').forEach(item => { item.classList.remove('hd-visible', 'hd-flash', 'hd-recap'); }); 667 } 668 669 // Phase 3: Score 670 if (target === 2) { 671 const pct = Math.min(easeOut((elapsed - PHASES.SCORE.start) / I.SCORE_ANIMATE_DURATION), 1); 672 const score = Math.floor(pct * SC.TARGET_SCORE); 673 el.querySelector('.hd-gauge-num').textContent = score; 674 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 675 const se = elapsed - PHASES.SCORE.start; 676 el.querySelectorAll('.hd-detail').forEach((d, i) => { 677 d.classList.toggle('hd-visible', se > I.SCORE_DETAIL_START + i * I.SCORE_DETAIL_STAGGER); 678 }); 679 } else { 680 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC; 681 el.querySelector('.hd-gauge-num').textContent = '0'; 682 el.querySelectorAll('.hd-detail').forEach(d => d.classList.remove('hd-visible')); 683 } 684 685 // Phase 4: Document 686 if (target === 3) { 687 const de = elapsed - PHASES.DOCUMENT.start; 688 const pct = Math.min(de / I.DOC_TYPE_DURATION, 1); 689 const full = t.docSections.map(s => s.title + ' ' + s.text).join(' '); 690 const totalChars = Math.floor(pct * full.length); 691 let html = '', remaining = totalChars; 692 for (const sec of t.docSections) { 693 if (remaining <= 0) break; 694 const chars = Math.min(remaining, sec.title.length + sec.text.length); 695 if (chars <= sec.title.length) { 696 html += '<div class="hd-sec-title">' + sec.title.substring(0, chars) + '</div>'; 697 } else { 698 html += '<div class="hd-sec-title">' + sec.title + '</div><p>' + sec.text.substring(0, chars - sec.title.length) + '</p>'; 699 } 700 remaining -= chars; 701 } 702 if (pct < 1) html += '<span class="hd-tw-cursor"></span>'; 703 el.querySelector('.hd-doc-body').innerHTML = html;
704 el.querySelector('.hd-doc-sent').classList.toggle('hd-visible', de > I.DOC_DELIVERED_DELAY); 705 } else { 706 el.querySelector('.hd-doc-sent').classList.remove('hd-visible'); 707 } 708 709 // Phase 5: Result â score counter + confetti 710 if (target === 4) { 711 const re = elapsed - PHASES.RESULT.start; 712 const pct = Math.min(easeOut(re / I.RESULT_ANIMATE_DURATION), 1); 713 const score = Math.floor(SC.TARGET_SCORE + pct * (SC.FINAL_SCORE - SC.TARGET_SCORE)); 714 715 // Slot machine effect: briefly show random digits while animating 716 const numEl = el.querySelector('.hd-gauge-num2'); 717 if (pct < 0.85) { 718 const jitter = Math.random() > 0.3 ? score : score + Math.floor(Math.random() * 5 - 2); 719 numEl.textContent = Math.max(0, Math.min(100, jitter)); 720 } else { 721 numEl.textContent = score; 722 } 723 724 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 725 726 // Confetti burst when score reaches 100 727 const confetti = el.querySelector('.hd-confetti'); 728 if (score >= 100 && !confetti.classList.contains('hd-burst')) { 729 confetti.classList.add('hd-burst'); 730 } 731 } else { 732 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * SC.TARGET_SCORE / 100); 733 el.querySelector('.hd-gauge-num2').textContent = SC.TARGET_SCORE; 734 const confetti = el.querySelector('.hd-confetti'); 735 if (confetti) confetti.classList.remove('hd-burst'); 736 } 737 738 // Browser URL 739 const urlEl = el.querySelector('.hd-url-text'); 740 if (target <= 0) urlEl.textContent = 'weblegal.ai'; 741 else if (target === 1) urlEl.textContent = 'weblegal.ai/scan...'; 742 else if (target === 2) urlEl.textContent = 'weblegal.ai/score/' + SC.TARGET_SCORE; 743 else if (target === 3) urlEl.textContent = 'weblegal.ai/documents/...'; 744 else urlEl.textContent = 'weblegal.ai/score/100'; 745 746 // Restart bar 747 el.querySelector('.hd-restart-fill').style.transform = 'scaleX(' + (elapsed / TOTAL) + ')'; 748 749 requestAnimationFrame(animate); 750 } 751 requestAnimationFrame(animate); 752 })(); 753 })();</script>
753</div> <div id="hero-anim-tos" style="display:none"><link rel="stylesheet" href="/css/hero-demo.css"><!-- JS mode: live animation --> 754 <div class="hero-demo-container" id="hd-terms-of-sale-evin8s" data-config="{"id":"hd-terms-of-sale-evin8s","speed":1.25,"showCta":false,"ctaUrl":"/en/scan/","basePhases":{"URL_TYPE":{"start":0,"duration":1500},"SCAN_CLICK":{"start":1500,"duration":400},"SCANNING":{"start":1900,"duration":3200},"SCORE":{"start":5100,"duration":3000},"DOCUMENT":{"start":8100,"duration":3000},"RESULT":{"start":11100,"duration":3200},"PAUSE":{"start":14300,"duration":1000}},"baseTotal":15300,"internal":{"URL_TYPE_DURATION":1200,"SCORE_ANIMATE_DURATION":1500,"SCORE_DETAIL_START":1200,"SCORE_DETAIL_STAGGER":150,"DOC_TYPE_DURATION":2800,"DOC_DELIVERED_DELAY":3000,"RESULT_ANIMATE_DURATION":1200},"scoreConfig":{"TARGET_SCORE":47,"FINAL_SCORE":100,"GAUGE_ARC":236},"content":{"heroTitle":"Analyze your site in 30 seconds","urlPlaceholder":"acme-store.com","btnLabel":"Analyze","trustItems":["No signup","Instant result","100% free"],"scanMessages":["Connecting to site...","Analyzing structure...","Detecting cookies...","Checking GDPR compliance...","Analyzing legal documents...","Verifying business registry...","Calculating compliance score..."],"docLogo":"Legal Document","docDate":"Generated in 2026","emailSent":"Document sent to [email protected]","resultLabel":"Excellent compliance","resultWarning":"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!","ctaText":"Protect my site now","scanItems":[{"check":true,"text":"Valid SSL certificate"},{"check":false,"text":"Terms of sale missing"},{"check":false,"text":"No withdrawal rights information"},{"check":false,"text":"Payment terms not specified"},{"check":false,"text":"Delivery policy missing"},{"check":true,"text":"Partial legal notices"},{"check":true,"text":"Business registration verified"}],"scoreLabel":"â Terms of sale missing","docTitle":"Terms of Sale","docSections":[{"title":"1. Scope and application","text":"These terms of sale apply to all orders placed on the website. Any order implies unconditional acceptance of these terms by the buyer."},{"title":"2. Pricing and payment","text":"Prices are displayed in euros including all taxes. Payment is made at the time of order through the secure payment methods offered on the site."},{"title":"3. Right of withdrawal","text":"In accordance with consumer protection law, the buyer has 14 days from receipt to exercise the right of withdrawal without having to justify reasons."}]}}"><div class="hd-browser-bar"><div class="hd-dots"><span></span><span></span><span></span></div><div class="hd-url"><span class="hd-lock">🔒</span><span class="hd-url-text">weblegal.ai</span></div></div><div class="hd-content"><!-- Phase 1: URL --><div class="hd-phase hd-phase-url hd-active"><h3 class="hd-subtitle">Analyze your site in 30 seconds</h3><div class="hd-url-input"><div class="hd-url-field"><span class="hd-typed"></span><span class="hd-cursor"></span></div><button class="hd-btn">🔍 Analyze</button></div><div class="hd-trust"><span>✔ No signup</span><span>✔ Instant result</span><span>✔ 100% free</span></div></div><!-- Phase 2: Scan --><div class="hd-phase hd-phase-scan"><div class="hd-scan-header"><div class="hd-spinner"></div><span class="hd-scan-status">Connecting to site...</span></div><div class="hd-progress"><div class="hd-progress-fill"></div></div><div class="hd-scan-items"><div class="hd-scan-item"><span class="hd-check">â</span>Valid SSL certificate</div><div class="hd-scan-item"><span class="hd-cross">â</span>Terms of sale missing</div><div class="hd-scan-item"><span class="hd-cross">â</span>No withdrawal rights information</div><div class="hd-scan-item"><span class="hd-cross">â</span>Payment terms not specified</div><div class="hd-scan-item"><span class="hd-cross">â</span>Delivery policy missing</div><div class="hd-scan-item"><span class="hd-check">â</span>Partial legal notices</div><div class="hd-scan-item"><span class="hd-check">â</span>Business registration verified</div></div></div><!-- Phase 3: Score --><div class="hd-phase hd-phase-score"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad-terms-of-sale" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url
754(#hd-grad-terms-of-sale)"></path></svg><span class="hd-gauge-num">0</span></div><span class="hd-score-label">â Terms of sale missing</span></div><div class="hd-score-details"><div class="hd-detail"><span class="hd-dl">Company</span><span class="hd-dv">ACME BOUTIQUE LTD</span></div><div class="hd-detail"><span class="hd-dl">Registration</span><span class="hd-dv">Company No: 12345678</span></div><div class="hd-detail"><span class="hd-dl">Country</span><span class="hd-dv">United Kingdom / English</span></div><div class="hd-detail"><span class="hd-dl">CMS</span><span class="hd-dv">WordPress / Google Analytics</span></div><div class="hd-detail"><span class="hd-dl">Consent</span><span class="hd-dv">No CMP detected</span></div></div></div><!-- Phase 4: Document --><div class="hd-phase hd-phase-doc"><div class="hd-doc-preview"><div class="hd-doc-header"><span>Legal Document</span><span>Generated in 2026</span></div><h4>Terms of Sale</h4><div class="hd-doc-body"></div><div class="hd-doc-fade"></div></div><div class="hd-doc-sent">Document sent to [email protected]</div></div><!-- Phase 5: Result --><div class="hd-phase hd-phase-result"><div class="hd-score-display"><div class="hd-gauge"><svg viewBox="0 0 180 100"><defs><linearGradient id="hd-grad2-terms-of-sale" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ef4444"></stop><stop offset="30%" stop-color="#f59e0b"></stop><stop offset="60%" stop-color="#eab308"></stop><stop offset="100%" stop-color="#10b981"></stop></linearGradient></defs><path class="hd-gauge-bg" d="M 15 90 A 75 75 0 0 1 165 90"></path><path class="hd-gauge-fill2" d="M 15 90 A 75 75 0 0 1 165 90" stroke="url(#hd-grad2-terms-of-sale)"></path></svg><span class="hd-gauge-num2">47</span></div><div class="hd-confetti"><span></span><span></span><span></span><span></span><span></span><span></span></div><span class="hd-result-label">✅ Excellent compliance</span></div><div class="hd-result-warning">Avoid fines up to <strong>â¬20,000</strong> â get compliant now!</div></div></div><div class="hd-restart"><div class="hd-restart-fill"></div></div></div> 755
755<script>(function(){const config = "{\"id\":\"hd-terms-of-sale-evin8s\",\"speed\":1.25,\"showCta\":false,\"ctaUrl\":\"/en/scan/\",\"basePhases\":{\"URL_TYPE\":{\"start\":0,\"duration\":1500},\"SCAN_CLICK\":{\"start\":1500,\"duration\":400},\"SCANNING\":{\"start\":1900,\"duration\":3200},\"SCORE\":{\"start\":5100,\"duration\":3000},\"DOCUMENT\":{\"start\":8100,\"duration\":3000},\"RESULT\":{\"start\":11100,\"duration\":3200},\"PAUSE\":{\"start\":14300,\"duration\":1000}},\"baseTotal\":15300,\"internal\":{\"URL_TYPE_DURATION\":1200,\"SCORE_ANIMATE_DURATION\":1500,\"SCORE_DETAIL_START\":1200,\"SCORE_DETAIL_STAGGER\":150,\"DOC_TYPE_DURATION\":2800,\"DOC_DELIVERED_DELAY\":3000,\"RESULT_ANIMATE_DURATION\":1200},\"scoreConfig\":{\"TARGET_SCORE\":47,\"FINAL_SCORE\":100,\"GAUGE_ARC\":236},\"content\":{\"heroTitle\":\"Analyze your site in 30 seconds\",\"urlPlaceholder\":\"acme-store.com\",\"btnLabel\":\"Analyze\",\"trustItems\":[\"No signup\",\"Instant result\",\"100% free\"],\"scanMessages\":[\"Connecting to site...\",\"Analyzing structure...\",\"Detecting cookies...\",\"Checking GDPR compliance...\",\"Analyzing legal documents...\",\"Verifying business registry...\",\"Calculating compliance score...\"],\"docLogo\":\"Legal Document\",\"docDate\":\"Generated in 2026\",\"emailSent\":\"Document sent to [email protected]\",\"resultLabel\":\"Excellent compliance\",\"resultWarning\":\"Avoid fines up to <strong>â¬20,000</strong> â get compliant now!\",\"ctaText\":\"Protect my site now\",\"scanItems\":[{\"check\":true,\"text\":\"Valid SSL certificate\"},{\"check\":false,\"text\":\"Terms of sale missing\"},{\"check\":false,\"text\":\"No withdrawal rights information\"},{\"check\":false,\"text\":\"Payment terms not specified\"},{\"check\":false,\"text\":\"Delivery policy missing\"},{\"check\":true,\"text\":\"Partial legal notices\"},{\"check\":true,\"text\":\"Business registration verified\"}],\"scoreLabel\":\"â Terms of sale missing\",\"docTitle\":\"Terms of Sale\",\"docSections\":[{\"title\":\"1. Scope and application\",\"text\":\"These terms of sale apply to all orders placed on the website. Any order implies unconditional acceptance of these terms by the buyer.\"},{\"title\":\"2. Pricing and payment\",\"text\":\"Prices are displayed in euros including all taxes. Payment is made at the time of order through the secure payment methods offered on the site.\"},{\"title\":\"3. Right of withdrawal\",\"text\":\"In accordance with consumer protection law, the buyer has 14 days from receipt to exercise the right of withdrawal without having to justify reasons.\"}]}}"; 756 757 // HeroDemo animation â see hero-demo/animation.ts for config docs 758 (function() { 759 const cfg = JSON.parse(config); 760 const el = document.getElementById(cfg.id); 761 if (!el) return; 762 763 const s = (ms) => Math.round(ms / cfg.speed); 764 const PHASES = {}; 765 for (const [k, v] of Object.entries(cfg.basePhases)) { 766 PHASES[k] = { start: s(v.start), duration: s(v.duration) }; 767 } 768 const TOTAL = s(cfg.baseTotal); 769 const I = {}; 770 for (const [k, v] of Object.entries(cfg.internal)) I[k] = s(v); 771 const SC = cfg.scoreConfig; 772 const t = cfg.content; 773 774 function easeOut(x) { return 1 - Math.pow(1 - x, 3); } 775 776 // CTA 777 if (!cfg.showCta) { const cta = el.querySelector('.hd-result-cta'); if (cta) cta.style.display = 'none'; } 778 779 const phaseEls = el.querySelectorAll('.hd-phase'); 780 let startTime, prevPhase = -1; 781 782 function animate(ts) { 783 if (!startTime) startTime = ts; 784 const elapsed = (ts - startTime) % TOTAL; 785 786 // Determine target phase 787 let target = -1; 788 if (elapsed < PHASES.SCANNING.start) target = 0; 789 else if (elapsed < PHASES.SCORE.start) target = 1; 790 else if (elapsed < PHASES.DOCUMENT.start) target = 2; 791 else if (elapsed < PHASES.RESULT.start) target = 3; 792 else if (elapsed < PHASES.PAUSE.start + PHASES.PAUSE.duration) target = 4; 793 794 // Transition phases 795 if (target !== prevPhase) { 796 phaseEls.forEach((p, i) => { 797 if (i === prevPhase) { p.classList.remove('hd-active'); p.classList.add('hd-exiting'); setTimeout(() => p.classList.remove('hd-exiting'), 400); } 798 else p.classList.remove('hd-active', 'hd-exiting'); 799 }); 800 if (target >= 0) phaseEls[target].classList.add('hd-active'); 801 prevPhase = target; 802 } 803 804 // Phase 1: URL typing 805 if (target === 0) { 806 const typed = el.querySelector('.hd-typed'); 807 const cursor = el.querySelector('.hd-cursor'); 808 const btn = el.querySelector('.hd-btn'); 809 if (elapsed < PHASES.SCAN_CLICK.start) { 810 const pct = Math.min(elapsed / I.URL_TYPE_DURATION, 1); 811 const chars = Math.floor(pct * t.urlPlaceholder.length); 812 typed.textContent = t.urlPlaceholder.substring(0, chars); 813 cursor.style.display = chars < t.urlPlaceholder.length ? 'inline-block' : 'none'; 814 btn.classList.remove('hd-pressed'); 815 } else { 816 typed.textContent = t.urlPlaceholder; 817 cursor.style.display = 'none'; 818 btn.classList.add('hd-pressed'); 819 } 820 } 821 822 // Phase 2: Scanning 823 if (target === 1) { 824 const pct = (elapsed - PHASES.SCANNING.start) / PHASES.SCANNING.duration; 825 el.querySelector('.hd-progress-fill').style.width = (pct * 100) + '%'; 826 const msgIdx = Math.min(Math.floor(pct * t.scanMessages.length), t.scanMessages.length - 1); 827 el.querySelector('.hd-scan-status').textContent = t.scanMessages[msgIdx]; 828 el.querySelectorAll('.hd-scan-item').forEach((item, i) => { 829 item.classList.toggle('hd-visible', pct > (i + 1) * 0.12); 830 }); 831 // Recap bounce: highlight cross items one by one before transitioning 832 const timeLeft = PHASES.SCORE.start - elapsed; 833 if (timeLeft < s(800)) { 834 const crossItems = Array.from(el.querySelectorAll('.hd-scan-item')).filter(item => item.querySelector('.hd-cross')); 835 const recapPct = 1 - (timeLeft / s(800));
836 crossItems.forEach((item, i) => { 837 item.classList.toggle('hd-recap', recapPct > i / crossItems.length); 838 }); 839 } 840 } else { 841 el.querySelector('.hd-progress-fill').style.width = '0%'; 842 el.querySelectorAll('.hd-scan-item').forEach(item => { item.classList.remove('hd-visible', 'hd-flash', 'hd-recap'); }); 843 } 844 845 // Phase 3: Score 846 if (target === 2) { 847 const pct = Math.min(easeOut((elapsed - PHASES.SCORE.start) / I.SCORE_ANIMATE_DURATION), 1); 848 const score = Math.floor(pct * SC.TARGET_SCORE); 849 el.querySelector('.hd-gauge-num').textContent = score; 850 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 851 const se = elapsed - PHASES.SCORE.start; 852 el.querySelectorAll('.hd-detail').forEach((d, i) => { 853 d.classList.toggle('hd-visible', se > I.SCORE_DETAIL_START + i * I.SCORE_DETAIL_STAGGER); 854 }); 855 } else { 856 el.querySelector('.hd-gauge-fill').style.strokeDashoffset = SC.GAUGE_ARC; 857 el.querySelector('.hd-gauge-num').textContent = '0'; 858 el.querySelectorAll('.hd-detail').forEach(d => d.classList.remove('hd-visible')); 859 } 860 861 // Phase 4: Document 862 if (target === 3) { 863 const de = elapsed - PHASES.DOCUMENT.start; 864 const pct = Math.min(de / I.DOC_TYPE_DURATION, 1); 865 const full = t.docSections.map(s => s.title + ' ' + s.text).join(' '); 866 const totalChars = Math.floor(pct * full.length); 867 let html = '', remaining = totalChars; 868 for (const sec of t.docSections) { 869 if (remaining <= 0) break; 870 const chars = Math.min(remaining, sec.title.length + sec.text.length); 871 if (chars <= sec.title.length) { 872 html += '<div class="hd-sec-title">' + sec.title.substring(0, chars) + '</div>'; 873 } else { 874 html += '<div class="hd-sec-title">' + sec.title + '</div><p>' + sec.text.substring(0, chars - sec.title.length) + '</p>'; 875 } 876 remaining -= chars; 877 } 878 if (pct < 1) html += '<span class="hd-tw-cursor"></span>'; 879 el.querySelector('.hd-doc-body').innerHTML = html; 880 el.querySelector('.hd-doc-sent').classList.toggle('hd-visible', de > I.DOC_DELIVERED_DELAY); 881 } else { 882 el.querySelector('.hd-doc-sent').classList.remove('hd-visible'); 883 } 884 885 // Phase 5: Result â score counter + confetti 886 if (target === 4) { 887 const re = elapsed - PHASES.RESULT.start; 888 const pct = Math.min(easeOut(re / I.RESULT_ANIMATE_DURATION), 1); 889 const score = Math.floor(SC.TARGET_SCORE + pct * (SC.FINAL_SCORE - SC.TARGET_SCORE)); 890 891 // Slot machine effect: briefly show random digits while animating 892 const numEl = el.querySelector('.hd-gauge-num2'); 893 if (pct < 0.85) { 894 const jitter = Math.random() > 0.3 ? score : score + Math.floor(Math.random() * 5 - 2); 895 numEl.textContent = Math.max(0, Math.min(100, jitter)); 896 } else { 897 numEl.textContent = score; 898 } 899 900 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * score / 100); 901 902 // Confetti burst when score reaches 100 903 const confetti = el.querySelector('.hd-confetti'); 904 if (score >= 100 && !confetti.classList.contains('hd-burst')) { 905 confetti.classList.add('hd-burst'); 906 } 907 } else { 908 el.querySelector('.hd-gauge-fill2').style.strokeDashoffset = SC.GAUGE_ARC - (SC.GAUGE_ARC * SC.TARGET_SCORE / 100); 909 el.querySelector('.hd-gauge-num2').textContent = SC.TARGET_SCORE; 910 const confetti = el.querySelector('.hd-confetti'); 911 if (confetti) confetti.classList.remove('hd-burst'); 912 } 913 914 // Browser URL 915 const urlEl = el.querySelector('.hd-url-text'); 916 if (target <= 0) urlEl.textContent = 'weblegal.ai'; 917 else if (target === 1) urlEl.textContent = 'weblegal.ai/scan...'; 918 else if (target === 2) urlEl.textContent = 'weblegal.ai/score/' + SC.TARGET_SCORE; 919 else if (target === 3) urlEl.textContent = 'weblegal.ai/documents/...'; 920 else urlEl.textContent = 'weblegal.ai/score/100'; 921 922 // Restart bar 923 el.querySelector('.hd-restart-fill').style.transform = 'scaleX(' + (elapsed / TOTAL) + ')'; 924 925 requestAnimationFrame(animate); 926 } 927 requestAnimationFrame(animate); 928 })(); 929 })();</script>
929</div> </div> </div> </section> <!-- A/B hero variant selection â runs immediately to avoid flicker -->
929<script> 930 (function() { 931 var h1 = document.getElementById('hero-h1'); 932 var sub = document.getElementById('hero-subtitle'); 933 if (!h1 || !sub) return; 934 935 // Disable A/B testing on jurisdiction-specific pages (they have correct static content) 936 // A/B test data-b-* attributes are GDPR-specific and would override jurisdiction content 937 // TODO: re-implement A/B testing with jurisdiction-aware variants (issue #16) 938 var path = window.location.pathname; 939 var jurisdictionPages = ['/en-us/', '/en-gb/', '/en-ca/', '/en-au/', '/pt-br/', '/fr-ca/', '/fr-be/', '/fr-ch/', '/de-ch/', '/de-at/', '/es-mx/']; 940 var isJurisdictionPage = jurisdictionPages.some(function(p) { return path.indexOf(p) !== -1; }); 941 if (isJurisdictionPage) { 942 window.__heroVariant = 'A'; // Always variant A on jurisdiction pages 943 944 // Read or assign variant (cookie persists 30 days) 945 } else { 946 var match = document.cookie.match(/hero_ab=([AB])/); 947 var variant = match ? match[1] : (Math.random() < 0.5 ? 'A' : 'B'); 948 if (!match) { 949 document.cookie = 'hero_ab=' + variant + ';path=/;max-age=' + (30 * 86400) + ';SameSite=Lax'; 950 } 951 952 // Swap to variant B if selected 953 if (variant === 'B') { 954 var p1 = h1.dataset.bPart1; 955 var p2 = h1.dataset.bPart2; 956 var p3 = h1.dataset.bPart3; 957 if (p1 || p2) { 958 var highlight = h1.querySelector('.gradient-highlight'); 959 // Rebuild H1: "part1 <span>part2</span> part3" 960 h1.innerHTML = (p1 || '') + ' <span class="gradient-highlight">' + (p2 || '') + '</span>' + (p3 ? ' ' + p3 : ''); 961 } 962 var bSub = sub.dataset.bSubtitle; 963 if (bSub) sub.innerHTML = bSub; 964 } 965 966 // Store variant for downstream tracking (URL submit, conversions) 967 window.__heroVariant = variant; 968 969 // GA4 event â track which variant was shown 970 function trackVariant() { 971 if (typeof gtag === 'function') { 972 gtag('event', 'hero_variant_shown', { 973 hero_variant: variant, 974 event_category: 'ab_test', 975 event_label: 'hero_h1_' + variant 976 }); 977 } 978 } 979 // gtag may not be loaded yet â defer if needed 980 if (typeof gtag === 'function') { trackVariant(); } 981 else { window.addEventListener('load', trackVariant); } 982 } // end else (non-jurisdiction pages) 983 })(); 984 </script>
984 <!-- Hero visual: pick a random animation variant on EVERY page load. 985 No cookie persistence â we want visitors to see a different document 986 each time they refresh the homepage (variety > statistical A/B). 987 Carousel (variant A) is currently disabled, pool = B/C/D/E. 988 TODO: reintroduce carousel in the pool once its sizing is stable. -->
988<script> 989 (function() { 990 var animMap = { B: 'privacy', C: 'terms', D: 'cookies', E: 'tos' }; 991 var variants = Object.keys(animMap); 992 var variant = variants[Math.floor(Math.random() * variants.length)]; 993 994 // Clean up any legacy hero_visual cookie so returning visitors get 995 // the fresh random behavior instead of a 30-day-sticky pick. 996 document.cookie = 'hero_visual=; path=/; max-age=0; SameSite=Lax'; 997 998 var carousel = document.getElementById('hero-visual-carousel'); 999 var animation = document.getElementById('hero-visual-animation'); 1000 if (carousel) carousel.style.display = 'none'; 1001 if (!animation) return; 1002 1003 // Don't show hero visual below 1024px â not enough space for 2-column layout 1004 if (window.innerWidth < 1024) return; 1005 1006 animation.style.display = 'flex'; 1007 var docType = animMap[variant]; 1008 ['privacy', 'terms', 'cookies', 'tos'].forEach(function(t) { 1009 var el = document.getElementById('hero-anim-' + t); 1010 if (el) el.style.display = (t === docType) ? '' : 'none'; 1011 }); 1012 1013 window.__heroVisualVariant = variant; 1014 1015 function trackVisual() { 1016 if (typeof gtag === 'function') { 1017 gtag('event', 'hero_visual_shown', { 1018 hero_visual: variant, 1019 event_category: 'ab_test', 1020 event_label: 'hero_visual_' + variant 1021 }); 1022 } 1023 } 1024 if (typeof gtag === 'function') { trackVisual(); } 1025 else { window.addEventListener('load', trackVisual); } 1026 })(); 1027 </script>
1027 <!-- ============================================================ 1028 2. SOCIAL PROOF â big stats + compact testimonials 1029 ============================================================ --> <!-- ============================================================ 1030 3. WHO NEEDS THIS â fusion of legal risks + use cases 1031 ============================================================ --> <section id="who-needs-this" class="section section-redesigned fade-on-scroll"> <div class="features-container"> <div class="section-header"> <h2 class="section-title"> Who Needs <span class="gradient-highlight">WebLegal?</span> </h2> <p class="subtitle">Of 1,068 sites run through our scanner between April and September 2026, 46% had no usable privacy policy.</p> </div> <div class="who-needs-grid"> <!-- Left: 3 risk bullets (title only) --> <div class="who-needs-risks"> <div class="risk-bullet"> <div class="icon-container icon-rose"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg> </div> <h4>Personal Liability Risk</h4> </div><div class="risk-bullet"> <div class="icon-container icon-rose"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg> </div> <h4>Payment Account Suspension</h4> </div><div class="risk-bullet"> <div class="icon-container icon-rose"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 21v-8l5-4 5 4v8"/><path d="M21 9l-3-3-3 3-3-3-3 3v12h12V9Z"/></svg> </div> <h4>Platform Requirements</h4> </div> </div> <!-- Right: 4 audience cards (title + 1 line) --> <div class="who-needs-audiences"> <div class="audience-card card-hover"> <div class="icon-container icon-blue"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg> </div> <h4>E-commerce Stores & Shopify</h4> <p>Generate privacy policies for Shopify stores, WooCommerce sites, and online marketplaces.</p> </div><div class="audience-card card-hover"> <div class="icon-container icon-purple"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14,2 14,8 20,8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg> </div> <h4>SaaS & Software Companies</h4> <p>Create comprehensive terms of use for SaaS platforms, mobile apps, and software subscriptions.</p> </div><div class="audience-card card-hover"> <div class="icon-container icon-amber"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg> </div> <h4>Content Creators & Bloggers</h4> <p>Perfect privacy policies for WordPress blogs, YouTube channels, and content creation platforms.</p> </div><div class="audience-card card-hover"> <div class="icon-container icon-sky"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27,6.96 12,12.01 20.73,6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg> </div> <h4>
1031Agencies & Consultants</h4> <p>AI legal page templates for digital agencies, consultants, and service providers.</p> </div><div class="audience-card card-hover"> <div class="icon-container icon-emerald"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg> </div> <h4>Brochure sites & sole traders</h4> <p>Freelancers, B&B owners, small charities, local businesses.</p> </div> </div> </div> <div class="section-cta"> <a href="/en/form/" class="btn-primary">Get Protected Now</a> </div> </div> </section> <!-- ============================================================ 1032 4. HOW IT WORKS â horizontal numbered timeline 1033 ============================================================ --> <section id="how-it-works" class="section section-redesigned section-emerald fade-on-scroll"> <div class="features-container"> <div class="section-header"> <h2 class="section-title"> Privacy Policy Generator & Terms Generator Process - <span class="gradient-highlight">Avoid GDPR Fines</span> in 4 Steps </h2> </div> <div class="timeline-steps stagger-children"> <div class="timeline-step"> <div class="timeline-step-number">1</div> <div> <h4>Smart Questionnaire</h4> <p>Answer guided questions about your business, website type, and legal requirements.</p> </div> </div><div class="timeline-step"> <div class="timeline-step-number">2</div> <div> <h4>Free Preview</h4> <p>Preview the first 20 percent of your document completely free.</p> </div> </div><div class="timeline-step"> <div class="timeline-step-number">3</div> <div> <h4>AI Document Generation</h4> <p>Our system generates a custom AI prompt and legal page templates.</p> </div> </div><div class="timeline-step"> <div class="timeline-step-number">4</div> <div> <h4>Instant Delivery</h4> <p>Receive your complete legal documents package instantly via email.</p> </div> </div> </div> <div class="section-cta"> <a href="/en/form/" class="btn-primary">Get Protected Now</a> </div> </div> </section> <!-- ============================================================ 1034 INTEGRATION â how to add documents to your site 1035 ============================================================ --> <section id="integration" class="section section-tinted fade-on-scroll"> <div class="features-container"> <div class="section-header"> <h2 class="section-title"> Integrate in <span class="gradient-highlight">2 minutes</span> </h2> <p class="section-subtitle">One link, one script â your legal documents are live</p> </div> <div class="integration-methods stagger-children"> <div class="integration-method-card"> <h3>Simple link</h3> <p>Add a link in your footer. That's it.</p> </div><div class="integration-method-card"> <h3>Overlay (popup)</h3> <p>Include our script, legal pages open in an overlay.</p> </div><div class="integration-method-card"> <h3>Full integration</h3> <p>Embed via iframe for seamless visual integration.</p> </div> </div> <p class="integration-platforms">Works with Shopify, WooCommerce, WordPress, TOWeb, PageXL and all platforms</p> <div class="section-cta"> <a href="/en/docs/" class="btn-secondary">View integration guides</a> </div> </div> </section> <!-- ============================================================ 1036 5. SAMPLE DOCUMENTS â document mockup previews 1037 ============================================================ --> <section id="sample-documents" class="section section-redesigned fade-on-scroll"> <div class="features-container"> <div class="section-header"> <h2 class="section-title"> Examples from our <span class="gradient-highlight">Privacy Policy</span> Generator and Terms Generator </h2> </div> <div class="sample-docs-grid stagger-children"> <a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/terms-of-use/?credit=1" class="sample-doc-preview" target="_blank" rel="noopener"> <div class="sample-doc-mockup"> <div class="sample-doc-header"> <span class="sample-doc-logo">Legal Document</span> <span class="sample-doc-date">Generated in 2026</span> </div> <div class="sample-doc-title">Terms of Use</div> <div class="sample-doc-section"> <div class="sample-doc-heading">1. Acceptance of Terms</div> <div class="sample-doc-text">By accessing this website, you agree to be bound by the terms of this agreement.</div> </div><div class="sample-doc-section"> <div class="sample-doc-heading">2. Use License</div> <div class="sample-doc-text">Permission is granted to download one copy for personal, non-commercial viewing only.</div> </div> <div class="sample-doc-fade"></div> </div> <div class="sample-doc-label"> <span>Terms of Use</span>
1037 <svg class="sample-link-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5l7 7-7 7"></path></svg> </div> </a><a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/privacy-policy/?credit=1" class="sample-doc-preview" target="_blank" rel="noopener"> <div class="sample-doc-mockup"> <div class="sample-doc-header"> <span class="sample-doc-logo">Legal Document</span> <span class="sample-doc-date">Generated in 2026</span> </div> <div class="sample-doc-title">Privacy Policy</div> <div class="sample-doc-section"> <div class="sample-doc-heading">1. Data Collection</div> <div class="sample-doc-text">We collect information that you provide directly when creating an account.</div> </div><div class="sample-doc-section"> <div class="sample-doc-heading">2. Data Usage</div> <div class="sample-doc-text">Your data is used to provide and improve our services in compliance with GDPR.</div> </div> <div class="sample-doc-fade"></div> </div> <div class="sample-doc-label"> <span>Privacy Policy</span> <svg class="sample-link-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5l7 7-7 7"></path></svg> </div> </a><a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/cookie-policy/?credit=1" class="sample-doc-preview" target="_blank" rel="noopener"> <div class="sample-doc-mockup"> <div class="sample-doc-header"> <span class="sample-doc-logo">Legal Document</span> <span class="sample-doc-date">Generated in 2026</span> </div> <div class="sample-doc-title">Cookie Policy</div> <div class="sample-doc-section"> <div class="sample-doc-heading">1. What Are Cookies</div> <div class="sample-doc-text">Cookies are small text files placed on your device when browsing our website.</div> </div><div class="sample-doc-section"> <div class="sample-doc-heading">2. Types of Cookies</div> <div class="sample-doc-text">We use essential, analytics, and user preference cookies on our platform.</div> </div> <div class="sample-doc-fade"></div> </div> <div class="sample-doc-label"> <span>Cookie Policy</span> <svg class="sample-link-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5l7 7-7 7"></path></svg> </div> </a><a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/terms-of-sale/?credit=1" class="sample-doc-preview" target="_blank" rel="noopener"> <div class="sample-doc-mockup"> <div class="sample-doc-header"> <span class="sample-doc-logo">Legal Document</span> <span class="sample-doc-date">Generated in 2026</span> </div> <div class="sample-doc-title">Terms of Sale</div> <div class="sample-doc-section"> <div class="sample-doc-heading">1. Product Description</div> <div class="sample-doc-text">We offer AI-generated legal documents tailored to your business needs.</div> </div><div class="sample-doc-section"> <div class="sample-doc-heading">2. Pricing & Payment</div> <div class="sample-doc-text">All prices include applicable taxes. Payment is processed via secure providers.</div> </div> <div class="sample-doc-fade"></div> </div> <div class="sample-doc-label"> <span>Terms of Sale</span> <svg class="sample-link-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5l7 7-7 7"></path></svg> </div> </a> </div> </div> </section> <!-- ============================================================ 1038 6. AI vs TRADITIONAL â comparison table only 1039 ============================================================ --> <section id="ai-vs-traditional" class="section section-redesigned section-tinted comparison-section fade-on-scroll"> <div class="container"> <div class="section-header"> <h2 class="section-title"><span class="gradient-highlight">AI</span> vs Traditional Legal</h2> </div> <div class="comparison-table-wrapper"> <table class="comparison-table"> <thead> <tr> <th class>Feature</th><th class="highlight-col">WebLegal AI</th><th class>Traditional Lawyer</th><th class>DIY Templates</th> </tr> </thead> <tbody> <tr> <td><strong>Generation time</strong></td> <td class="highlight-col">5 minutes</td> <td>2-6 weeks</td> <td>2-5 hours</td> </tr><tr> <td><strong>Cost</strong></td> <td class="highlight-col">From <span data-price-type="pack_essential" style="white-space:nowrap">â¬19.90</span></td> <td>â¬1,500-â¬3,000</td> <td>Free (risky)</td> </tr><tr> <td><strong>Customization</strong></td> <td class="highlight-col">Platform-specific AI</td> <td>Fully custom</td> <td>Generic</td> </tr><tr> <td><strong>Languages</strong></td> <td class="highlight-col">12</td> <td>1-3</td> <td>1</td> </tr><tr> <td><strong>Countries covered</strong></td> <td class="highlight-col">30+</td> <td>1-5</td> <td>1</td> </tr> </tbody> </table> </div> <div class="section-cta"> <a href="/en/form/" class="btn-primary">Start Saving Now</a> </div> </div> </section> <!-- ============================================================ 1040 6b. MULTILINGUAL â document showcase (languages from product-facts.ts) 1041 ============================================================ --> <section id="multilingual" class="section section-redesigned fade-on-scroll"> <div class="container"> <div class="section-header"> <h2 class="section-title"> Your legal documents in <span class="gradient-highlight"> 12 languages</span> </h2> <p class="subtitle"> Written in the language you choose, for the country you declare. From French to Greek, Swedish to Polish. </p> </div> <div class="multilingual-showcase stagger-children"> <div class="multilingual-grid"> <div class="mini-doc"> <div class="mini-doc-flag"><img src="/img/flags/pl.svg" width="24" height="24" alt="PL"></div> <div class="mini-doc-title">Polityka prywatnoÅci</div> <div class="mini-doc-excerpt">Zbieramy informacje, które przekazujesz nam bezpoÅrednio, takie jak imiÄ i adres e-mail...</div> <div class="mini-doc-lines"><span></span><span></span><span></span><span></span></div> </div><div class="mini-doc"> <div class="mini-doc-flag"><img src="/img/flags/cz.svg" width="24" height="24" alt="CZ"></div> <div class="mini-doc-title">Zásady ochrany osobnÃch údajů</div> <div class="mini-doc-excerpt">ShromažÄujeme informace, které nám poskytujete pÅÃmo, napÅÃklad vaÅ¡e jméno a e-mailovou adresu...</div> <div class="mini-doc-lines"><span></span><span></span><span></span><span></span></div> </div><div class="mini-doc"> <div class="mini-doc-flag"><img src="/img/flags/gr.svg" width="24" height="24" alt="GR"></div> <div class="mini-doc-title">ΠολιÏική ÎÏοÏÏήÏÎ¿Ï </div> <div class="mini-doc-excerpt">Î£Ï Î»Î»ÎÎ³Î¿Ï Î¼Îµ ÏληÏοÏοÏÎ¯ÎµÏ ÏÎ¿Ï Î¼Î±Ï ÏαÏÎÏεÏε αÏÎµÏ Î¸ÎµÎ¯Î±Ï, ÏÏÏÏ Ïο Ïνομά ÏÎ±Ï ÎºÎ±Î¹ Ïη διεÏÎ¸Ï Î½Ïη email...</div> <div class="mini-doc-lines"><span></span><span></span><span></span><span></span></div> </div><div class="mini-doc"> <div class="mini-doc-flag"><img src="/img/flags/de.svg" width="24" height="24" alt="DE"></div> <div class="mini-doc-title">Datenschutzrichtlinie</div> <div class="mini-doc-excerpt">Wir erheben Daten, die Sie uns direkt zur Verfügung stellen, wie Ihren Namen und Ihre E-Mail-Adresse...</div> <div class="mini-doc-lines"><span></span><span></span><span></span><span></span></div> </div> </div> </div> </div> </section> <!-- ============================================================ 1042 7. PRICING â dark glassmorphism, 3 pack cards + individual link 1043 ============================================================ --> <section id="pricing" class="pricing-dark section-redesigned"> <div class="container"> <h2 class="section-title"> Our <span class="gradient-highlight">Plans</span> & Pricing </h2> <p class="subtitle">Choose the pack that fits your needs â GDPR-compliant documents, generated in minutes</p> <div class="pricing-cards pricing-cards-3"> <div class="pricing-card "> <h3 class="pricing-type">Essential</h3> <p class="pricing-subtitle">The essentials for your website</p> <div class="pricing-price" data-price-type="pack_essential">â¬19.90</div> <div class="pricing-period">one-time payment</div> <span class="pricing-savings">No subscription</span> <p class="pricing-doc-count">2 documents included</p> <ul class="pricing-features"> <li class="excluded"><span class="pricing-excluded-text"><span class="pricing-excluded-label">Not included:</span> Terms of Use</span></li><li>Privacy Policy</li><li>Cookie Policy</li><li class="excluded"><span class="pricing-excluded-text"><span class="pricing-excluded-label">Not included:</span> Terms of Sale</span></li> </ul> <a href="/en/form/?pack=essential" class="btn-primary">Protect my site â</a> </div><div class="pricing-card featured"> <span class="pricing-badge">Popular</span> <h3 class="pricing-type">Pro</h3> <p class="pricing-subtitle">The complete solution</p> <div class="pricing-price" data-price-type="pack_pro">â¬34.90</div> <div class="pricing-period">one-time payment</div> <span class="pricing-savings">No subscription</span> <p class="pricing-doc-count">3 documents included</p> <ul class="pricing-features"> <li>Terms of Use</li><li>Privacy Policy</li><li>Cookie Policy</li><li class="excluded"><span class="pricing-excluded-text"><span class="pricing-excluded-label">Not included:</span> Terms of Sale</span></li> </ul> <a href="/en/form/?pack=pro" class="btn-primary">Protect my site â</a> </div><div class="pricing-card "> <h3 class="pricing-type">Business</h3> <p class="pricing-subtitle">All-inclusive for e-commerce</p> <div class="pricing-price" data-price-type="pack_business">â¬49.90</div> <div class="pricing-period">one-time payment</div> <span class="pricing-savings">No subscription</span> <p class="pricing-doc-count">4 documents included</p> <ul class="pricing-features"> <li>Terms of Use</li><li>Privacy Policy</li><li>Cookie Policy</li><li>Terms of Sale</li> </ul> <a href="/en/form/?pack=business" class="btn-primary">Protect my site â</a> </div> </div> <div class="pricing-shared-features"> <span class="pricing-shared-feature">Free preview</span><span class="pricing-shared-feature">12 languages</span><span class="pricing-shared-feature">30+ countries covered</span><span class="pricing-shared-feature">Instant generation</span><span class="pricing-shared-feature">GDPR compliant</span> </div> <p class="pricing-currency-note">Prices in EUR. Your bank converts automatically at the current rate.</p> </div> </section> <!-- ============================================================ 1044 COOKIE CONSENT BANNER â free tool showcase (post-pricing trust-builder) 1045 ============================================================ --> <section id="cookie-consent-banner" class="section section-redesigned section-emerald fade-on-scroll"> <div class="container"> <div class="section-header"> <h2 class="section-title"> Free cookie <span class="gradient-highlight">banner</span> for your website </h2> <p class="section-subtitle">ePrivacy & GDPR compliance in 2 minutes â no subscription, no complex code.</p> </div> <div class="ccb-section-layout"> <!-- Left: animated demo --> <div class="ccb-section-demo scale-on-scroll"> <link rel="stylesheet" href="/css/cookie-banner-demo.css"><div class="ccbd-container" id="ccbd-n1ofuk" data-config="{"id":"ccbd-n1ofuk","speed":1}"> <!-- Browser chrome --> <div class="ccbd-browser-bar"> <div class="ccbd-dots"><span></span><span></span><span></span></div> <div class="ccbd-url"><span class="ccbd-lock">🔒</span><span class="ccbd-url-text">ma-boutique.fr</span></div> </div> <!-- Mini website mockup --> <div class="ccbd-viewport"> <div class="ccbd-site"> <!-- Mini site header --> <div class="ccbd-site-header"> <span class="ccbd-site-logo">My Shop</span> <nav class="ccbd-site-nav"> <span>Home</span><span>Products</span><span>Contact</span> </nav> </div> <!-- Mini site content --> <div class="ccbd-site-body"> <div class="ccbd-site-hero-text">Welcome to our online shop. Discover our handcrafted products made with care.</div> <div class="ccbd-site-placeholder"></div> <div class="ccbd-site-placeholder ccbd-short"></div> </div> </div> <!-- Cookie banner (popup style) --> <div class="ccbd-banner" id="ccbd-n1ofuk-banner"> <div class="ccbd-banner-inner"> <div class="ccbd-banner-title">🍪
1045 This site uses cookies</div> <div class="ccbd-banner-desc">We use cookies to improve your experience and analyse traffic.</div> <!-- Categories (hidden initially) --> <div class="ccbd-cats" id="ccbd-n1ofuk-cats"> <div class="ccbd-cat"> <div class="ccbd-cat-info"> <span class="ccbd-cat-name">Necessary</span> <span class="ccbd-cat-desc">Essential for the site to function.</span> </div> <label class="ccbd-toggle ccbd-toggle-locked"> <input type="checkbox" checked disabled> <span class="ccbd-slider"></span> </label> </div> <div class="ccbd-cat"> <div class="ccbd-cat-info"> <span class="ccbd-cat-name">Analytics</span> <span class="ccbd-cat-desc">Audience measurement (e.g. Google Analytics).</span> </div> <label class="ccbd-toggle" id="ccbd-n1ofuk-toggle-analytics"> <input type="checkbox"> <span class="ccbd-slider"></span> </label> </div> <div class="ccbd-cat"> <div class="ccbd-cat-info"> <span class="ccbd-cat-name">Marketing</span> <span class="ccbd-cat-desc">Targeted advertising (e.g. Facebook Pixel).</span> </div> <label class="ccbd-toggle"> <input type="checkbox"> <span class="ccbd-slider"></span> </label> </div> </div> <!-- Buttons --> <div class="ccbd-btns"> <button class="ccbd-btn ccbd-btn-accept" id="ccbd-n1ofuk-btn-accept">Accept all</button> <button class="ccbd-btn ccbd-btn-reject" id="ccbd-n1ofuk-btn-reject">Reject all</button> <button class="ccbd-btn ccbd-btn-settings" id="ccbd-n1ofuk-btn-settings">Customise</button> </div> <!-- Branding â kept in sync with wl-cookie-consent.js (#104) --> <div class="ccbd-branding">Powered by <span>WebLegal.ai</span></div> </div> </div> <!-- Success toast --> <div class="ccbd-toast" id="ccbd-n1ofuk-toast"> <span class="ccbd-toast-icon">✅</span> <span class="ccbd-toast-text">Preferences saved</span> </div> </div> <!-- Progress bar --> <div class="ccbd-progress"><div class="ccbd-progress-fill" id="ccbd-n1ofuk-progress"></div></div> </div>
1045<script>(function(){const config = "{\"id\":\"ccbd-n1ofuk\",\"speed\":1}"; 1046const instanceId = "ccbd-n1ofuk"; 1047 1048(function() { 1049 var cfg = JSON.parse(config); 1050 var el = document.getElementById(cfg.id); 1051 if (!el) return; 1052 1053 var sp = cfg.speed || 1; 1054 function ms(v) { return Math.round(v / sp); } 1055 1056 // Timeline (ms at 1x speed) 1057 var T = { 1058 BANNER_APPEAR: 800, // banner slides up 1059 PAUSE_READ: 3200, // user reads banner 1060 CLICK_SETTINGS: 3600, // "Customize" gets clicked 1061 CATS_EXPAND: 4200, // categories expand 1062 TOGGLE_ON: 5400, // analytics toggle slides on 1063 PAUSE_TOGGLE: 6400, // pause after toggle 1064 CLICK_SAVE: 6800, // "Save" gets clicked 1065 BANNER_HIDE: 7200, // banner slides down 1066 TOAST_SHOW: 7800, // success toast 1067 TOAST_HIDE: 9400, // toast fades 1068 TOTAL: 10800, // full cycle 1069 }; 1070 1071 // Scale all times 1072 for (var k in T) T[k] = ms(T[k]); 1073 1074 var banner = document.getElementById(instanceId + '-banner'); 1075 var cats = document.getElementById(instanceId + '-cats'); 1076 var btnSettings = document.getElementById(instanceId + '-btn-settings'); 1077 var btnAccept = document.getElementById(instanceId + '-btn-accept'); 1078 var toggleAnalytics = document.getElementById(instanceId + '-toggle-analytics'); 1079 var toast = document.getElementById(instanceId + '-toast'); 1080 var progress = document.getElementById(instanceId + '-progress'); 1081 var startTime; 1082 1083 function animate(ts) { 1084 if (!startTime) startTime = ts; 1085 var elapsed = (ts - startTime) % T.TOTAL; 1086 1087 // Banner visibility 1088 if (elapsed >= T.BANNER_APPEAR && elapsed < T.BANNER_HIDE) { 1089 banner.classList.add('ccbd-show'); 1090 } else { 1091 banner.classList.remove('ccbd-show'); 1092 } 1093 1094 // Categories expanded 1095 if (elapsed >= T.CATS_EXPAND && elapsed < T.BANNER_HIDE) { 1096 cats.classList.add('ccbd-expanded'); 1097 // Change button text to "Save" 1098 btnSettings.classList.add('ccbd-active'); 1099 } else { 1100 cats.classList.remove('ccbd-expanded'); 1101 btnSettings.classList.remove('ccbd-active'); 1102 } 1103 1104 // Settings button press animation 1105 if (elapsed >= T.CLICK_SETTINGS && elapsed < T.CLICK_SETTINGS + 200) { 1106 btnSettings.classList.add('ccbd-pressed'); 1107 } else { 1108 btnSettings.classList.remove('ccbd-pressed'); 1109 } 1110 1111 // Analytics toggle 1112 if (elapsed >= T.TOGGLE_ON && elapsed < T.BANNER_HIDE) { 1113 toggleAnalytics.querySelector('input').checked = true; 1114 } else { 1115 toggleAnalytics.querySelector('input').checked = false; 1116 } 1117 1118 // Save button press (reusing accept button visual for "save") 1119 if (elapsed >= T.CLICK_SAVE && elapsed < T.CLICK_SAVE + 200) { 1120 btnAccept.classList.add('ccbd-pressed'); 1121 } else { 1122 btnAccept.classList.remove('ccbd-pressed'); 1123 } 1124 1125 // Toast 1126 if (elapsed >= T.TOAST_SHOW && elapsed < T.TOAST_HIDE) { 1127 toast.classList.add('ccbd-show'); 1128 } else { 1129 toast.classList.remove('ccbd-show'); 1130 } 1131 1132 // Progress bar 1133 progress.style.transform = 'scaleX(' + (elapsed / T.TOTAL) + ')'; 1134 1135 requestAnimationFrame(animate); 1136 } 1137 1138 // Start animation when visible (IntersectionObserver) 1139 var started = false; 1140 var observer = new IntersectionObserver(function(entries) { 1141 if (entries[0].isIntersecting && !started) { 1142 started = true; 1143 requestAnimationFrame(animate); 1144 observer.disconnect(); 1145 } 1146 }, { threshold: 0.2 }); 1147 observer.observe(el); 1148})(); 1149})();</script>
1149 </div> <!-- Right: features grid --> <div class="ccb-section-features stagger-children"> <div class="ccb-feature-card fade-on-scroll"> <div class="ccb-feature-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path><path d="m9 12 2 2 4-4"></path></svg> </div> <div class="ccb-feature-text"> <h3>ePrivacy & GDPR compliant</h3> <p>Automatically blocks third-party scripts (Analytics, Pixel, etc.) until the visitor has given consent.</p> </div> </div><div class="ccb-feature-card fade-on-scroll"> <div class="ccb-feature-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M2 12h20"></path><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg> </div> <div class="ccb-feature-text"> <h3>30 languages included</h3> <p>The banner adapts to the visitor's language. French, English, German, Spanish, Italian, and 25 other languages.</p> </div> </div><div class="ccb-feature-card fade-on-scroll"> <div class="ccb-feature-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> </div> <div class="ccb-feature-text"> <h3>1 line of code</h3> <p>Copy-paste a script into your site. Works with WordPress, Shopify, TOWeb, PageXL and all CMS.</p> </div> </div><div class="ccb-feature-card fade-on-scroll"> <div class="ccb-feature-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="13.5" cy="6.5" r="2.5"></circle><circle cx="17.5" cy="10.5" r="2.5"></circle><circle cx="8.5" cy="7.5" r="2.5"></circle><circle cx="6.5" cy="12.5" r="2.5"></circle><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"></path></svg> </div> <div class="ccb-feature-text"> <h3>Customisable</h3> <p>Colours, position, light/dark theme â adapt the banner to your site's design in a few clicks.</p> </div> </div><div class="ccb-feature-card fade-on-scroll"> <div class="ccb-feature-icon"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="4.5" r="1.8"></circle><path d="M5 8.5l7 1.5 7-1.5"></path><path d="M12 10v5l-3 6"></path><path d="M12 15l3 6"></path></svg> </div> <div class="ccb-feature-text"> <h3><a href="/en/cookie-banner/#accessibilite" class="ccb-feature-link">Accessible WCAG 2.2 AA</a></h3> <p>Keyboard navigable, screen-reader friendly, contrast checked in both themes. Accessibility statement on the banner page.</p> </div> </div> </div> </div> <!-- CTA --> <div class="ccb-section-cta fade-on-scroll"> <a href="/en/cookie-banner/" class="btn-primary"> Set up my free banner → 1150</a> <p class="ccb-cta-sub">Ready in 2 minutes â no sign-up required</p> </div> </div> </section> <!-- ============================================================ 1151 8. GDPR RISK CALCULATOR (style refresh only) 1152 ============================================================ --> <section class="calculator-section section-redesigned" id="calculator"> <div class="container"> <h2 class="section-title fade-on-scroll"> What's Your <span class="gradient-highlight">GDPR Fine Risk?</span> </h2> <p class="section-subtitle fade-on-scroll">Calculate your potential exposure in seconds</p> <div class="calculator-card scale-on-scroll"> <label for="revenue-input" class="calculator-label"> Your annual revenue (â¬) </label> <div class="calculator-input-group"> <input type="number" id="revenue-input" class="calculator-input" placeholder="e.g. 50000" min="0" step="10000"> <button type="button" class="calculator-btn" id="calculate-risk-btn"> Calculate My Risk </button> </div> <div class="calculator-result" id="calculator-result"> <p>Your potential fine risk: up to</p> <div class="risk-amount" id="risk-amount"></div> <p class="protection-cost"> Protect your business for just <strong id="calculator-price"></strong> </p> <a href="/en/form/" class="btn-primary calculator-cta"> Reduce My Risk Now </a> </div> <p class="calculator-disclaimer">Based on GDPR Art. 83 maximum penalty of <strong>4% of annual turnover or â¬20 million</strong>, whichever is higher.</p> </div> </div> </section> <!-- ============================================================ 1153 9. FAQ â clickable accordion 1154 ============================================================ --> <section id="faq" class="section section-redesigned section-tinted fade-on-scroll"> <div class="container"> <div class="section-header"> <h2 class="section-title">Frequently Asked <span class="gradient-highlight">Questions</span> </h2> </div> <div class="faq-accordion"> <div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Is my small brochure website affected by GDPR?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes. As soon as a website collects personal data â even a simple c
1154ontact form, Google Analytics, or a social share button â the GDPR applies, regardless of business size. A freelancer's portfolio site is subject to the same rules as a large e-commerce store.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Does GDPR apply to associations and non-profits?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes. The GDPR makes no distinction between commercial and non-commercial organisations. Any charity or association that manages members, sends newsletters, or uses a contact form must have a compliant privacy policy and cookie policy.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Are the generated documents legally valid?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes, all our templates are designed to be legally valid and compliant with regulations across multiple jurisdictions. Our documents provide solid legal protection for standard use cases.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I preview my document before purchasing?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes! You can preview the first 20% of your document completely free. The preview shows real content generated specifically for your business, so you can see exactly what you'll receive before making a purchase. No payment or registration required.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I avoid GDPR fines with WebLegal?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Documents are one part of compliance: they cover the information you must publish. A fine depends on how you actually handle personal data (consent, security, contracts), which no document settles on its own. Documents that accurately describe what your site does reduce that risk; they do not guarantee compliance.</p></div> </div> </div> <div id="faq-hidden-items" class="faq-hidden"> <div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Which countries and languages are supported?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Our documents are built on 7 legal frameworks â GDPR, UK GDPR, CCPA, LGPD, PIPEDA, the Australian Privacy Act and the Swiss nFADP â covering 30+ countries: all EU member states, the UK, Switzerland, the US,
1154Canada, Brazil, Australia and New Zealand. Documents are available in 12 languages including English, French, German, Spanish, Italian, and Portuguese.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>How do I know which legal documents my website needs?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Start with the free scanner: paste your address and it checks, in about 30 seconds, which legal pages are missing and which trackers load before consent. No signup, no card, no email. You get the list of what is missing before deciding whether to generate anything.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Do I need a privacy policy for my Shopify store?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes, Shopify requires all stores to have a privacy policy. Our AI generator creates Shopify-compliant privacy policies covering payment processing, customer data collection, cookies, and third-party integrations. Essential for avoiding policy violations and maintaining customer trust.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>What privacy policy template do I need for my SaaS business?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>SaaS businesses need comprehensive privacy policies covering user data processing, API integrations, third-party services, and subscription billing. Our AI generator creates GDPR-compliant SaaS privacy policies with specific clauses for software licensing, data retention, and user rights management.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>How much does a lawyer charge for creating a privacy policy?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Fees vary widely with the firm, the scope and the number of documents: ask for a quote. WebLegal packs start at â¬19.90, paid once (privacy policy + cookie policy). They are generated from your answers and do not replace legal advice for a complex or high-risk activity.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Is this a subscription or a one-time payment?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>A one-time payment. No subscription, no recurring charge, no card stored for future billing. You pay for your pack once and the documents are yours. Nothing renews or updates on its own.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Do you accept PayPal and credit cards?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes, we accept all major credit cards, PayPal, Stripe Link, Klarna, and other secure payment methods. All payments are processed through Stripe with enterprise-grade security.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>
1154Which privacy laws do your documents comply with?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>WebLegal templates are designed to comply with major regulatory frameworks including EU and UK GDPR, the EU ePrivacy Directive, California's CCPA/CPRA, Brazil's LGPD, and Switzerland's nFADP. Coverage may vary depending on the use case and jurisdiction.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>How often should I update my privacy policy and cookie policy?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Update whenever your data practices change (new analytics/ad tools, new markets, new data sharing) or when regulations evolve. With WebLegal, you can regenerate updated documents in minutes.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Does WebLegal store my personal data or my customers' data?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>We collect only the minimum information needed to generate your documents and process payments via Stripe. We do not store sensitive data belonging to your website's customers.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I customize clauses and regenerate documents at any time?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes. You can modify key clauses (purpose, data retention, contact details, refund terms, etc.) and regenerate versions as your business evolves.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Do I need both Terms of Use and Terms of Sale?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>In most cases, yes. Terms of Use govern website/app usage and user behavior, while Terms of Sale cover pricing, shipping, refunds, warranties, and consumer rights for transactions. If you sell products or services, you need both.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I host documents on my domain or use a direct link?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Both options are available. You can copy HTML/Markdown/Text onto your site or publish via a permanent direct link for quick updates without redeploying pages.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Are WebLegal documents accepted by platforms and payment providers?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes. Our policies meet the requirements commonly requested by Shopify and other marketplaces, as well as payment processors like Stripe and PayPal that expect clear legal pages.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I generate documents in multiple languages for the same website?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Yes. Generate policies in 12 languages and serve the right version based on your site's language settings or user location. Each language version is independently customized for the target market.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>What information should I prepare before generating my documents?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Have your company name and contact information, business location, data controller email, tools you use (analytics, ads, emails), and refund/return rules for sales if applicable. The guided questionnaire will walk
1154you through everything.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>How fast will I receive my documents?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>Most users complete generation in under 3 minutes. Your documents are available immediately for copying, downloading, or publishing via a direct link. Delivery by email is also instant.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Can I use one set of documents for multiple websites?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>No. Each website or app should have its own customized documents that reflect its specific data practices, features, and jurisdiction. Using the same documents across different sites can leave compliance gaps.</p></div> </div> </div><div class="faq-accordion-item"> <button class="faq-accordion-trigger" type="button"> <span>Does WebLegal provide legal advice?</span> <svg class="faq-accordion-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line> </svg> </button> <div class="faq-accordion-content"> <div class="faq-accordion-answer"><p>WebLegal is a document generation tool and does not replace professional legal advice. For complex or high-risk questions, consult a qualified attorney. Our documents provide strong baseline protection for standard business use cases.</p></div> </div> </div> </div> <button type="button" class="faq-show-more" id="faq-show-more-btn"> Show more questions (19) 1155</button> </div> </div> </section> <!-- FAQPage Structured Data (all items for SEO) -->
1155<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Is my small brochure website affected by GDPR?","acceptedAnswer":{"@type":"Answer","text":"Yes. As soon as a website collects personal data â even a simple contact form, Google Analytics, or a social share button â the GDPR applies, regardless of business size. A freelancer's portfolio site is subject to the same rules as a large e-commerce store."}},{"@type":"Question","name":"Does GDPR apply to associations and non-profits?","acceptedAnswer":{"@type":"Answer","text":"Yes. The GDPR makes no distinction between commercial and non-commercial organisations. Any charity or association that manages members, sends newsletters, or uses a contact form must have a compliant privacy policy and cookie policy."}},{"@type":"Question","name":"Are the generated documents legally valid?","acceptedAnswer":{"@type":"Answer","text":"Yes, all our templates are designed to be legally valid and compliant with regulations across multiple jurisdictions. Our documents provide solid legal protection for standard use cases."}},{"@type":"Question","name":"Can I preview my document before purchasing?","acceptedA
1155nswer":{"@type":"Answer","text":"Yes! You can preview the first 20% of your document completely free. The preview shows real content generated specifically for your business, so you can see exactly what you'll receive before making a purchase. No payment or registration required."}},{"@type":"Question","name":"Can I avoid GDPR fines with WebLegal?","acceptedAnswer":{"@type":"Answer","text":"Documents are one part of compliance: they cover the information you must publish. A fine depends on how you actually handle personal data (consent, security, contracts), which no document settles on its own. Documents that accurately describe what your site does reduce that risk; they do not guarantee compliance."}},{"@type":"Question","name":"Which countries and languages are supported?","acceptedAnswer":{"@type":"Answer","text":"Our documents are built on 7 legal frameworks â GDPR, UK GDPR, CCPA, LGPD, PIPEDA, the Australian Privacy Act and the Swiss nFADP â covering 30+ countries: all EU member states, the UK, Switzerland, the US, Canada, Brazil, Australia and New Zealand. Documents are available in 12 languages including English, French, German, Spanish, Italian, and Portuguese."}},{"@type":"Question","name":"How do I know which legal documents my website needs?","acceptedA
1155nswer":{"@type":"Answer","text":"Start with the free scanner: paste your address and it checks, in about 30 seconds, which legal pages are missing and which trackers load before consent. No signup, no card, no email. You get the list of what is missing before deciding whether to generate anything."}},{"@type":"Question","name":"Do I need a privacy policy for my Shopify store?","acceptedAnswer":{"@type":"Answer","text":"Yes, Shopify requires all stores to have a privacy policy. Our AI generator creates Shopify-compliant privacy policies covering payment processing, customer data collection, cookies, and third-party integrations. Essential for avoiding policy violations and maintaining customer trust."}},{"@type":"Question","name":"What privacy policy template do I need for my SaaS business?","acceptedAnswer":{"@type":"Answer","text":"SaaS businesses need comprehensive privacy policies covering user data processing, API integrations, third-party services, and subscription billing. Our AI generator creates GDPR-compliant SaaS privacy policies with specific clauses for software licensing, data retention, and user rights management."}},{"@type":"Question","name":"How much does a lawyer charge for creating a privacy policy?","acceptedA
1155nswer":{"@type":"Answer","text":"Fees vary widely with the firm, the scope and the number of documents: ask for a quote. WebLegal packs start at â¬19.90, paid once (privacy policy + cookie policy). They are generated from your answers and do not replace legal advice for a complex or high-risk activity."}},{"@type":"Question","name":"Is this a subscription or a one-time payment?","acceptedAnswer":{"@type":"Answer","text":"A one-time payment. No subscription, no recurring charge, no card stored for future billing. You pay for your pack once and the documents are yours. Nothing renews or updates on its own."}},{"@type":"Question","name":"Do you accept PayPal and credit cards?","acceptedAnswer":{"@type":"Answer","text":"Yes, we accept all major credit cards, PayPal, Stripe Link, Klarna, and other secure payment methods. All payments are processed through Stripe with enterprise-grade security."}},{"@type":"Question","name":"Which privacy laws do your documents comply with?","acceptedAnswer":{"@type":"Answer","text":"WebLegal templates are designed to comply with major regulatory frameworks including EU and UK GDPR, the EU ePrivacy Directive, California's CCPA/CPRA, Brazil's LGPD, and Switzerland's nFADP. Coverage may vary depending on the use case and jurisdiction."}},{"@type":"Question","name":"How often should I update my privacy policy and cookie policy?","acceptedA
1155nswer":{"@type":"Answer","text":"Update whenever your data practices change (new analytics/ad tools, new markets, new data sharing) or when regulations evolve. With WebLegal, you can regenerate updated documents in minutes."}},{"@type":"Question","name":"Does WebLegal store my personal data or my customers' data?","acceptedAnswer":{"@type":"Answer","text":"We collect only the minimum information needed to generate your documents and process payments via Stripe. We do not store sensitive data belonging to your website's customers."}},{"@type":"Question","name":"Can I customize clauses and regenerate documents at any time?","acceptedAnswer":{"@type":"Answer","text":"Yes. You can modify key clauses (purpose, data retention, contact details, refund terms, etc.) and regenerate versions as your business evolves."}},{"@type":"Question","name":"Do I need both Terms of Use and Terms of Sale?","acceptedAnswer":{"@type":"Answer","text":"In most cases, yes. Terms of Use govern website/app usage and user behavior, while Terms of Sale cover pricing, shipping, refunds, warranties, and consumer rights for transactions. If you sell products or services, you need both."}},{"@type":"Question","name":"Can I host documents on my domain or use a direct link?","acceptedA
1155nswer":{"@type":"Answer","text":"Both options are available. You can copy HTML/Markdown/Text onto your site or publish via a permanent direct link for quick updates without redeploying pages."}},{"@type":"Question","name":"Are WebLegal documents accepted by platforms and payment providers?","acceptedAnswer":{"@type":"Answer","text":"Yes. Our policies meet the requirements commonly requested by Shopify and other marketplaces, as well as payment processors like Stripe and PayPal that expect clear legal pages."}},{"@type":"Question","name":"Can I generate documents in multiple languages for the same website?","acceptedAnswer":{"@type":"Answer","text":"Yes. Generate policies in 12 languages and serve the right version based on your site's language settings or user location. Each language version is independently customized for the target market."}},{"@type":"Question","name":"What information should I prepare before generating my documents?","acceptedAnswer":{"@type":"Answer","text":"Have your company name and contact information, business location, data controller email, tools you use (analytics, ads, emails), and refund/return rules for sales if applicable. The guided questionnaire will walk you through everything."}},{"@type":"Question","name":"How fast will I receive my documents?","acceptedA
1155nswer":{"@type":"Answer","text":"Most users complete generation in under 3 minutes. Your documents are available immediately for copying, downloading, or publishing via a direct link. Delivery by email is also instant."}},{"@type":"Question","name":"Can I use one set of documents for multiple websites?","acceptedAnswer":{"@type":"Answer","text":"No. Each website or app should have its own customized documents that reflect its specific data practices, features, and jurisdiction. Using the same documents across different sites can leave compliance gaps."}},{"@type":"Question","name":"Does WebLegal provide legal advice?","acceptedAnswer":{"@type":"Answer","text":"WebLegal is a document generation tool and does not replace professional legal advice. For complex or high-risk questions, consult a qualified attorney. Our documents provide strong baseline protection for standard business use cases."}}]}</script>
1155 <!-- Product Structured Data -->
1155<script type="application/ld+json">{"@context":"https://schema.org","@type":"Product","name":"WebLegal.ai - AI Legal Document Generator","description":"Free GDPR + CCPA scan, then generate Privacy Policy, Terms & Cookies in 5 min with AI. 12 languages, 7 legal frameworks. From â¬19.90.","image":"https://weblegal.ai/assets/og-default-DliLAxtt.png","url":"https://weblegal.ai","brand":{"@type":"Brand","name":"WebLegal.ai"},"offers":[{"@type":"Offer","name":"Pro Pack","description":"Terms of Use + Privacy Policy + Cookie Policy","price":"34.90","priceCurrency":"EUR","availability":"https://schema.org/InStock","priceValidUntil":"2026-12-31","url":"https://weblegal.ai/en/form/","hasMerchantReturnPolicy":{"@type":"MerchantReturnPolicy","applicableCountry":"FR","returnPolicyCategory":"https://schema.org/MerchantReturnNotPermitted","merchantReturnDays":0},"shippingDetails":{"@type":"OfferShippingDetails","shippingRate":{"@type":"MonetaryAmount","value":"0","currency":"EUR"},"shippingDestination":{"@type":"DefinedRegion","addressCountry":"FR"},"deliveryTime":{"@type":"ShippingDeliveryTime","handlingTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"},"transitTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"}}}},{"@type":"Offer","name":"Essential Pack","description":"Privacy Policy + Cookie Policy","price":"19.90","priceCurrency":"EUR","availability":"https://schema.org/InStock","priceValidUntil":"2026-12-31","url":"https://weblegal.ai/en/form/","hasMerchantReturnPolicy":{"@type":"MerchantReturnPolicy","applicableCountry":"FR","returnPolicyCategory":"https://schema.org/MerchantReturnNotPermitted","merchantReturnDays":0},"shippingDetails":{"@type":"OfferShippingDetails","shippingRate":{"@type":"MonetaryAmount","value":"0","currency":"EUR"},"shippingDestination":{"@type":"DefinedRegion","addressCountry":"FR"},"deliveryTime":{"@type":"ShippingDeliveryTime","handlingTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"},"transitTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"}}}},{"@type":"Offer","name":"Business Pack","description":"Terms of Use + Privacy Policy + Cookie Policy + Terms of Sale","price":"49.90","priceCurrency":"EUR","availability":"https://schema.org/InStock","priceValidUntil":"2026-12-31","url":"https://weblegal.ai/en/form/","hasMerchantReturnPolicy":{"@type":"MerchantReturnPolicy","applicableCountry":"FR","returnPolicyCategory":"https://schema.org/MerchantReturnNotPermitted","merchantReturnDays":0},"shippingDetails":{"@type":"OfferShippingDetails","shippingRate":{"@type":"MonetaryAmount","value":"0","currency":"EUR"},"shippingDestination":{"@type":"DefinedRegion","addressCountry":"FR"},"deliveryTime":{"@type":"ShippingDeliveryTime","handlingTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"},"transitTime":{"@type":"QuantitativeValue","minValue":0,"maxValue":0,"unitCode":"d"}}}}]}</script>
1155 <!-- SoftwareApplication Structured Data -->
1155<script type="application/ld+json">{"@context":"https://schema.org","@type":"SoftwareApplication","name":"WebLegal.ai","operatingSystem":"Web","applicationCategory":"BusinessApplication","offers":{"@type":"Offer","price":"19.90","priceCurrency":"EUR","priceValidUntil":"2026-12-31"}}</script>
1155 <!-- ============================================================ 1156 10. BLOG â teaser section 1157 ============================================================ --> <section id="blog-teaser" class="section section-redesigned section-emerald fade-on-scroll"> <div class="container"> <div class="section-header"> <h2 class="section-title"> Our <span class="gradient-highlight">Blog</span> </h2> <p class="subtitle">Practical guides, GDPR news and legal advice to protect your business.</p> </div> <div class="blog-grid blog-teaser-featured-grid"> <a href="/en/blog/barometre-conformite-2026-09/" class="blog-card"> <div class="blog-card-header"> <img src="/img/blog/barometre-conformite-2026-09.webp" alt="What 1,068 scanned websites told us - Cookies & Consent" class="blog-card-image" loading="lazy"> </div> <div class="blog-card-body"> <h2 class="blog-card-title"> What 1,068 scanned websites told us </h2> <div class="blog-card-tags"> <span class="blog-topic-tag blog-topic-3"> Cookies & Consent </span><span class="blog-topic-tag blog-topic-5"> Compliance & Rights </span> </div> <div class="blog-card-meta"> <time class="blog-card-date" datetime="2026-09-07T00:00:00.000Z"> 7 September 2026 </time> <span class="blog-card-reading-time">â± 5 min read</span> </div> <p class="blog-card-excerpt"> At least 12.9% of the sites we scan load trackers without valid consent. First edition of our barometer, with open method and open data. </p> <span class="blog-card-link"> Read article â </span> </div> </a><a href="/en/blog/joomla-consent-mode-v2-no-plugin/" class="blog-card"> <div class="blog-card-header"> <img src="/img/blog/joomla-consent-mode-v2-20260802.webp" alt="Joomla Consent Mode v2: No Plugin Needed - Cookies & Consent" class="blog-card-image" loading="lazy"> </div> <div class="blog-card-body"> <h2 class="blog-card-title"> Joomla Consent Mode v2: No Plugin Needed </h2> <div class="blog-card-tags"> <span class="blog-topic-tag blog-topic-3"> Cookies & Consent </span><span class="blog-topic-tag blog-topic-5"> Compliance & Rights </span> </div> <div class="blog-card-meta"> <time class="blog-card-date" datetime="2026-08-02T00:00:00.000Z"> 2 August 2026 </time> <span class="blog-card-reading-time">â± 8 min read</span> </div> <p class="blog-card-excerpt"> Joomla ships no cookie banner in core. Add Google Consent Mode v2 in one line â no extension, no licence â plus the template traps that break it. </p> <span class="blog-card-link"> Read article â </span> </div> </a><a href="/en/blog/global-privacy-control-complete-guide/" class="blog-card"> <div class="blog-card-header"> <img src="/img/blog/global-privacy-control-guide-20260724.webp" alt="Global Privacy Control (GPC): 2026 Guide - Cookies & Consent" class="blog-card-image" loading="lazy"> </div> <div class="blog-card-body"> <h2 class="blog-card-title"> Global Privacy Control (GPC): 2026 Guide </h2> <div class="blog-card-tags"> <span class="blog-topic-tag blog-topic-3"> Cookies & Consent </span><span class="blog-topic-tag blog-topic-5"> Compliance & Rights </span> <span style="font-size:10px;padding:2px 8px;border-radius:10px;background:#f59e0b15;color:#f59e0b;border:1px solid #f59e0b40;font-weight:600"> CCPA </span> </div> <div class="blog-card-meta"> <time class="blog-card-date" datetime="2026-07-25T00:00:00.000Z"> 25 July 2026 </time> <span class="blog-card-reading-time">â± 12 min read</span> </div> <p class="blog-card-excerpt"> What GPC is, how to turn it on in every browser, the 12 US states where it is legally binding, and what your website must do to comply in 2026. </p> <span class="blog-card-link"> Read article â </span> </div> </a> </div> <div class="blog-teaser-grid"> <div class="blog-teaser-topics stagger-children"> <a href="/en/blog/?category=fondamentaux-rgpd" class="blog-topic-tag blog-topic-0">GDPR Fundamentals</a><a href="/en/blog/?category=documents-legaux" class="blog-topic-tag blog-topic-1">Legal Documents</a><a href="/en/blog/?category=e-commerce" class="blog-topic-tag blog-topic-2">E-commerce</a><a href="/en/blog/?category=cookies-consent" class="blog-topic-tag blog-topic-3">Cookies &
1157 Consent</a><a href="/en/blog/?category=securite" class="blog-topic-tag blog-topic-4">Security</a><a href="/en/blog/?category=conformite" class="blog-topic-tag blog-topic-5">Compliance</a> <a href="/en/blog/?jurisdiction=eu-gdpr" class="blog-topic-tag" style="background:#3B82F615;color:#3B82F6;border:1px solid #3B82F640">GDPR</a><a href="/en/blog/?jurisdiction=us-ccpa" class="blog-topic-tag" style="background:#f59e0b15;color:#f59e0b;border:1px solid #f59e0b40">CCPA</a><a href="/en/blog/?jurisdiction=ca-pipeda" class="blog-topic-tag" style="background:#ef444415;color:#ef4444;border:1px solid #ef444440">PIPEDA</a><a href="/en/blog/?jurisdiction=br-lgpd" class="blog-topic-tag" style="background:#10b98115;color:#10b981;border:1px solid #10b98140">LGPD</a> </div> <div class="blog-teaser-visual"> <div class="blog-teaser-card"> <div class="blog-teaser-icon"> <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path> <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path> <line x1="8" y1="7" x2="16" y2="7"></line> <line x1="8" y1="11" x2="14" y2="11"></line> </svg> </div> <p class="blog-teaser-tagline">Practical guides, GDPR news and legal advice to protect your business.</p> <a href="/en/blog/" class="btn-primary blog-teaser-cta"> View all articles <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5l7 7-7 7"></path></svg> </a> </div> </div> </div> </div> </section> <!-- ============================================================ 1158 11. FINAL CTA â gradient dark background 1159 ============================================================ --> <section id="final-cta" class="final-cta-dark section-redesigned"> <div class="container"> <h2> <span class="gradient-highlight">Ready to protect</span> your business? </h2> <div> <a href="/en/form/" class="btn-primary btn-large">Eliminate Legal Risks</a> </div> </div> </section> </main>
1159<script>(function(){const activePrices = {"cgu":14.9,"privacy":14.9,"cookies":14.9,"cgv":19.9,"pack_essential":19.9,"pack_pro":34.9,"pack_business":49.9}; 1160 1161 // Inject build-time prices from pricing.json (single source of truth) 1162 // These will be overridden by promotions-config.php API call at runtime 1163 window.currentPrices = activePrices; 1164})();</script>
1164
1164<script> 1165 // Shared globals 1166 var lang = document.documentElement.lang || 'fr'; 1167 1168 function getGdprFine(revenue) { 1169 return Math.min(revenue * 0.04, 20000000); 1170 } 1171 function formatCurrency(amount) { 1172 return new Intl.NumberFormat(lang === 'fr' ? 'fr-FR' : lang === 'de' ? 'de-DE' : lang === 'pt' ? 'pt-BR' : lang === 'ro' ? 'ro-RO' : lang === 'cs' ? 'cs-CZ' : lang === 'el' ? 'el-GR' : lang === 'hu' ? 'hu-HU' : lang === 'da' ? 'da-DK' : lang + '-' + lang.toUpperCase(), { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(amount); 1173 } 1174 // animateCounter is provided by core.js: animateCounter(el, from, to) 1175 // It formats as â¬X with locale-aware separators. 1176 // For homepage we also need a version using formatCurrency (Intl style). 1177 function animateCounterHome(el, target) { 1178 var duration = 800; 1179 var start = performance.now(); 1180 function tick(now) { 1181 var t = Math.min((now - start) / duration, 1); 1182 var eased = t === 1 ? 1 : 1 - Math.pow(2, -10 * t); 1183 el.textContent = formatCurrency(Math.round(eased * target)); 1184 if (t < 1) requestAnimationFrame(tick); 1185 } 1186 requestAnimationFrame(tick); 1187 } 1188 function getMinPrice() { 1189 // Only consider pack prices (individual units removed: 0/28 sales since 2026-02-28). 1190 var prices = window.currentPrices || {}; 1191 var packKeys = ['pack_essential', 'pack_pro', 'pack_business']; 1192 var min = Infinity; 1193 for (var i = 0; i < packKeys.length; i++) { 1194 var p = prices[packKeys[i]]; 1195 if (typeof p === 'number' && p < min) min = p; 1196 } 1197 return min === Infinity ? 19.90 : min; 1198 } 1199 function formatProtectPrice() { 1200 var p = Number(getMinPrice()).toFixed(2); 1201 if (lang !== 'en') p = p.replace('.', ','); 1202 return lang === 'en' ? '\u20AC' + p : p + '\u00A0\u20AC'; 1203 } 1204 1205 // ââ Shared revenue sync: localStorage is the single source of truth ââ 1206 var REVENUE_KEY = 'wl_hero_revenue'; 1207 var FINE_KEY = 'wl_hero_fine'; 1208 var DEFAULT_REVENUE = 50000; 1209 var fourPctLabel = lang === 'en' ? '4% of revenue' : lang === 'de' ? '4 % des Umsatzes' : lang === 'es' ? '4 % de la facturación' : lang === 'it' ? '4 % del fatturato' : lang === 'pt' ? '4 % da receita' : lang === 'ro' ? '4 % din venituri' : lang === 'cs' ? '4 % z obratu' : lang === 'el' ? '4 % ÏÎ¿Ï ÎºÏÎºÎ»Î¿Ï ÎµÏγαÏιÏν' : lang === 'hu' ? 'az árbevétel 4%-a' : lang === 'da' ? '4 % af omsætningen' : '4 % du CA'; 1210 1211 function saveRevenue(v) { 1212 localStorage.setItem(REVENUE_KEY, v); 1213 localStorage.setItem(FINE_KEY, getGdprFine(v)); 1214 window.dispatchEvent(new CustomEvent('revenueSync', { detail: { revenue: v } })); 1215 } 1216 function getSavedRevenue() { 1217 var s = localStorage.getItem(REVENUE_KEY); 1218 return s ? parseFloat(s) : DEFAULT_REVENUE; 1219 } 1220 1221 // Hero mini calculator 1222 (function() { 1223 var input = document.getElementById('hero-revenue'); 1224 var btn = document.getElementById('hero-calc-btn'); 1225 if (!btn || !input) return; 1226 1227 var resultEl = document.getElementById('hero-calc-result'); 1228 var amountEl = document.getElementById('hero-risk-amount'); 1229 var protectPriceEl = document.getElementById('hero-protect-price'); 1230 1231 function updateProtectPrice() { 1232 if (protectPriceEl) protectPriceEl.textContent = formatProtectPrice() + '\u00A0!'; 1233 } 1234 1235 updateProtectPrice(); 1236 window.addEventListener('pricesUpdated', updateProtectPrice); 1237 1238 var _lastDisplayedFine = 0; 1239 1240 function showFine(revenue, animate) { 1241 if (!resultEl || !amountEl) return; 1242 var v = parseFloat(revenue); 1243 if (!v || v <= 0) { 1244 amountEl.textContent = fourPctLabel; 1245 resultEl.classList.add('visible'); 1246 _lastDisplayedFine = 0; 1247 return; 1248 } 1249 var fine = getGdprFine(v); 1250 if (animate && _lastDisplayedFine > 0 && _lastDisplayedFine !== fine) { 1251 animateCounterHome(amountEl, fine); 1252 } else { 1253 amountEl.textContent = formatCurrency(fine); 1254 } 1255 updateProtectPrice(); 1256 resultEl.classList.add('visible'); 1257 _lastDisplayedFine = fine; 1258 } 1259 1260 // Init from localStorage 1261 var currentRaw = getSavedRevenue(); 1262 input.value = currentRaw; 1263 showFine(currentRaw, false); 1264 1265 input.addEventListener('input', function() { 1266 var v = parseFloat(input.value); 1267 if (v > 0) saveRevenue(v); 1268 showFine(v, true); 1269 }); 1270 1271 btn.addEventListener('click', function() { 1272 var revenue = parseFloat(input.value); 1273 if (!revenue || revenue <= 0) { 1274 input.classList.add('hero-input-shake'); 1275 input.focus(); 1276 setTimeout(function() { input.classList.remove('hero-input-shake'); }, 600); 1277 return; 1278 } 1279 saveRevenue(revenue); 1280 showFine(revenue, true); 1281 }); 1282 1283 input.addEventListener('keydown', function(e) { 1284 if (e.key === 'Enter') { e.preventDefault(); btn.click(); } 1285 }); 1286 1287 // Listen for sync from other calculators on the same page 1288 window.addEventListener('revenueSync', function(e) { 1289 var v = e.detail.revenue; 1290 if (parseFloat(input.value) !== v) { 1291 input.value = v; 1292 showFine(v, true); 1293 } 1294 }); 1295 })(); 1296 1297 // Hero calculator toggle 1298 (function() { 1299 var toggle = document.getElementById('hero-calc-toggle'); 1300 var group = document.getElementById('hero-calculator-group'); 1301 if (toggle && group) { 1302 toggle.addEventListener('click', function(e) { 1303 e.preventDefault(); 1304 var isHidden = group.style.display === 'none'; 1305 group.style.display = isHidden ? '' : 'none'; 1306 }); 1307 } 1308 })(); 1309 1310 // Hero URL scanner â redirects to form with URL pre-filled 1311 (function() { 1312 var urlInput = document.getElementById('hero-url-input'); 1313 var scanBtn = document.getElementById('hero-url-btn'); 1314 if (!scanBtn || !urlInput) return; 1315 1316 function doScan() { 1317 var url = urlInput.value.trim(); 1318 // Auto-add https:// if missing 1319 if (url && !url.match(/^https?:\/\//i)) url = 'https://' + url; 1320 if (!url || url.length < 10) return; 1321 1322 // GA4: track URL submission with A/B variant 1323 if (typeof gtag === 'function') { 1324 gtag('event', 'hero_url_submitted', { 1325 hero_variant: window.__heroVariant || 'A', 1326 event_category: 'ab_test', 1327 // Extension seule, jamais l'URL du site client (WL-B04). 1328 url_tld: window.wlUrlTld ? window.wlUrlTld(url) : 'unknown' 1329 }); 1330 } 1331
1332 // Get base language from URL path (en-usâen, fr-caâfr, pt-brâpt, de-châde) 1333 var pathLang = window.location.pathname.split('/')[1] || 'fr'; 1334 var baseLang = pathLang.split('-')[0]; // en-usâen, fr-caâfr, pt-brâpt 1335 var validLangs = ['fr','en','de','es','it','pt','nl','pl','sv','ro','cs','el','hu','da']; 1336 if (validLangs.indexOf(baseLang) === -1) baseLang = 'fr'; 1337 // Pass jurisdiction from current page (en-usâus-ccpa, fr-caâca-pipeda, etc.) 1338 var jurisdictionMap = {'en-us':'us-ccpa','en-gb':'uk-gdpr','en-ca':'ca-pipeda','en-au':'au-privacy','fr-ca':'ca-pipeda','pt-br':'br-lgpd','de-ch':'ch-revdsg','de-at':'eu-gdpr','es-mx':'eu-gdpr','fr-be':'eu-gdpr','fr-ch':'ch-revdsg'}; 1339 var juris = jurisdictionMap[pathLang] || ''; 1340 var scanParams = 'url=' + encodeURIComponent(url); 1341 if (juris) scanParams += '&jurisdiction=' + juris; 1342 var dest = '/' + baseLang + '/form/?' + scanParams; 1343 window.location.href = window.wlCarrySrc ? window.wlCarrySrc(dest) : dest; 1344 } 1345 1346 scanBtn.addEventListener('click', doScan); 1347 urlInput.addEventListener('keydown', function(e) { 1348 if (e.key === 'Enter') { e.preventDefault(); doScan(); } 1349 }); 1350 1351 // Restore last tested domain from localStorage 1352 try { 1353 var lastDomain = localStorage.getItem('activeFormDomain'); 1354 if (lastDomain && lastDomain !== 'default' && !urlInput.value) { 1355 urlInput.value = lastDomain; 1356 } 1357 } catch(e) {} 1358 })(); 1359 1360 // Full calculator section 1361 (function() { 1362 var calcBtn = document.getElementById('calculate-risk-btn'); 1363 if (!calcBtn) return; 1364 1365 var calcInput = document.getElementById('revenue-input'); 1366 1367 function updateCalcPrice() { 1368 var el = document.getElementById('calculator-price'); 1369 if (el) el.textContent = formatProtectPrice(); 1370 } 1371 1372 updateCalcPrice(); 1373 window.addEventListener('pricesUpdated', updateCalcPrice); 1374 1375 function showCalcFine(revenue, animate) { 1376 var resultEl = document.getElementById('calculator-result'); 1377 var amountEl = document.getElementById('risk-amount'); 1378 if (!resultEl || !amountEl) return; 1379 var v = parseFloat(revenue); 1380 if (!v || v <= 0 || getGdprFine(v) === 0) { 1381 amountEl.textContent = fourPctLabel; 1382 updateCalcPrice(); 1383 resultEl.classList.add('visible'); 1384 return; 1385 } 1386 if (animate) { 1387 animateCounterHome(amountEl, getGdprFine(v)); 1388 } else { 1389 amountEl.textContent = formatCurrency(getGdprFine(v)); 1390 } 1391 updateCalcPrice(); 1392 resultEl.classList.add('visible'); 1393 } 1394 1395 // Init from localStorage 1396 if (calcInput) { 1397 var saved = getSavedRevenue(); 1398 calcInput.value = saved; 1399 } 1400 1401 calcBtn.addEventListener('click', function() { 1402 var revenue = parseFloat(calcInput.value); 1403 if (!revenue || revenue <= 0) { 1404 calcInput.classList.add('hero-input-shake'); 1405 calcInput.focus(); 1406 setTimeout(function() { calcInput.classList.remove('hero-input-shake'); }, 600); 1407 showCalcFine(0, false); 1408 return; 1409 } 1410 saveRevenue(revenue); 1411 showCalcFine(revenue, true); 1412 }); 1413 1414 if (calcInput) { 1415 calcInput.addEventListener('input', function() { 1416 var v = parseFloat(calcInput.value); 1417 if (v > 0) saveRevenue(v); 1418 showCalcFine(v, true); 1419 }); 1420 calcInput.addEventListener('keydown', function(e) { 1421 if (e.key === 'Enter') { e.preventDefault(); calcBtn.click(); } 1422 }); 1423 } 1424 1425 // Listen for sync from other calculators on the same page 1426 window.addEventListener('revenueSync', function(e) { 1427 var v = e.detail.revenue; 1428 if (calcInput && parseFloat(calcInput.value) !== v) { 1429 calcInput.value = v; 1430 showCalcFine(v, true); 1431 } 1432 }); 1433 })(); 1434 1435 // FAQ Accordion toggle 1436 (function() { 1437 var triggers = document.querySelectorAll('.faq-accordion-trigger'); 1438 for (var i = 0; i < triggers.length; i++) { 1439 triggers[i].addEventListener('click', function() { 1440 this.parentElement.classList.toggle('active'); 1441 }); 1442 } 1443 1444 var showMoreBtn = document.getElementById('faq-show-more-btn'); 1445 var hiddenItems = document.getElementById('faq-hidden-items'); 1446 if (showMoreBtn && hiddenItems) { 1447 showMoreBtn.addEventListener('click', function() { 1448 hiddenItems.classList.add('faq-visible'); 1449 showMoreBtn.style.display = 'none'; 1450 }); 1451 } 1452 })(); 1453</script>
1453 <!-- Jurisdiction adapter: adapts hero/calculator for non-EU visitors on /en/ -->
1453<script src="/js/jurisdiction-adapter.js"></script>
1453 <!-- Footer --> <footer class="site-footer"> <div class="footer-content"> <div class="footer-main"> <div class="footer-logo"> <a href="#top" class="footer-logo-link"> <svg fill="none" height="36" viewBox="0 0 48 48" width="36" xmlns="http://www.w3.org/2000/svg"> <path d="m14.5 4.5h19c5.5228 0 10 4.47715 10 10v19c0 5.5228-4.4772 10-10 10h-19c-5.52285 0-10-4.4771-10-10v-19c0-5.52285 4.47715-10 10-10z" fill="#10b981"></path> <path d="m40.29 16.6145c-.2825.0274-.5651.0889-.8476.1846-.2826.0957-.5606.2165-.834.3623-.4193.237-.7178.4967-.8955.7793-.1777.2825-.3395.6243-.4854 1.0254-.5013 1.3854-1.2737 3.6048-2.3173 6.6582-1.0437 3.0534-2.1306 6.2252-3.2608 9.5156h-2.748l-5.127-14.4238-4.6211 14.4238h-2.748c-1.5222-4.4297-2.6888-7.8408-3.5-10.2334s-1.4948-4.4001-2.0508-6.0224c-.1732-.4922-.3691-.85-.5879-1.0733-.2187-.2233-.5013-.4489-.84765-.6767-.2461-.1641-.50814-.2849-.78614-.3624-.27799-.0774-.59928-.139-.96386-.1845v-1.0664h10.34965v1.039c-.6107.0729-1.0665.1436-1.3672.2119-.3008.0684-.5378.139-.711.212-.164.0729-.2643.1504-.3008.2324-.0364.082-.0546.1549-.0546.2187 0 .1276.0159.2507.0478.3692s.0661.2552.1026.4101c.2187.711.6608 2.0599 1.3261 4.0469.6654 1.987 1.4857 4.4525 2.461 7.3965l4.416-14.1367h2.8984l5.127 14.5742c.7565-2.3425 1.3603-4.2565 1.8115-5.7422s.8317-2.7572 1.1416-3.8145c.1823-.6471.3281-1.1894.4375-1.6269s.1641-.8158.1641-1.1348c0-.1914-.0889-.3554-.2666-.4922-.1778-.1367-.417-.2552-.7178-.3554-.2552-.0821-.5856-.1481-.9912-.1983-.4056-.0501-.7588-.0888-1.0596-.1162v-1.0937h7.8066z" fill="#fff"></path> </svg> <span class="logo-text logo-text-white">Web<em>Legal</em>.ai</span> </a> <p class="footer-desc"> AI-powered legal documents for websites and e-commerce. Save time, ensure compliance, and protect your business. </p> <div class="payment-security"> <div class="payment-method"> <div class="powered-by-stripe"> <span class="stripe-text">Secure payment by</span> <svg viewBox="0 0 60 25" xmlns="http://www.w3.org/2000/svg" width="60" height="25" class="stripe-svg"> <title>Logo Stripe</title> <path fill="currentColor" d="M59.64 14.28h-8.06c.19 1.93 1.6 2.55 3.2 2.55 1.64 0 2.96-.37 4.05-.95v3.32a8.33 8.33 0 0 1-4.56 1.1c-4.01 0-6.83-2.5-6.83-7.48 0-4.19 2.39-7.52 6.3-7.52 3.92 0 5.96 3.28 5.96 7.5 0 .4-.04 1.26-.06 1.48zm-5.92-5.62c-1.03 0-2.17.73-2.17 2.58h4.25c0-1.85-1.07-2.58-2.08-2.58zM40.95 20.3c-1.44 0-2.32-.6-2.9-1.04l-.02 4.63-4.12.87V5.57h3.76l.08 1.02a4.7 4.7 0 0 1 3.23-1.29c2.9 0 5.62 2.6 5.62 7.4 0 5.23-2.7 7.6-5.65 7.6zM40 8.95c-.95 0-1.54.34-1.97.81l.02 6.12c.4.44.98.78 1.95.78 1.52 0 2.54-1.65 2.54-3.87 0-2.15-1.04-3.84-2.54-3.84zM28.24 5.57h4.13v14.44h-4.13V5.57zm0-4.7L32.37 0v3.36l-4.13.88V.88zm-4.32 9.35v9.79H19.8V5.57h3.7l.12 1.22c1-1.77 3.07-1.41 3.62-1.22v3.79c-.52-.17-2.29-.43-3.32.86zm-8.55 4.72c0 2.43 2.6 1.68 3.12 1.46v3.36c-.55.3-1.54.54-2.89.54a4.15 4.15 0 0 1-4.27-4.24l.01-13.17 4.02-.86v3.54h3.14V9.1h-3.13v5.85zm-4.91.7c0 2.97-2.31 4.66-5.73 4.66a11.2 11.2 0 0 1-4.46-.93v-3.93c1.38.75 3.1 1.31 4.46 1.31.92 0 1.53-.24 1.53-1C6.26 13.77 0 14.51 0 9.95 0 7.04 2.28 5.3 5.62 5.3c1.36 0 2.72.2 4.09.75v3.88a9.23 9.23 0 0 0-4.1-1.06c-.86 0-1.44.25-1.44.9 0 1.85 6.29.97 6.29 5.88z" fill-rule="evenodd"></path> </svg> </div> </div> </div> <div class="footer-newsletter-inline"> <h2>Stay Updated</h2> <form class="newsletter-form" method="post" action="https://mailzy.cc/campaign/subscribe?sid=news%40lauyan.com&lid=M9IP314533KABVQVL&sign=RTEruPll707OQK25p54ErW7czGUyroQQSdHgAKMvqLM%3D" target="_top"> <label for="mzemail" class="newsletter-label">Email address for newsletter</label> <div class="input-group"> <input required type="email" name="email" id="mzemail" placeholder="Your email address" class="newsletter-input" aria-label="Email address for newsletter"> <button type="submit" class="newsletter-button" aria-label="Subscribe"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="white" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M12.75 15l3-3m0 0l-3-3m3 3h-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> </button> </div> </form> </div> </div> <div class="footer-col"> <h2>Products</h2> <ul> <li> <a href="/en/form/">Terms of Use Generator</a> </li> <li> <a href="/en/form/">Privacy Policy Generator</a> </li> <li> <a href="/en/form/">Cookie Policy Generator</a> </li> <li> <a href="/en/form/">Terms of Sale Generator</a> </li> <li> <a href="/en/scan/">Free GDPR Scanner</a> </li> <li><a href="/en/privacy-checker/">Privacy policy checker</a></li> <li><a href="/en/cookie-checker/">Cookie checker</a></li> <li> <a href="/en/alternatives/">Compare alternatives</a> </li> </ul> <h2>Other Products</h2> <ul> <li> <a href="https://www.lauyan.com" target="_blank" rel="noopener"> <strong>TOWeb</strong> - Website &
1453 online store builder </a> </li> <li> <a href="https://pagexl.com" target="_blank" rel="noopener"> <strong>PageXL</strong> - One-page website builder </a> </li> <li> <a href="https://mailzy.cc" target="_blank" rel="noopener"> <strong>Mailzy</strong> - Email marketing software </a> </li> <li> <a href="https://screenzy.io" target="_blank" rel="noopener"> <strong>Screenzy</strong> - Screenshot enhancement tool </a> </li> </ul> </div> <div class="footer-col"> <h2>Legal Resources</h2> <ul> <li> <a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/terms-of-use/?credit=1" target="_blank" rel="noopener">Terms of Use</a> </li> <li> <a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/privacy-policy/?credit=1" target="_blank" rel="noopener">Privacy Policy</a> </li> <li> <a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/cookie-policy/?credit=1" target="_blank" rel="noopener">Cookie Policy</a> </li> <li> <a href="https://weblegal.ai/documents/lauyan-software/weblegal-ai/terms-of-sale/?credit=1" target="_blank" rel="noopener">Terms of Sale</a> </li> <li> <a href="/en/#how-it-works">AI Document Generation</a> </li> <li> <a href="/en/docs/">Documentation & Integration</a> </li> <li> <a href="/en/cookie-banner/">Free Cookie Banner</a> </li> </ul> </div> <div class="footer-col"> <h2>Blog</h2> <ul> <li> <a href="/en/blog/barometre-conformite-2026-09/">What 1,068 scanned websites told us</a> </li><li> <a href="/en/blog/joomla-consent-mode-v2-no-plugin/">Joomla Consent Mode v2: No Plugin Needed</a> </li><li> <a href="/en/blog/global-privacy-control-complete-guide/">Global Privacy Control (GPC): 2026 Guide</a> </li><li> <a href="/en/blog/weblegal-vs-cookieyes-consent-mode-and-docs/">WebLegal vs CookieYes: Consent Mode & Docs</a> </li><li> <a href="/en/blog/weblegal-vs-iubenda-which-to-choose-2026/">WebLegal vs iubenda: which to choose 2026</a> </li> <li> <a href="/en/blog/" class="footer-all-articles">All articles →</a> </li> </ul> </div> </div> <div class="footer-bottom"> <div class="copyright"> 1454© 2026 WebLegal - All rights reserved | Made with â¤ï¸ by <a href="https://www.lauyan.com" target="_blank" rel="noopener" aria-label="Lauyan Software website (opens in new tab)"> 1455Lauyan Software 1456</a> <span class="footer-sep" aria-hidden="true"> | </span> <a href="/en/press/">Press kit</a> </div> <div class="footer-language-selector"> <div class="lang-dropdown" id="footerLangDropdown"> <button type="button" class="lang-dropdown-toggle footer-lang-toggle" id="footerLangDropdownToggle" aria-label="Select country" aria-expanded="false"> <img src="/img/flags/eu.svg" width="20" height="20" alt="Europe (EN)" style="border-radius:50%;object-fit:cover;width:20px;height:20px"> <span style="font-size:12px">Europe (EN)</span> <svg class="lang-chevron" width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"> <path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path> </svg> </button> <div class="lang-dropdown-menu lang-dropdown-menu-up" id="footerLangDropdownMenu" style="width:420px;padding:8px"> <div style="display:flex;flex-direction:column"> <a href="/fr/" class="lang-option" data-lang="fr" data-path="/fr/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/fr.svg" width="18" height="18" alt="France" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>France</span> </a><a href="/fr-be/" class="lang-option" data-lang="fr" data-path="/fr-be/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/be.svg" width="18" height="18" alt="Belgique" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Belgique</span> </a><a href="/fr-ch/" class="lang-option" data-lang="fr" data-path="/fr-c
1456h/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ch.svg" width="18" height="18" alt="Suisse FR" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Suisse FR</span> </a><a href="/de/" class="lang-option" data-lang="de" data-path="/de/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/de.svg" width="18" height="18" alt="Deutschland" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Deutschland</span> </a><a href="/de-at/" class="lang-option" data-lang="de" data-path="/de-at/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/at.svg" width="18" height="18" alt="Ãsterreich" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Ãsterreich</span> </a><a href="/de-ch/" class="lang-option" data-lang="de" data-path="/de-ch/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ch.svg" width="18" height="18" alt="Schweiz DE" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Schweiz DE</span> </a><a href="/pl/" class="lang-option" data-lang="pl" data-path="/pl/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/pl.svg" width="18" height="18" alt="Polska" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Polska</span> </a><a href="/sv/" class="lang-option" data-lang="sv" data-path="/sv/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/se.svg" width="18" height="18" alt="Sverige" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Sverige</span> </a><a href="/cs/" class="lang-option" data-lang="cs" data-path="/cs/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/cz.svg" width="18" height="18" alt="Äesko" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Äesko</span> </a><a href="/hu/" class="lang-option" data-lang="hu" data-path="/hu/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/hu.svg" width="18" height="18" alt="Magyarország" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Magyarország</span> </a> </div><div style="display:flex;flex-direction:column"> <a href="/en/" class="lang-option active" data-lang="en" data-path="/en/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/eu.svg" width="18" height="18" alt="Europe (EN)" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Europe (EN)</span> </a><a href="/en-gb/" class="lang-option" data-lang="en" data-path="/en-gb/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/gb.svg" width="18" height="18" alt="United Kingdom" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>United Kingdom</span> </a><a href="/es/" class="lang-option" data-lang="es" data-path="/es/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/es.svg" width="18" height="18" alt="España" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>España</span> </a><a href="/es-mx/" class="lang-option" data-lang="es" data-path="/es-mx/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/mx.svg" width="18" height="18" alt="México" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>México</span> </a><a href="/it/" class="lang-option" data-lang="it" data-path="/it/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/it.svg" width="18" height="18" alt="Italia" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Italia</span> </a><a href="/pt/" class="lang-option" data-lang="pt" data-path="/pt/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/pt.svg" width="18" height="18" alt="Portugal" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Portugal</span> </a><a href="/nl/" class="lang-option" data-lang="nl" data-path="/nl/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/nl.svg" width="18" height="18" alt="Nederland" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Nederland</span> </a><a href="/ro/" class="lang-option" data-lang="ro" data-path="/ro/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ro.svg" width="18" height="18" alt="România" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>România</span> </a><a href="/el/" class="lang-option" data-lang="el" data-path="/el/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/gr.svg" width="18" height="18" alt="Îλλάδα" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Îλλάδα</span> </a><a href="/da/" class="lang-option" data-lang="da" data-path="/da/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/dk.svg" width="18" height="18" alt="Danmark" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Danmark</span> </a> </div><div style="display:flex;flex-direction:column"> <a href="/en-us/" class="lang-option" data-lang="en" data-path="/en-us/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/us.svg" width="18" height="18" alt="United States" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>United States</span> </a><a href="/en-ca/" class="lang-option" data-lang="en" data-path="/en-ca/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ca.svg" width="18" height="18" alt="Canada EN" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Canada EN</span> </a><a href="/fr-ca/" class="lang-option" data-lang="fr" data-path="/fr-ca/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/ca.svg" width="18" height="18" alt="Canada FR" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Canada FR</span> </a><a href="/pt-br/" class="lang-option" data-lang="pt" data-path="/pt-br/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/br.svg" width="18" height="18" alt="Brasil" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Brasil</span> </a><a href="/en-au/" class="lang-option" data-lang="en" data-path="/en-au/" style="display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:11px;white-space:nowrap;text-decoration:none;border-radius:4px"> <img src="/img/flags/au.svg" width="18" height="18" alt="Australia" style="border-radius:50%;object-fit:cover;width:18px;height:18px;flex-shrink:0" loading="lazy"> <span>Australia</span> </a> </div> </div> </div> </div> </div> </div> </footer>
1456<script type="module">document.addEventListener("DOMContentLoaded",function(){const t=document.getElementById("footerLangDropdown"),n=document.getElementById("footerLangDropdownToggle");if(!t||!n)return;n.addEventListener("click",function(o){o.stopPropagation(),t.classList.toggle("open"),n.setAttribute("aria-expanded",String(t.classList.contains("open")))}),document.addEventListener("click",function(){t.classList.remove("open"),n.setAttribute("aria-expanded","false")});const i=document.getElementById("translation-links");i&&t.querySelectorAll(".lang-option").forEach(function(o){o.addEventListener("click",function(r){const a=this.getAttribute("data-lang")||"";try{const e=JSON.parse(i.getAttribute("data-links")||"{}");e[a]&&(r.preventDefault(),window.location.href=window.wlCarrySrc?window.wlCarrySrc(e[a]):e[a])}catch{}})})});</script>
1456 <!-- Core JavaScript: critical (sync) + main (deferred) -->
1456<script src="/js/core-critical.js?v=4"></script>
1456
1456<script> 1457 // Load core.js deferred (is:inline does not support defer attribute) 1458 var _coreScript = document.createElement('script'); 1459 _coreScript.src = '/js/core.js?v=2'; 1460 _coreScript.defer = true; 1461 document.head.appendChild(_coreScript); 1462 // currency manager â listens for wl-currency-ready and swaps prices 1463 var _currencyScript = document.createElement('script'); 1464 _currencyScript.src = '/js/wl-currency.js'; 1465 _currencyScript.defer = true; 1466 document.head.appendChild(_currencyScript); 1467 </script>
1467 <!-- Theme Switcher Script --> 1468
1468<script type="module">const b={threshold:.1,rootMargin:"0px 0px -50px 0px"},d=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-in"),t.target.classList.contains("stagger-children")&&Array.from(t.target.children).forEach((r,s)=>{r.style.transitionDelay=`${s*100}ms`,r.classList.add("animate-in")}),t.target.classList.contains("stagger-grid")&&Array.from(t.target.children).forEach((r,s)=>{r.style.transitionDelay=`${s*70}ms`,r.classList.add("animate-in")}),d.unobserve(t.target))})},b);document.querySelectorAll(".fade-on-scroll, .slide-left-on-scroll, .slide-right-on-scroll, .scale-on-scroll, .stagger-children, .stagger-grid").forEach(e=>{d.observe(e)});const g=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-pop"),g.unobserve(t.target))})},{threshold:.3});document.querySelectorAll(".stat-item").forEach(e=>g.observe(e));const f=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-pop"),f.unobserve(t.target))})},{threshold:.2});document.querySelectorAll(".timeline-step").forEach(e=>f.observe(e));const u=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-slide"),u.unobserve(t.target))})},{threshold:.2});document.querySelectorAll(".risk-bullet").forEach(e=>u.observe(e));const h=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-scale"),h.unobserve(t.target))})},{threshold:.15});document.querySelectorAll(".audience-card").forEach(e=>h.observe(e));const v=new IntersectionObserver(e=>{e.forEach(t=>{t.isIntersecting&&(t.target.classList.add("animate-underline"),v.unobserve(t.target))})},{threshold:.5});document.querySelectorAll(".section-redesigned .section-title").forEach(e=>v.observe(e));document.querySelectorAll(".audience-card, .testimonial-compact").forEach(e=>{e.addEventListener("mousemove",t=>{const r=t,s=e.getBoundingClientRect(),n=r.clientX-s.left,i=r.clientY-s.top,a=s.width/2,o=s.height/2,l=(i-o)/o*-6,c=(n-a)/a*6;e.style.transform=`perspective(800px) rotateX(${l}deg) rotateY(${c}deg) translateY(-4px)`}),e.addEventListener("mouseleave",()=>{e.style.transform=""})});document.querySelectorAll(".counter-animate").forEach(e=>{const t=parseInt(e.dataset.target||"0",10);if(!t)return;const r=e.dataset.suffix||"",s=e.dataset.prefix||"",n=new IntersectionObserver(i=>{i.forEach(a=>{if(a.isIntersecting){let o=0;const c=t/(2e3/16),m=setInterval(()=>{o+=c,o>=t&&(o=t,clearInterval(m)),e.textContent=s+Math.floor(o).toLocaleString()+r},16);n.unobserve(e)}})},{threshold:.5});n.observe(e)});</script>
1468 1469 1470 <!-- Header Language Switcher Script --> 1471 <!-- Language Dropdown Script --> 1472
1472<script> 1473 document.addEventListener('DOMContentLoaded', function () { 1474 1475 // Desktop dropdown 1476 var dropdown = document.getElementById('langDropdown'); 1477 var toggle = document.getElementById('langDropdownToggle'); 1478 if (dropdown && toggle) { 1479 toggle.addEventListener('click', function (e) { 1480 e.stopPropagation(); 1481 dropdown.classList.toggle('open'); 1482 toggle.setAttribute('aria-expanded', dropdown.classList.contains('open')); 1483 }); 1484 // Language clicks â smart redirect: keep current page, swap locale prefix 1485 var translationEl = document.getElementById('translation-links'); 1486 var blogLinks = null; 1487 if (translationEl) { 1488 try { blogLinks = JSON.parse(translationEl.getAttribute('data-links') || '{}'); } catch(_) {} 1489 } 1490 dropdown.querySelectorAll('.lang-option').forEach(function (opt) { 1491 opt.addEventListener('click', function (e) { 1492 var targetPath = this.getAttribute('data-path'); // e.g. /en/ or /de-ch/ 1493 var targetLang = this.getAttribute('data-lang'); // e.g. en, de (base lang) 1494 // Explicit choice: never auto-redirect this visitor to another variant again. 1495 document.cookie = 'wl_locale_pin=1; max-age=2592000; path=/; samesite=lax'; 1496 1497 // Blog articles: use translation slug mapping (slugs differ per language) 1498 if (blogLinks) { 1499 e.preventDefault(); 1500 if (blogLinks[targetLang]) { 1501 // Translation exists â navigate to translated article 1502 window.location.href = (window.wlCarrySrc ? window.wlCarrySrc(blogLinks[targetLang]) : blogLinks[targetLang]); 1503 } else { 1504 // No translation â go to blog index in target language (never 404) 1505 window.location.href = (window.wlCarrySrc ? window.wlCarrySrc('/' + targetLang + '/blog/') : '/' + targetLang + '/blog/'); 1506 } 1507 return; 1508 } 1509 1510 // Other pages: replace locale prefix in current URL 1511 var currentPath = window.location.pathname; 1512 // Match current locale prefix: /xx/ or /xx-yy/ 1513 var match = currentPath.match(/^\/([a-z]{2}(?:-[a-z]{2})?)(\/.*)$/); 1514 if (match && match[2] !== '/') { 1515 e.preventDefault(); 1516 // Use baseLang (not regional path) for sub-pages to avoid 404 1517 // Regional variants only have a homepage â sub-pages use base lang 1518 window.location.href = (window.wlCarrySrc ? window.wlCarrySrc('/' + targetLang + match[2]) : '/' + targetLang + match[2]); 1519 } 1520 // else: on homepage â let the default href work (regional paths exist) 1521 }); 1522 }); 1523 // Close on click outside 1524 document.addEventListener('click', function () { 1525 dropdown.classList.remove('open'); 1526 toggle.setAttribute('aria-expanded', 'false'); 1527 }); 1528 } 1529 1530 // Mobile language switcher â smart redirect like desktop 1531 document.addEventListener('change', function (e) { 1532 if (e.target && e.target.id === 'mobileLanguageSwitcher') { 1533 var targetPath = e.target.value; // e.g. /en/ or /de-ch/ 1534 // Explicit choice: never auto-redirect this visitor to another variant again. 1535 document.cookie = 'wl_locale_pin=1; max-age=2592000; path=/; samesite=lax'; 1536 var selectedOption = e.target.options[e.target.selectedIndex]; 1537 var baseLang = selectedOption ? selectedOption.getAttribute('data-lang') : null; 1538 var currentPath = window.location.pathname; 1539 var match = currentPath.match(/^\/([a-z]{2}(?:-[a-z]{2})?)(\/.*)$/); 1540 if (match && match[2] !== '/' && baseLang) { 1541 // Sub-page: use baseLang to avoid 404 on regional variants 1542 window.location.href = (window.wlCarrySrc ? window.wlCarrySrc('/' + baseLang + match[2]) : '/' + baseLang + match[2]); 1543 } else { 1544 // Homepage: use regional path directly 1545 window.location.href = (window.wlCarrySrc ? window.wlCarrySrc(targetPath) : targetPath); 1546 } 1547 } 1548 }); 1549 }); 1550 </script>
1550 1551 1552 <!-- Mobile Menu Script --> 1553
1553<script type="module">document.querySelectorAll('a[href*="#"]').forEach(s=>{s.addEventListener("click",function(a){const t=this.getAttribute("href");if(!t)return;const e=t.indexOf("#");if(e===-1)return;const n=t.substring(e),r=t.substring(0,e),c=window.location.pathname.replace(/\/$/,""),i=r.replace(/\/$/,"");if((!r||i===c)&&n.length>1){const o=document.querySelector(n);o&&(a.preventDefault(),o.scrollIntoView({behavior:"smooth",block:"start"}),history.pushState(null,"",n))}})});</script>
1553 <!-- Smooth Scrolling (handles both #hash and /path/#hash on same page) -->
1553<script type="module">document.addEventListener("DOMContentLoaded",function(){const n=document.querySelector(".mobile-menu-toggle");if(n){const e=document.createElement("div");e.id="mobile-menu",e.className="mobile-menu-hidden",window.innerWidth>1180&&(e.style.display="none");const d=document.querySelectorAll(".nav-menu .nav-link"),o=document.querySelector(".nav-menu .btn-primary");let i=` 1554 <button class="mobile-menu-close" aria-label="Close menu"> 1555 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 1556 <line x1="18" y1="6" x2="6" y2="18"></line> 1557 <line x1="6" y1="6" x2="18" y2="18"></line> 1558 </svg> 1559 </button> 1560 <nav>`;d.forEach(function(t){i+=`<a href="${t.getAttribute("href")}">${t.textContent.trim()}</a>`}),o&&(i+=`<a href="${o.getAttribute("href")}" class="btn-primary">${o.textContent.trim()}</a>`);var l=document.getElementById("langDropdown");if(l){var c=l.querySelectorAll(".lang-option"),r=document.documentElement.lang||"fr",s="";c.forEach(function(t){var a=t.getAttribute("data-lang"),m=t.getAttribute("data-path"),u=a===r?" selected":"";s+='<option value="'+m+'" data-lang="'+a+'"'+u+">"+a.toUpperCase()+"</option>"}),i+='<div class="mobile-language-selector"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg><select id="mobileLanguageSwitcher" aria-label="Language">'+s+"</select></div>"}i+="</nav>",e.innerHTML=i,document.body.appendChild(e),n.addEventListener("click",function(){this.classList.toggle("active"),e.classList.toggle("active"),document.body.classList.toggle("menu-open")}),e.addEventListener("click",function(t){(t.target.tagName==="A"||t.target.closest(".mobile-menu-close"))&&(n.classList.remove("active"),e.classList.remove("active"),document.body.classList.remove("menu-open"))}),document.addEventListener("click",function(t){!t.target.closest(".mobile-menu-toggle")&&!t.target.closest("#mobile-menu")&&(n.classList.remove("active"),e.classList.remove("active"),document.body.classList.remove("menu-open"))}),window.addEventListener("resize",function(){window.innerWidth>1180?(e.style.display="none",n.classList.remove("active"),e.classList.remove("active"),document.body.classList.remove("menu-open")):e.style.display=""})}});</script>
1560 <!-- Scroll Animation Observer (all pages) -->
1560<script type="module">document.addEventListener("DOMContentLoaded",function(){const t=document.getElementById("themeSwitcher");if(t){const e=document.createElement("div");e.style.position="absolute",e.style.top="0",e.style.left="0",e.style.width="100%",e.style.height="100%",e.style.zIndex="100",e.style.cursor="pointer",t.style.position="relative",t.appendChild(e),e.addEventListener("click",function(o){o.stopPropagation();var l=localStorage.getItem("theme");return l?l==="light"?(localStorage.setItem("theme","dark"),window.__applyTheme("dark")):(localStorage.removeItem("theme"),window.__applyTheme(null)):(localStorage.setItem("theme","light"),window.__applyTheme("light")),!1})}});</script>
1560 <!-- WebLegal Cookie Consent Banner â uses the public "bottom" preset 1561 (full-width bar) so it never covers the hero scanner/CTA on the left. 1562 WebLegal must use the same preset options as any third-party client. 1563 privacy-url points to WebLegal's own cookie policy (fallback to EN for 1564 languages where the localized policy doesn't exist yet). -->
1564<script src="/js/wl-cookie-consent.js" data-position="bottom" data-privacy-url="https://weblegal.ai/documents/lauyan-software/weblegal-ai/cookie-policy/?credit=1"></script>
1564 </body> </html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.