1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 8 <!-- Primary Meta Tags --> 9 <title>LinkGuard.ai â Protect Your Backlink Investments | Automated Monitoring & Alerts</title> 10 <meta name="title" content="LinkGuard.ai â Protect Your Backlink Investments | Automated Monitoring & Alerts"> 11 <meta name="description" content="Stop losing $300-1000 backlinks silently. LinkGuard monitors 24/7, sends instant alerts when links change. Pay-as-you-go, no subscriptions."> 12 <meta name="keywords" content="backlink monitoring, link building, SEO tools, backlink checker, link tracker, SEO monitoring, backlink alerts, link building CRM, dofollow checker, nofollow detector, SERP monitoring, backlink protection, SEO agency tools, link management"> 13 <meta name="author" content="LinkGuard.ai"> 14 <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"> 15 <meta name="googlebot" content="index, follow"> 16 <link rel="canonical" href="https://linkguard.ai/"> 17 18 <!-- Favicon - All Required Sizes --> 19 <link rel="icon" href="/static/img/icons/favicon.ico" sizes="16x16 32x32 48x48"> 20 <link rel="icon" type="image/svg+xml" href="/static/img/icons/favicon.svg"> 21 <link rel="icon" type="image/png" sizes="32x32" href="/static/img/icons/favicon-32x32.png"> 22 <link rel="icon" type="image/png" sizes="16x16" href="/static/img/icons/favicon-16x16.png"> 23 <link rel="apple-touch-icon" sizes="180x180" href="/static/img/icons/apple-touch-icon.png"> 24 <link rel="apple-touch-icon" sizes="152x152" href="/static/img/icons/apple-touch-icon-152x152.png"> 25 <link rel="apple-touch-icon" sizes="120x120" href="/static/img/icons/apple-touch-icon-120x120.png"> 26 <link rel="mask-icon" href="/static/img/icons/safari-pinned-tab.svg" color="#00f5d4"> 27 <link rel="manifest" href="/static/manifest.json"> 28 <meta name="msapplication-TileImage" content="/static/img/icons/mstile-150x150.png"> 29 30 <!-- Open Graph / Facebook --> 31 <meta property="og:type" content="website"> 32 <meta property="og:url" content="https://linkguard.ai/"> 33 <meta property="og:title" content="LinkGuard.ai â Protect Your Backlink Investments"> 34 <meta property="og:description" content="Stop losing $300-1000 backlinks silently. Automated monitoring with instant alerts when links are removed or changed. Pay-as-you-go, no subscriptions."> 35 <meta property="og:image" content="https://linkguard.ai/static/img/og/og-homepage-v2.png"> 36 <meta property="og:image:width" content="1200"> 37 <meta property="og:image:height" content="630"> 38 <meta property="og:image:alt" content="LinkGuard.ai - Backlink Monitoring Dashboard"> 39 <meta property="og:site_name" content="LinkGuard.ai"> 40 <meta property="og:locale" content="en_US"> 41 42 <!-- Twitter Card --> 43 <meta name="twitter:card" content="summary_large_image"> 44 <meta name="twitter:url" content="https://linkguard.ai/"> 45 <meta name="twitter:title" content="LinkGuard.ai â Protect Your Backlink Investments"> 46 <meta name="twitter:description" content="Stop losing $300-1000 backlinks silently. Automated monitoring with instant alerts. Pay-as-you-go pricing."> 47 <meta name="twitter:image" content="https://linkguard.ai/static/img/og/og-homepage-v2.png"> 48 <meta name="twitter:image:alt" content="LinkGuard.ai - Backlink Monitoring Dashboard"> 49 <meta name="twitter:creator" content="@o638562538"> 50 <meta name="twitter:site" content="@o638562538"> 51 52 <!-- Additional SEO Meta --> 53 <meta name="theme-color" content="#0a0a0f"> 54 <meta name="msapplication-TileColor" content="#0a0a0f"> 55 <meta name="format-detection" content="telephone=no"> 56 <meta name="mobile-web-app-capable" content="yes"> 57 <meta name="apple-mobile-web-app-capable" content="yes"> 58 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 59 <meta name="apple-mobile-web-app-title" content="LinkGuard"> 60 61 <!-- Structured Data - Organization --> 62
62<script type="application/ld+json"> 63 { 64 "@context": "https://schema.org", 65 "@type": "Organization", 66 "name": "LinkGuard.ai", 67 "url": "https://linkguard.ai", 68 "logo": "https://linkguard.ai/static/img/logo/logo.png", 69 "description": "Automated backlink monitoring platform with instant alerts for link building professionals.", 70 "foundingDate": "2025", 71 "sameAs": [ 72 "https://x.com/o638562538", 73 "https://www.linkedin.com/in/andrievskiiandr/", 74 "https://github.com/Black-coffe", 75 "https://www.youtube.com/@andrievskii" 76 ], 77 "contactPoint": { 78 "@type": "ContactPoint", 79 "contactType": "customer support", 80 "email": "[email protected]" 81 } 82 } 83 </script>
83 84 85 <!-- Structured Data - SoftwareApplication --> 86
86<script type="application/ld+json"> 87 { 88 "@context": "https://schema.org", 89 "@type": "SoftwareApplication", 90 "name": "LinkGuard.ai", 91 "applicationCategory": "BusinessApplication", 92 "operatingSystem": "Web", 93 "description": "Automated backlink monitoring with instant alerts. Protect your link building investments.", 94 "url": "https://linkguard.ai", 95 "offers": { 96 "@type": "AggregateOffer", 97 "lowPrice": "10", 98 "highPrice": "500", 99 "priceCurrency": "USD", 100 "offerCount": "4" 101 }, 102 "featureList": [ 103 "SERP indexation monitoring", 104 "HTML link status verification", 105 "Email notifications", 106 "Slack notifications", 107 "Per-project Slack channel routing" 108 ] 109 } 110 </script>
110 111 112 <!-- Structured Data - FAQ --> 113
113<script type="application/ld+json"> 114 { 115 "@context": "https://schema.org", 116 "@type": "FAQPage", 117 "mainEntity": [ 118 { 119 "@type": "Question", 120 "name": "How quickly can I get started with LinkGuard?", 121 "acceptedAnswer": { 122 "@type": "Answer", 123 "text": "Under 5 minutes. Sign up, upload your CSV or add links manually, and monitoring starts immediately. No API keys needed, no complex setup." 124 } 125 }, 126 { 127 "@type": "Question", 128 "name": "What types of backlink checks does LinkGuard perform?", 129 "acceptedAnswer": { 130 "@type": "Answer", 131 "text": "Two main types: SERP checks (is the page indexed in Google?) and HTML checks (does the link exist, what's the anchor text, is it dofollow/nofollow?). Both are essential for complete monitoring." 132 } 133 }, 134 { 135 "@type": "Question", 136 "name": "How fast are the backlink alerts?", 137 "acceptedAnswer": { 138 "@type": "Answer", 139 "text": "Alerts are sent within minutes of detecting a change. You'll get notified via Email and/or Slack (your choice) with full details of what changed." 140 } 141 }, 142 { 143 "@type": "Question", 144 "name": "Do I get free tokens to start?", 145 "acceptedAnswer": { 146 "@type": "Answer", 147 "text": "Yes! Every new user receives 1,000 free tokens after verifying their email. Tokens never expire â no trial period, no forced purchase." 148 } 149 }, 150 { 151 "@type": "Question", 152 "name": "Do tokens expire in LinkGuard?", 153 "acceptedAnswer": { 154 "@type": "Answer", 155 "text": "No, tokens never expire. Once you purchase tokens, they remain in your account until you use them. There are no monthly fees or subscriptions." 156 } 157 }, 158 { 159 "@type": "Question", 160 "name": "Why was VAT added to my total at checkout?", 161 "acceptedAnswer": { 162 "@type": "Answer", 163 "text": "Prices on LinkGuard are shown in USD exclusive of tax. If your country charges VAT, GST, or sales tax on digital services, Paddle â our Merchant of Record â calculates the correct rate based on your billing country and adds it at checkout. Paddle remits that tax to your local authority on our behalf, and you receive an invoice with the full breakdown." 164 } 165 } 166 ] 167 } 168 </script>
168 169 170 <!-- Structured Data - WebSite with SearchAction --> 171
171<script type="application/ld+json"> 172 { 173 "@context": "https://schema.org", 174 "@type": "WebSite", 175 "name": "LinkGuard.ai", 176 "url": "https://linkguard.ai", 177 "description": "Automated backlink monitoring platform for SEO professionals and link building agencies.", 178 "publisher": { 179 "@type": "Organization", 180 "name": "LinkGuard.ai" 181 } 182 } 183 </script>
183 184 185 <!-- Structured Data - SiteNavigationElement --> 186
186<script type="application/ld+json"> 187 { 188 "@context": "https://schema.org", 189 "@graph": [ 190 { 191 "@type": "SiteNavigationElement", 192 "name": "Benefits", 193 "url": "https://linkguard.ai/#benefits" 194 }, 195 { 196 "@type": "SiteNavigationElement", 197 "name": "How It Works", 198 "url": "https://linkguard.ai/#how-it-works" 199 }, 200 { 201 "@type": "SiteNavigationElement", 202 "name": "Features", 203 "url": "https://linkguard.ai/#features" 204 }, 205 { 206 "@type": "SiteNavigationElement", 207 "name": "Pricing", 208 "url": "https://linkguard.ai/#pricing" 209 }, 210 { 211 "@type": "SiteNavigationElement", 212 "name": "FAQ", 213 "url": "https://linkguard.ai/#faq" 214 } 215 ] 216 } 217 </script>
217 218 219 <!-- Preconnect for performance --> 220 <link rel="preconnect" href="https://fonts.googleapis.com"> 221 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 222 <link rel="preconnect" href="https://unpkg.com"> 223 <link rel="dns-prefetch" href="https://fonts.googleapis.com"> 224 <link rel="dns-prefetch" href="https://unpkg.com"> 225 226 <!-- Fonts - Cyberpunk Typography --> 227 <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=Rajdhani:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet"> 228 229 <!-- Styles --> 230 <link rel="stylesheet" href="/static/landing/styles.css"> 231 <!-- Statable Analytics (site 3300732) - cookieless, EU-hosted. Public pages only. --> 232
232<script src="https://statable.com/js/3300732/s.js" defer></script>
232 233 234</head> 235<body itemscope itemtype="https://schema.org/WebPage"> 236 237 <!-- Shader Background Canvas --> 238 <canvas id="shader-bg"></canvas> 239 240 <!-- Grid Overlay --> 241 <div class="grid-overlay" aria-hidden="true"></div> 242 243 <!-- Scanlines Effect --> 244 <div class="scanlines" aria-hidden="true"></div> 245 246 <!-- Skip to main content link for accessibility --> 247 <a href="#main-content" class="skip-link">Skip to main content</a> 248 249 <!-- ============ WELCOME BONUS RIBBON ============ --> 250 <div class="wb-ribbon" id="wb-ribbon" role="banner" aria-label="Welcome bonus announcement"> 251 <div class="wb-ribbon-inner"> 252 <svg class="wb-ribbon-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 253 <polyline points="20 12 20 22 4 22 4 12"/><rect x="2" y="7" width="20" height="5"/><line x1="12" y1="22" x2="12" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/> 254 </svg> 255 <span class="wb-ribbon-badge">WELCOME_BONUS</span> 256 <span class="wb-ribbon-text">1,000 tokens on signup â no card required.</span> 257 <a href="/register" class="wb-ribbon-cta">Start free →</a> 258 </div> 259 <button class="wb-ribbon-close" id="wb-ribbon-close" aria-label="Dismiss announcement"> 260 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 261 <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/> 262 </svg> 263 </button> 264 </div> 265 266 <!-- ============ HEADER ============ --> 267 <header id="header" role="banner" aria-label="Main navigation"> 268 <div class="container"> 269 <div class="header-inner"> 270 <a href="/" class="logo" aria-label="LinkGuard.ai - Home" itemprop="url"> 271 <div class="logo-icon" aria-hidden="true"> 272 <svg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 100 100"> 273 <defs> 274 <linearGradient id="logoShieldBg" x1="0%" y1="0%" x2="100%" y2="100%"> 275 <stop offset="0%" stop-color="#0d0d14"/> 276 <stop offset="100%" stop-color="#0a0a0f"/> 277 </linearGradient> 278 <linearGradient id="logoCyan" x1="0%" y1="0%" x2="100%" y2="100%"> 279 <stop offset="0%" stop-color="#00f5d4"/> 280 <stop offset="100%" stop-color="#00d4aa"/> 281 </linearGradient> 282 <filter id="logoGlow" x="-50%" y="-50%" width="200%" height="200%"> 283 <feGaussianBlur stdDeviation="2" result="blur"/> 284 <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge> 285 </filter> 286 </defs> 287 <path d="M50 5 L90 20 L90 45 C90 70 70 90 50 95 C30 90 10 70 10 45 L10 20 Z" fill="url(#logoShieldBg)" stroke="url(#logoCyan)" stroke-width="2.5" filter="url(#logoGlow)"/> 288 <path d="M50 15 L80 27 L80 45 C80 65 65 80 50 85 C35 80 20 65 20 45 L20 27 Z" fill="none" stroke="#00f5d4" stroke-width="0.8" opacity="0.4"/> 289 <g transform="translate(50, 50) rotate(-30)" filter="url(#logoGlow)"> 290 <ellipse cx="-8" cy="0" rx="12" ry="8" fill="none" stroke="#00f5d4" stroke-width="4"/> 291 <ellipse cx="8" cy="0" rx="12" ry="8" fill="none" stroke="#00f5d4" stroke-width="4"/> 292 </g> 293 </svg> 294 </div> 295 <span itemprop="name">LinkGuard</span> 296 </a> 297 <nav role="navigation" aria-label="Primary navigation"> 298 <a href="#benefits">Benefits</a> 299 <a href="#how-it-works">How It Works</a> 300 <a href="#features">Features</a> 301 <a href="#pricing">Pricing</a> 302 <a href="#faq">FAQ</a> 303 </nav> 304 <!-- Guest Actions (shown when not logged in) --> 305 <div class="header-actions" id="header-actions"> 306 <!-- Sign Up - always visible to guests (new visitors and returning) --> 307 <a href="/register" class="btn btn-primary header-cta" id="guest-cta" aria-label="Start free with LinkGuard">Start Free</a> 308 <!-- Login - always visible to guests --> 309 <a href="/login" class="header-login" id="login-btn" aria-label="Log in to your account"> 310 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 311 <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/> 312 <polyline points="10 17 15 12 10 7"/> 313 <line x1="15" y1="12" x2="3" y2="12"/> 314 </svg>
315 <span class="login-text">Log In</span> 316 </a> 317 </div> 318 319 <!-- User Menu (shown when logged in) --> 320 <div class="user-menu" id="user-menu" style="display: none;"> 321 <button class="user-menu-trigger" id="user-menu-trigger" aria-expanded="false" aria-haspopup="true"> 322 <div class="user-avatar" id="user-avatar"> 323 <span class="user-avatar-letter" id="user-avatar-letter">U</span> 324 </div> 325 <span class="user-name" id="user-name">User</span> 326 <svg class="user-menu-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 327 <polyline points="6 9 12 15 18 9"/> 328 </svg> 329 </button> 330 <div class="user-dropdown" id="user-dropdown" role="menu"> 331 <div class="user-dropdown-header"> 332 <span class="user-dropdown-email" id="user-dropdown-email">[email protected]</span> 333 <span class="user-dropdown-status"> 334 <span class="status-dot"></span> 335 Active 336 </span> 337 </div> 338 <div class="user-dropdown-divider"></div> 339 <a href="/dashboard" class="user-dropdown-item" role="menuitem"> 340 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 341 <rect x="3" y="3" width="7" height="7"/> 342 <rect x="14" y="3" width="7" height="7"/> 343 <rect x="14" y="14" width="7" height="7"/> 344 <rect x="3" y="14" width="7" height="7"/> 345 </svg> 346 Dashboard 347 </a> 348 <a href="/dashboard/projects" class="user-dropdown-item" role="menuitem"> 349 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 350 <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/> 351 </svg> 352 Projects 353 </a> 354 <div class="user-dropdown-divider"></div> 355 <a href="/dashboard/settings" class="user-dropdown-item disabled" role="menuitem"> 356 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 357 <circle cx="12" cy="12" r="3"/> 358 <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> 359 </svg> 360 Settings 361 <span class="coming-soon-badge">Soon</span> 362 </a> 363 <a href="/dashboard/billing" class="user-dropdown-item disabled" role="menuitem"> 364 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 365 <rect x="1" y="4" width="22" height="16" rx="2" ry="2"/> 366 <line x1="1" y1="10" x2="23" y2="10"/> 367 </svg> 368 Billing
369 <span class="coming-soon-badge">Soon</span> 370 </a> 371 <div class="user-dropdown-divider"></div> 372 <button class="user-dropdown-item user-dropdown-logout" id="logout-btn" role="menuitem"> 373 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 374 <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/> 375 <polyline points="16 17 21 12 16 7"/> 376 <line x1="21" y1="12" x2="9" y2="12"/> 377 </svg> 378 Logout 379 </button> 380 </div> 381 </div> 382 383 <button class="mobile-menu-btn" aria-label="Open mobile menu" aria-expanded="false" aria-controls="mobile-nav"> 384 <i data-lucide="menu" style="width: 24px; height: 24px;" aria-hidden="true"></i> 385 </button> 386 </div> 387 </div> 388 </header> 389 390 <!-- Mobile Navigation Overlay --> 391 <div class="mobile-nav-overlay" id="mobile-nav-overlay" aria-hidden="true"></div> 392 393 <!-- Mobile Navigation Menu --> 394 <nav class="mobile-nav" id="mobile-nav" role="navigation" aria-label="Mobile navigation"> 395 <button class="mobile-menu-close" id="mobile-menu-close" aria-label="Close mobile menu"> 396 <i data-lucide="x" style="width: 24px; height: 24px;"></i> 397 </button> 398 <div class="mobile-nav-links"> 399 <a href="#benefits">Benefits</a> 400 <a href="#how-it-works">How It Works</a> 401 <a href="#features">Features</a> 402 <a href="#pricing">Pricing</a> 403 <a href="#faq">FAQ</a> 404 </div> 405 <div class="mobile-nav-ctas"> 406 <a href="/login" class="btn btn-login">Log In</a> 407 <a href="/register" class="btn btn-primary">Start Free</a> 408 </div> 409 </nav> 410 411 <main id="main-content" role="main"> 412 413 <!-- ============ HERO SECTION ============ --> 414 <section class="hero" aria-labelledby="hero-heading"> 415 <div class="container"> 416 <div class="hero-grid"> 417 <div class="hero-content"> 418 <div class="hero-badge" role="status" aria-live="polite"> 419 <i data-lucide="alert-triangle" style="width: 14px; height: 14px;" aria-hidden="true"></i> 420 7% of backlinks disappear every year 421 </div> 422 <h1 id="hero-heading">Protect every dollar you <span>invested in backlinks</span></h1> 423 <p class="hero-subtitle">Automated monitoring with instant alerts when your $300-1000 links get removed, changed to nofollow, or modified. Never lose a backlink unnoticed again.</p> 424 <div class="hero-free-pill" aria-label="Signup bonus"> 425 <i data-lucide="gift" style="width: 14px; height: 14px;" aria-hidden="true"></i> 426 <span>Start free â 1,000 tokens on signup, no card needed</span> 427 </div> 428 429 <div class="hero-ctas"> 430 <a href="/register" class="btn btn-primary"> 431 <i data-lucide="rocket" style="width: 18px; height: 18px;"></i> 432 Start Free 433 </a> 434 <button type="button" class="btn btn-secondary" id="watchDemoBtn" aria-label="Watch LinkGuard demo video" title="Watch the LinkGuard product demo"> 435 <i data-lucide="play-circle" style="width: 18px; height: 18px;"></i> 436 Watch Demo 437 </button> 438 </div> 439 <div class="hero-proof"> 440 <div class="hero-stat"> 441 <div class="hero-stat-value">$15K</div> 442 <div class="hero-stat-label">Founder lost before building this</div> 443 </div> 444 <div class="hero-divider"></div> 445 <div class="hero-stat"> 446 <div class="hero-stat-value">$0</div> 447 <div class="hero-stat-label">Monthly subscription fee</div> 448 </div> 449 <div class="hero-divider"></div> 450 <div class="hero-stat"> 451 <div class="hero-stat-value">Early</div> 452 <div class="hero-stat-label">Access â be customer #1</div> 453 </div> 454 </div> 455 </div> 456 <div class="hero-visual"> 457 <div class="hero-mockup"> 458 <div class="mockup-header">
459 <span class="mockup-dot red"></span> 460 <span class="mockup-dot yellow"></span> 461 <span class="mockup-dot green"></span> 462 </div> 463 <div class="mockup-content"> 464 <div class="mockup-row"> 465 <div class="mockup-link"> 466 <div class="mockup-link-icon"> 467 <i data-lucide="link" style="width: 16px; height: 16px;"></i> 468 </div> 469 <span class="mockup-link-text">forbes.com/best-seo-tools</span> 470 </div> 471 <div class="mockup-status active"> 472 <i data-lucide="check-circle" style="width: 12px; height: 12px;"></i> 473 Active 474 </div> 475 </div> 476 <div class="mockup-row"> 477 <div class="mockup-link"> 478 <div class="mockup-link-icon"> 479 <i data-lucide="link" style="width: 16px; height: 16px;"></i> 480 </div> 481 <span class="mockup-link-text">techcrunch.com/review</span> 482 </div> 483 <div class="mockup-status warning"> 484 <i data-lucide="alert-circle" style="width: 12px; height: 12px;"></i> 485 Nofollow 486 </div> 487 </div> 488 <div class="mockup-row"> 489 <div class="mockup-link"> 490 <div class="mockup-link-icon"> 491 <i data-lucide="link" style="width: 16px; height: 16px;"></i> 492 </div> 493 <span class="mockup-link-text">entrepreneur.com/tools</span> 494 </div> 495 <div class="mockup-status active"> 496 <i data-lucide="check-circle" style="width: 12px; height: 12px;"></i> 497 Active 498 </div> 499 </div> 500 <div class="mockup-row"> 501 <div class="mockup-link"> 502 <div class="mockup-link-icon"> 503 <i data-lucide="link" style="width: 16px; height: 16px;"></i> 504 </div> 505 <span class="mockup-link-text">inc.com/marketing</span> 506 </div> 507 <div class="mockup-status error"> 508 <i data-lucide="x-circle" style="width: 12px; height: 12px;"></i> 509 Removed 510 </div> 511 </div> 512 </div> 513 </div> 514 <div class="alert-popup"> 515 <div class="alert-popup-icon"> 516 <i data-lucide="bell" style="width: 18px; height: 18px;"></i> 517 </div> 518 <div class="alert-popup-text"> 519 <div class="alert-popup-title">Link Alert!</div> 520 <div class="alert-popup-desc">inc.com link was removed</div> 521 </div> 522 </div> 523 </div> 524 </div> 525 </div> 526 </section> 527 528 <!-- ============ PROBLEM SECTION ============ --> 529 <section class="problem"> 530 <div class="container"> 531 <div class="problem-header"> 532 <h2>You spent $50,000 on backlinks. <span>Are you tracking them?</span></h2> 533 <p>Most SEO teams discover lost backlinks months later â after the damage is done. Here's what's actually happening:</p> 534 </div> 535 <div class="problem-grid"> 536 <div class="pain-points"> 537 <div class="pain-point"> 538 <div class="pain-icon"> 539 <i data-lucide="clock" style="width: 20p
539x; height: 20px;"></i> 540 </div> 541 <div class="pain-text"> 542 <h4>10-15 hours/month on manual checks</h4> 543 <p>Opening every page by hand to confirm each link is still live burns 10-15 hours a month. That's time your team owes to building links, not checking them.</p> 544 </div> 545 </div> 546 <div class="pain-point"> 547 <div class="pain-icon"> 548 <i data-lucide="eye-off" style="width: 20px; height: 20px;"></i> 549 </div> 550 <div class="pain-text"> 551 <h4>Sneaky nofollow switches</h4> 552 <p>Dofollow today, nofollow tomorrow. The seller never says a word.</p> 553 </div> 554 </div> 555 <div class="pain-point"> 556 <div class="pain-icon"> 557 <i data-lucide="trash-2" style="width: 20px; height: 20px;"></i> 558 </div> 559 <div class="pain-text"> 560 <h4>Links removed without notice</h4> 561 <p>Your $500 placement disappears, you notice weeks later, and by then the seller has gone quiet for good.</p> 562 </div> 563 </div> 564 <div class="pain-point"> 565 <div class="pain-icon"> 566 <i data-lucide="users" style="width: 20px; height: 20px;"></i> 567 </div> 568 <div class="pain-text"> 569 <h4>No seller accountability</h4> 570 <p>Who pulled what, and when? No history means no proof, and nothing to hold the seller to.</p> 571 </div> 572 </div> 573 </div> 574 <div class="problem-story"> 575 <div class="story-header"> 576 <div class="story-avatar">AA</div> 577 <div class="story-meta"> 578 <h4>Andrii A., LinkGuard Founder</h4> 579 <span>Lost ~$15,000 before building this tool</span> 580 </div> 581 </div> 582 <div class="story-content"> 583 <p>"I was buying 20-40 links per month for fintech clients. Rankings were okay, reports looked fine â we had no reason to check manually."</p> 584 <p>"Then I audited the portfolio properly. About $15,000 worth of links had quietly disappeared â removed, nofollowed, or redirected. Some had been gone for over a year."</p> 585 <div class="story-highlight"> 586 <strong>"The sellers who were reachable mostly fixed the issues when shown proof. The ones we couldn't contact in time? Those links were gone forever. So I built LinkGuard."</strong> 587 </div> 588 </div> 589 </div> 590 </div> 591 </div> 592 </section> 593 594 <!-- ============ BENEFITS SECTION ============ --> 595 <section class="benefits" id="benefits"> 596 <div class="container"> 597 <div class="benefits-header"> 598 <span class="section-badge"> 599 <i data-lucide="sparkles" style="width: 14px; height: 14px;"></i> 600 Benefits 601 </span> 602 <h2>Stop losing money. Start protecting it.</h2> 603 <p>LinkGuard turns your chaotic link portfolio into a managed, protected asset.</p> 604 </div> 605 <div class="benefits-grid"> 606 <div class="benefit-card"> 607 <div class="benefit-icon"> 608 <i data-lucide="zap" style="width: 28px; height: 28px;"></i> 609 </div> 610 <h3>Save 15+ hours monthly</h3> 611 <p>Monitoring runs in the background, so no one on your team opens pages by hand anymore.</p> 612 <div class="benefit-stat"> 613 <i data-lucide="trending-up" style="width: 14px; height: 14px;"></i> 614 Zero manual checks 615 </div> 616 </div> 617 <div class="benefit-card"> 618 <div class="benefit-icon"> 619 <i data-lucide="shield" style="width: 28px; height: 28px;"></i> 620 </div> 621 <h3>Catch issues in minutes</h3> 622 <p>The instant a link is removed or flipped to nofollow, an Email or Slack alert lands in your inbox, so you can reach the seller while they still remember placing it.</p> 623 <div class="benefit-stat"> 624 <i data-lucide="clock" style="width: 14px; height: 14px;"></i> 625 < 5 min alert time 626 </div> 627 </div> 628 <div class="benefit-card"> 629 <div class="benefit-icon"> 630 <i data-lucide="dollar-sign" style="width: 28px; height: 28px;"></i> 631 </div> 632 <h3>Recover lost value</h3> 633 <p>Move fast while the trail's still warm. That's usually the line between a fix and a write-off.</p> 634 <div class="benefit-stat"> 635 <i data-lucide="check-circle" style="width: 14px; height: 14px;"></i> 636 Act in hours, not weeks 637 </div> 638 </div> 639 </div> 640 </div> 641 </section> 642 643 <!-- ============ FOUNDER STORY SECTION ============ --> 644 <section class="social-proof"> 645 <div class="container"> 646 <div class="social-proof-header"> 647 <h2>Built from a <span class="proof-heading-accent">$15,000 loss</span></h2> 648 <p class="social-proof-lead"> 649 I spent years building backlinks for fintech clients in Ukraine. One day I audited our portfolio and discovered that roughly $15,000 worth of links had quietly vanished â removed, nofollowed, or redirected with zero notification. We had been paying for links that no longer existed. 650 </p> 651 </div> 652 653 <!-- Founder story cards --> 654 <div class="stats-row"> 655 <div class="stat-card"> 656 <div class="stat-value stat-value--danger">$15K</div> 657 <div class="stat-label">Lost before monitoring</div> 658 </div> 659 <div class="stat-card"> 660 <div class="stat-value">1</div> 661 <div class="stat-label">
661Solo founder, Ukraine</div> 662 </div> 663 <div class="stat-card"> 664 <div class="stat-value stat-value--cyan">0</div> 665 <div class="stat-label">Monthly subscriptions</div> 666 </div> 667 <div class="stat-card"> 668 <div class="stat-value stat-value--cyan">#1</div> 669 <div class="stat-label">Be our first customer</div> 670 </div> 671 </div> 672 673 <!-- Honest early-access positioning --> 674 <div class="early-access-box"> 675 <div class="early-access-tag">// EARLY_ACCESS</div> 676 <h3 class="early-access-heading">No fake reviews. No inflated numbers.</h3> 677 <p class="early-access-body"> 678 LinkGuard is new. We don't have a hundred customers yet â and we won't pretend otherwise. 679 What we have is a tool that works, a founder who personally lost real money to this exact problem, 680 and the motivation to make it the best backlink monitor available. 681 <strong class="early-access-strong">Be one of the first real customers shaping this product.</strong> 682 </p> 683 <a href="/register" class="btn btn-primary"> 684 <i data-lucide="rocket" style="width: 16px; height: 16px;"></i> 685 Get 1,000 Free Tokens â Start Now 686 </a> 687 </div> 688 </div> 689 </section> 690 691 <!-- ============ HOW IT WORKS SECTION ============ --> 692 <section class="how-it-works" id="how-it-works"> 693 <div class="container"> 694 <div class="how-header"> 695 <span class="section-badge"> 696 <i data-lucide="settings" style="width: 14px; height: 14px;"></i> 697 How It Works 698 </span> 699 <h2>Start protecting links in 3 steps</h2> 700 <p>No API keys, no complex setup. Import your links and monitoring begins immediately.</p> 701 </div> 702 <div class="steps-container"> 703 <!-- Step 1 --> 704 <div class="step"> 705 <div class="step-content"> 706 <div class="step-number">01</div> 707 <div class="step-text"> 708 <h3>Import your links</h3> 709 <p>Drop in a CSV, paste straight from a spreadsheet, or type them in by hand. Any format works; the only thing that matters is getting your links in.</p> 710 <div class="step-features"> 711 <div class="step-feature"> 712 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 713 CSV, Excel, Google Sheets 714 </div> 715 <div class="step-feature"> 716 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 717 Copy-paste support 718 </div> 719 <div class="step-feature"> 720 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 721 Bulk import (up to 1,000 rows) 722 </div> 723 </div> 724 </div> 725 </div> 726 <div class="step-visual"> 727 <div class="step-visual-header"> 728 <span class="step-visual-title">Import Links</span> 729 <span class="step-visual-badge">Step 1</span> 730 </div> 731 <div style="display: flex; flex-direction: column; gap: 12px;"> 732 <div style="padding: 16px; background: rgba(255,255,255,0.02); border: 2px dashed rgba(0,245,212,0.3); text-align: center;"> 733 <i data-lucide="upload" style="width: 32px; height: 32px; color: var(--neon-cyan); margin-bottom: 8px;"></i> 734 <p style="font-size: 14px; color: var(--text-secondary);">Drop CSV here or click to upload</p> 735 </div> 736 <div style="display: flex; gap: 8px;"> 737 <div style="flex: 1; padding: 12px; background: rgba(255,255,255,0.02); text-align: center; font-size: 12px; color: var(--text-secondary);"> 738 <i data-lucide="file-spreadsheet" style="width: 20p
738x; height: 20px; margin-bottom: 4px; color: var(--neon-cyan);"></i> 739 <br>Excel 740 </div> 741 <div style="flex: 1; padding: 12px; background: rgba(255,255,255,0.02); text-align: center; font-size: 12px; color: var(--text-secondary);"> 742 <i data-lucide="table" style="width: 20px; height: 20px; margin-bottom: 4px; color: var(--neon-cyan);"></i> 743 <br>Sheets 744 </div> 745 <div style="flex: 1; padding: 12px; background: rgba(255,255,255,0.02); text-align: center; font-size: 12px; color: var(--text-secondary);"> 746 <i data-lucide="code" style="width: 20px; height: 20px; margin-bottom: 4px; color: var(--neon-cyan);"></i> 747 <br>API 748 </div> 749 </div> 750 </div> 751 </div> 752 </div> 753 754 <!-- Step 2 --> 755 <div class="step"> 756 <div class="step-content"> 757 <div class="step-number">
75702</div> 758 <div class="step-text"> 759 <h3>Set monitoring rules</h3> 760 <p>Now decide how closely each link gets watched: daily for the expensive placements you can't afford to lose, weekly for the stable ones. You set the pace, so you control the token spend.</p> 761 <div class="step-features"> 762 <div class="step-feature"> 763 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 764 SERP indexation checks 765 </div> 766 <div class="step-feature"> 767 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 768 HTML status verification 769 </div> 770 <div class="step-feature"> 771 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 772 Dofollow/nofollow tracking 773 </div> 774 </div> 775 </div> 776 </div> 777 <div class="step-visual"> 778 <div class="step-visual-header"> 779 <span class="step-visual-title">Monitoring Presets</span> 780 <span class="step-visual-badge">Step 2</span> 781 </div> 782 <div style="display: flex; flex-direction: column; gap: 10px;"> 783 <div style="padding: 14px 16px; background: rgba(247, 37, 133, 0.1); border: 1px solid rgba(247, 37, 133, 0.3); display: flex; justify-content: space-between; align-items: center;"> 784 <div> 785 <div style="font-size: 14px; font-weight: 600; color: var(--neon-magenta);">Paranoid Mode</div> 786 <div style="font-size: 12px; color: var(--text-muted);">For $500+ links</div> 787 </div> 788 <div style="font-size: 13px; color: var(--text-secondary);">6x/day</div> 789 </div> 790 <div style="padding: 14px 16px; background: rgba(0, 245, 212, 0.1); border: 2px solid var(--neon-cyan); display: flex; justify-content: space-between; align-items: center;"> 791 <div> 792 <div style="font-size: 14px; font-weight: 600; color: var(--neon-cyan);">Balanced</div> 793 <div style="font-size: 12px; color: var(--text-muted);">Standard monitoring</div> 794 </div> 795 <div style="font-size: 13px; color: var(--text-secondary);">Daily</div> 796 </div> 797 <div style="padding: 14px 16px; background: rgba(255, 255, 255, 0.02); border: 1px solid rgba(255, 255, 255, 0.1); display: flex; justify-content: space-between; align-items: center;"> 798 <div> 799 <div style="font-size: 14px; font-weight: 600; color: var(--text-secondary);">Economy</div> 800 <div style="font-size: 12px; color: var(--text-muted);">For stable links</div> 801 </div> 802 <div style="font-size: 13px; color: var(--text-secondary);">Weekly</div> 803 </div> 804 </div> 805 </div> 806 </div> 807 808 <!-- Step 3 --> 809 <div class="step"> 810 <div class="step-content"> 811 <div class="step-number">03</div> 812 <div class="step-text"> 813 <h3>Get instant alerts & act fast</h3> 814 <p>After that, it runs itself. The moment a link drops or changes, an Email or Slack alert shows you exactly what happened, and hands you a ready-to-send template to chase the seller.</p> 815 <div class="step-features"> 816 <div class="step-feature"> 817 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 818 Email + Slack notifications 819 </div> 820 <div class="step-feature"> 821 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 822 Auto-generated seller emails 823 </div> 824 <div class="step-feature"> 825 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 826 Change history & audit log 827 </div> 828 </div> 829 </div> 830 </div> 831 <div class="step-visual"> 832 <div class="step-visual-header">
833 <span class="step-visual-title">Alert Center</span> 834 <span class="step-visual-badge">Step 3</span> 835 </div> 836 <div style="display: flex; flex-direction: column; gap: 10px;"> 837 <div style="padding: 14px 16px; background: rgba(247, 37, 133, 0.1); border-left: 3px solid var(--neon-magenta);"> 838 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;"> 839 <span style="font-size: 13px; font-weight: 600; color: var(--neon-magenta);">Link Removed</span> 840 <span style="font-size: 11px; color: var(--text-muted);">2 min ago</span> 841 </div> 842 <p style="font-size: 13px; color: var(--text-secondary);">inc.com/marketing removed your link</p> 843 </div> 844 <div style="padding: 14px 16px; background: rgba(254, 228, 64, 0.1); border-left: 3px solid var(--neon-yellow);"> 845 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;"> 846 <span style="font-size: 13px; font-weight: 600; color: var(--neon-yellow);">Changed to Nofollow</span> 847 <span style="font-size: 11px; color: var(--text-muted);">1 hour ago</span> 848 </div> 849 <p style="font-size: 13px; color: var(--text-secondary);">techcrunch.com/review changed attribute</p> 850 </div> 851 <div style="padding: 12px 16px; background: var(--neon-cyan); text-align: center; color: var(--bg-deep); font-size: 13px; font-weight: 600; cursor: pointer;"> 852 Contact Seller â 853 </div> 854 </div> 855 </div> 856 </div> 857 </div> 858 </div> 859 </section> 860 861 <!-- ============ FEATURES SECTION ============ --> 862 <section class="features" id="features"> 863 <div class="container"> 864 <div class="features-header"> 865 <span class="section-badge"> 866 <i data-lucide="box" style="width: 14px; height: 14px;"></i> 867 Features 868 </span> 869 <h2>Everything you need in one place</h2> 870 <p>Purpose-built for link building professionals. No bloat, no unnecessary features.</p> 871 </div> 872 <div class="features-grid"> 873 <div class="feature-card"> 874 <div class="feature-card-icon"> 875 <i data-lucide="search" style="width: 22px; height: 22px;"></i> 876 </div> 877 <h3>SERP indexation check</h3> 878 <p>Confirm Google still has your links indexed, and catch deindexed pages before they drag your rankings down.</p> 879 </div> 880 <div class="feature-card"> 881 <div class="feature-card-icon"> 882 <i data-lucide="code" style="width: 22px; height: 22px;"></i> 883 </div> 884 <h3>HTML status verification</h3> 885 <p>A deep crawl confirms the link is there, reads its anchor text, and flags any dofollow-to-nofollow switch, surrounding context and all.</p> 886 </div> 887 <div class="feature-card"> 888 <div class="feature-card-icon"> 889 <i data-lucide="bell" style="width: 22px; height: 22px;"></i> 890 </div> 891 <h3>Instant alerts</h3> 892 <p>Email or Slack, minutes after anything changes. You're never the last to know.</p> 893 </div> 894 <div class="feature-card"> 895 <div class="feature-card-icon"> 896 <i data-lucide="users" style="width: 22px; height: 22px;"></i> 897 </div> 898 <h3>Seller reliability ledger</h3> 899 <p>Every seller's track record: links bought, links still live, links lost, refunds received. A reliability tier computed from what actually happened.</p> 900 </div> 901 <div class="feature-card"> 902 <div class="feature-card-icon"> 903 <i data-lucide="calendar" style="width: 22px; height: 22px;"></i> 904 </div> 905 <h3>Contract reminders</h3> 906 <p>A heads-up 14 days and 3 days before each placement expires, so you can renew on time or line up a replacement.</p> 907 </div> 908 <div class="feature-card"> 909 <div class="feature-card-icon"> 910 <i data-lucide="file-text" style="width: 22px; height: 22px;"></i> 911 </div> 912 <h3>White-label reports</h3> 913 <p>Client-ready PDFs in your logo and colors â with no LinkGuard marks anyw
913here on them.</p> 914 </div> 915 <div class="feature-card"> 916 <div class="feature-card-icon"> 917 <i data-lucide="history" style="width: 22px; height: 22px;"></i> 918 </div> 919 <h3>Domain trust history</h3> 920 <p>See how often a domain quietly drops links, and steer clear of the risky ones before you pay.</p> 921 </div> 922 <div class="feature-card"> 923 <div class="feature-card-icon"> 924 <i data-lucide="mail" style="width: 22px; height: 22px;"></i> 925 </div> 926 <h3>Auto email drafts</h3> 927 <p>When a link breaks, one click writes the recovery email â from what changed, when, and the terms you agreed with the seller.</p> 928 </div> 929 <div class="feature-card"> 930 <div class="feature-card-icon"> 931 <i data-lucide="plug" style="width: 22px; height: 22px;"></i> 932 </div> 933 <h3>Search Console connect</h3> 934 <p>Link your own GSC to check whether Google still indexes the pages your backlinks point to â then turn your real search data into ranked, AI-written next steps.</p> 935 </div> 936 </div> 937 </div> 938 </section> 939 940 <!-- ============ GSC SPOTLIGHT SECTION ============ --> 941 <section class="gsc-spotlight" id="search-console" aria-labelledby="gsc-spotlight-heading"> 942 <div class="container"> 943 <div class="gsc-spotlight-grid"> 944 <div class="gsc-spotlight-text"> 945 <span class="section-badge"> 946 <i data-lucide="plug" style="width: 14px; height: 14px;"></i> 947 Google Search Console 948 </span> 949 <h2 id="gsc-spotlight-heading">Connect your Search Console. See what Google actually sees.</h2> 950 <p class="gsc-spotlight-lead">Your backlinks point to your pages. Good â but is the page each one points to still in Google's index? If a target page drops out, every link you aimed at it is pushing on a page that can't rank. A monitor watching only the donor side won't catch it. So LinkGuard checks the other end, through your own Search Console.</p> 951 952 <ul class="gsc-spotlight-points"> 953 <li> 954 <i data-lucide="search-check" style="width: 20px; height: 20px;"></i> 955 <div> 956 <h4>Indexation cross-check</h4> 957 <p>For every page of yours a link points to, LinkGuard checks â via your own GSC â whether Google still has it indexed. A backlink aimed at a dropped page is money wasted. Now you'll see it.</p> 958 </div> 959 </li> 960 <li> 961 <i data-lucide="bar-chart-3" style="width: 20px; height: 20px;"></i> 962 <div> 963 <h4>Your real numbers, next to your links</h4> 964 <p>Clicks, impressions, average position, top queries â pulled straight from Search Console, not a separate Google tab.</p> 965 </div> 966 </li> 967 <li> 968 <i data-lucide="sparkles" style="width: 20px; height: 20px;"></i> 969 <div> 970 <h4>AI actions from your data â not generic advice</h4> 971 <p>The AI reads your actual findings â striking-distance keywords, CTR gaps, pages with impressions but no coverage â and writes a short, ranked to-do list that cites your own impression counts.</p> 972 </div> 973 </li> 974 </ul> 975 976 <p class="gsc-spotlight-honest"> 977 <i data-lucide="lock" style="width: 16px; height: 16px;"></i>
978 <span>Read-only access, and it's <em>your</em> data â Search Console has no competitor-backlink numbers, so this won't replace a crawl index like Ahrefs. It does the one thing they can't: check the pages your links point to against Google's own index. Performance and indexation come with monitoring; the AI insights are pay-as-you-go, priced at what they cost us to run.</span> 979 </p> 980 981 <div class="gsc-spotlight-cta"> 982 <a href="/register" class="btn btn-primary" aria-label="Connect your Google Search Console with LinkGuard"> 983 <i data-lucide="plug" style="width: 18px; height: 18px;"></i> 984 Connect your Search Console 985 </a> 986 <a href="/features/gsc" class="btn btn-secondary">See how it works →</a> 987 </div> 988 </div> 989 990 <div class="gsc-spotlight-visual" aria-hidden="true"> 991 <div class="gsc-mock"> 992 <div class="gsc-mock-header"> 993 <span class="gsc-mock-title">Search Console · yoursite.com</span> 994 <span class="gsc-mock-badge">Connected</span> 995 </div> 996 <div class="gsc-mock-kpis"> 997 <div class="gsc-mock-kpi"> 998 <span class="gsc-mock-kpi-label">Clicks</span> 999 <span class="gsc-mock-kpi-value">1,204</span> 1000 </div> 1001 <div class="gsc-mock-kpi"> 1002 <span class="gsc-mock-kpi-label">Impressions</span> 1003 <span class="gsc-mock-kpi-value">38,910</span> 1004 </div> 1005 <div class="gsc-mock-kpi"> 1006 <span class="gsc-mock-kpi-label">Avg position</span> 1007 <span class="gsc-mock-kpi-value">14.2</span> 1008 </div> 1009 </div> 1010 <div class="gsc-mock-index"> 1011 <i data-lucide="search-check" style="width: 16px; height: 16px;"></i> 1012 <span><strong>18 of 20</strong> linked pages indexed · <span class="gsc-mock-warn">2 dropped</span></span> 1013 </div> 1014 <div class="gsc-mock-insight gsc-mock-insight--p1"> 1015 <span class="gsc-mock-tag">P1 · Coverage gap</span> 1016 <p>A page with 672 impressions isn't indexed. Resubmit it and add an internal link.</p> 1017 </div> 1018 <div class="gsc-mock-insight gsc-mock-insight--p2"> 1019 <span class="gsc-mock-tag">P2 · Striking distance</span> 1020 <p>Three queries sit at position 11–14. Small on-page edits could move them to page one.</p> 1021 </div> 1022 </div> 1023 </div> 1024 </div> 1025 </div> 1026 </section> 1027 1028 <!-- ============ PRICING SECTION ============ --> 1029 <section class="pricing" id="pricing"> 1030 <div class="container"> 1031 <div class="pricing-header"> 1032 <span class="section-badge"> 1033 <i data-lucide="credit-card" style="width: 14px; height: 14px;"></i> 1034 Pricing 1035 </span> 1036 <h2>Pay only for what you use</h2> 1037 <p>No monthly subscriptions. Buy tokens once, use them anytime. Top up when you need more.</p> 1038 <div class="pricing-note"> 1039 <i data-lucide="infinity" style="width: 16px; height: 16px;"></i> 1040 Tokens never expire 1041 </div> 1042 </div> 1043 1044 <!-- Free entry-point card â standalone block above the 4-column paid grid --> 1045 <!-- Violation-1 fix: Free card removed from .pricing-grid to preserve canonical repeat(4,1fr) layout --> 1046 <div class="pricing-free-hero"> 1047 <div class="pricing-card pricing-card--free"> 1048 <div class="pricing-card-header"> 1049 <div class="pricing-card-name">Free</div> 1050 <div class="pricing-card-price">
1051 <span class="currency">$</span> 1052 <span class="amount">0</span> 1053 <span class="period">forever</span> 1054 </div> 1055 <div class="pricing-card-tokens pricing-card-tokens--free"> 1056 <i data-lucide="gift" style="width: 16px; height: 16px;"></i> 1057 1,000 tokens on signup 1058 <span class="bonus-free">SIGNUP_BONUS</span> 1059 </div> 1060 <div class="pricing-card-tax">≈ 83 full checks</div> 1061 </div> 1062 <ul class="pricing-card-features"> 1063 <li> 1064 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1065 Full access to every feature 1066 </li> 1067 <li> 1068 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1069 Tokens never expire 1070 </li> 1071 <li> 1072 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1073 No credit card required 1074 </li> 1075 <li> 1076 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1077 Upgrade whenever you're ready 1078 </li> 1079 </ul> 1080 <a href="/register" class="btn btn-free">Start Free</a> 1081 </div> 1082 </div> 1083 1084 <div class="pricing-grid"> 1085 <!-- Full check = HTML check (5 tokens) + SERP check (7 tokens) = 12 tokens, per app/core/config.py 1086 (token_cost_html_check + token_cost_serp_check). Update every card below if those costs change. --> 1087 <!-- Lite --> 1088 <div class="pricing-card"> 1089 <div class="pricing-card-header"> 1090 <div class="pricing-card-name">Lite</div> 1091 <div class="pricing-card-price"> 1092 <span class="currency">$</span> 1093 <span class="amount">25</span> 1094 <span class="period">one-time</span> 1095 </div> 1096 <div class="pricing-card-tokens"> 1097 <i data-lucide="coins" style="width: 16px; height: 16px;"></i> 1098 25,000 tokens 1099 </div> 1100 <div class="pricing-card-tax">+ VAT where applicable</div> 1101 </div> 1102 <ul class="pricing-card-features"> 1103 <li> 1104 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1105 ~2,000 full link checks 1106 </li> 1107 <li> 1108 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1109 All monitoring features 1110 </li> 1111 <li> 1112 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1113 Email & Slack alerts 1114 </li> 1115 <li> 1116 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1117 Seller ledger, DR & domain trust history 1118 </li> 1119 </ul> 1120 <a href="/register" class="btn btn-secondary">Get Started</a> 1121 </div> 1122 1123 <!-- Standard â Most Popular --> 1124 <div class="pricing-card popular"> 1125 <div class="pricing-card-header"> 1126 <div class="pricing-card-name">Standard</div> 1127 <div class="pricing-card-price"> 1128 <span class="currency">$</span>
1129 <span class="amount">50</span> 1130 <span class="period">one-time</span> 1131 </div> 1132 <div class="pricing-card-tokens"> 1133 <i data-lucide="coins" style="width: 16px; height: 16px;"></i> 1134 55,000 tokens 1135 <span class="bonus">+10% value</span> 1136 </div> 1137 <div class="pricing-card-tax">+ VAT where applicable</div> 1138 </div> 1139 <ul class="pricing-card-features"> 1140 <li> 1141 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1142 ~4,500 full link checks 1143 </li> 1144 <li> 1145 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1146 All monitoring features 1147 </li> 1148 <li> 1149 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1150 Email & Slack alerts 1151 </li> 1152 <li> 1153 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1154 Seller ledger, DR & domain trust history 1155 </li> 1156 </ul> 1157 <a href="/register" class="btn btn-primary">Get Started</a> 1158 </div> 1159 1160 <!-- Pro --> 1161 <div class="pricing-card"> 1162 <div class="pricing-card-header"> 1163 <div class="pricing-card-name">Pro</div> 1164 <div class="pricing-card-price"> 1165 <span class="currency">$</span> 1166 <span class="amount">100</span> 1167 <span class="period">one-time</span> 1168 </div> 1169 <div class="pricing-card-tokens"> 1170 <i data-lucide="coins" style="width: 16px; height: 16px;"></i> 1171 115,000 tokens 1172 <span class="bonus">+15% value</span> 1173 </div> 1174 <div class="pricing-card-tax">+ VAT where applicable</div> 1175 </div> 1176 <ul class="pricing-card-features"> 1177 <li> 1178 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1179 ~9,500 full link checks 1180 </li> 1181 <li> 1182 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1183 All monitoring features 1184 </li> 1185 <li> 1186 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1187 Email & Slack alerts 1188 </li> 1189 <li> 1190 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1191 Seller ledger, DR & domain trust history 1192 </li> 1193 </ul> 1194 <a href="/register" class="btn btn-secondary">Get Started</a> 1195 </div> 1196 1197 <!-- Agency --> 1198 <div class="pricing-card"> 1199 <div class="pricing-card-header"> 1200 <div class="pricing-card-name">Agency</div> 1201 <div class="pricing-card-price"> 1202 <span class="currency">$</span> 1203 <span class="amount">500</span> 1204 <span class="period">one-time</span> 1205 </div> 1206 <div class="pricing-card-tokens"> 1207 <i data-lucide="coins" style="width: 16px; height: 16px;"></i> 1208 625,000 tokens
1209 <span class="bonus">+25% value</span> 1210 </div> 1211 <div class="pricing-card-tax">+ VAT where applicable</div> 1212 </div> 1213 <ul class="pricing-card-features"> 1214 <li> 1215 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1216 ~52,000 full link checks 1217 </li> 1218 <li> 1219 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1220 All monitoring features 1221 </li> 1222 <li> 1223 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1224 Email & Slack alerts 1225 </li> 1226 <li> 1227 <i data-lucide="check" style="width: 16px; height: 16px;"></i> 1228 Seller ledger, DR & domain trust history 1229 </li> 1230 </ul> 1231 <a href="/register" class="btn btn-secondary">Get Started</a> 1232 </div> 1233 </div> 1234 1235 <div class="pricing-benefits"> 1236 <div class="pricing-benefit"> 1237 <i data-lucide="gift" style="width: 18px; height: 18px;"></i> 1238 1,000 free tokens on signup 1239 </div> 1240 <div class="pricing-benefit"> 1241 <i data-lucide="check-circle" style="width: 18px; height: 18px;"></i> 1242 Start monitoring instantly 1243 </div> 1244 <div class="pricing-benefit"> 1245 <i data-lucide="check-circle" style="width: 18px; height: 18px;"></i> 1246 No subscriptions 1247 </div> 1248 <div class="pricing-benefit"> 1249 <i data-lucide="check-circle" style="width: 18px; height: 18px;"></i> 1250 Full features included 1251 </div> 1252 </div> 1253 1254 <p class="pricing-tax-note"> 1255 Prices shown in USD. Applicable VAT, GST, or sales tax is calculated and added 1256 at checkout based on your billing country. LinkGuard uses 1257 <a href="https://www.paddle.com/legal/terms" rel="noopener">Paddle</a> 1258 as our Merchant of Record â all invoices include the applicable tax breakdown. 1259 </p> 1260 1261 <!-- Token Calculator --> 1262 <div class="calculator"> 1263 <div class="calculator-header"> 1264 <h3>Token calculator</h3> 1265 <p>Estimate how many tokens you'll need per month</p> 1266 </div> 1267 <div class="calculator-body"> 1268 <div class="calculator-inputs"> 1269 <div class="calc-input-group"> 1270 <label for="linkCount">Number of backlinks to monitor</label> 1271 <input type="number" id="linkCount" value="100" min="1" max="100000" placeholder="e.g., 100"> 1272 </div> 1273 <div class="calc-input-group"> 1274 <label>Check frequency</label> 1275 <div class="custom-select" id="checkFrequencySelect"> 1276 <input type="hidden" id="checkFrequency" value="4"> 1277 <div class="custom-select-trigger" tabindex="0" role="combobox" aria-expanded="false" aria-haspopup="listbox"> 1278 <span class="custom-select-value">Weekly (4 checks/month)</span> 1279 <svg class="custom-select-arrow" viewB
1279ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 1280 <polyline points="6 9 12 15 18 9"/> 1281 </svg> 1282 </div> 1283 <div class="custom-select-options" role="listbox"> 1284 <div class="custom-select-option" data-value="30" role="option">Daily (30 checks/month)</div> 1285 <div class="custom-select-option selected" data-value="4" role="option" aria-selected="true">Weekly (4 checks/month)</div> 1286 <div class="custom-select-option" data-value="1" role="option">Monthly (1 check/month)</div> 1287 </div> 1288 </div> 1289 </div> 1290 <div class="calc-rates"> 1291 <div class="calc-rate"> 1292 <span class="calc-rate-name">SERP check</span> 1293 <span class="calc-rate-value" id="calcRateSerp">7 tokens</span> 1294 </div> 1295 <div class="calc-rate"> 1296 <span class="calc-rate-name">HTML check</span> 1297 <span class="calc-rate-value" id="calcRateHtml">5 tokens</span> 1298 </div> 1299 <div class="calc-rate"> 1300 <span class="calc-rate-name">Full check (both)</span> 1301 <span class="calc-rate-value" id="calcRateFull">12 tokens</span> 1302 </div> 1303 </div> 1304 </div> 1305 <div class="calculator-result"> 1306 <div class="calc-result-header">Monthly token usage:</div> 1307 <div id="calcResultTokens" class="calc-result-tokens">2,200 <span>tokens</span></div> 1308 <div id="calcResultPeriod" class="calc-result-period">for 100 links checked weekly</div> 1309 <div class="calc-result-breakdown"> 1310 <div class="calc-breakdown-row"> 1311 <span class="label">Links:</span> 1312 <span id="calcLinks" class="value">100</span> 1313 </div> 1314 <div class="calc-breakdown-row"> 1315 <span class="label">Checks/month:</span> 1316 <span id="calcChecks" class="value">4</span> 1317 </div> 1318 <div class="calc-breakdown-row"> 1319 <span class="label">Formula:</span> 1320 <span id="calcFormula" class="value">100 Ã 4 Ã 12</span> 1321 </div> 1322 </div> 1323 <div id="calcRecommendation" class="calc-result-recommendation"> 1324 <i data-lucide="lightbulb" style="width: 20px; height: 20px;"></i> 1325 <div class="calc-result-recommendation-text"> 1326 Recommended: <strong>Lite ($25)</strong> â 25,000 tokens 1327 </div> 1328 </div> 1329 </div> 1330 </div> 1331 </div> 1332 </div> 1333 </section> 1334 1335 <!-- ============ FAQ SECTION ============ --> 1336 <section class="faq" id="faq"> 1337 <div class="container"> 1338 <div class="faq-header"> 1339 <span class="section-badge"> 1340 <i data-lucide="help-circle" style="width: 14px; height: 14px;"></i> 1341 FAQ 1342 </span> 1343 <h2>Frequently asked questions</h2> 1344 </div> 1345 <div class="faq-grid"> 1346 <div class="faq-item"> 1347 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1348 <span>How quickly can I get started?</span> 1349 <i data-lucide="chevron-down" style="width: 20p
1349x; height: 20px;"></i> 1350 </div> 1351 <div class="faq-answer"> 1352 <p>Under 5 minutes. Sign up, upload your CSV or add links manually, and monitoring starts immediately. No API keys needed, no complex setup.</p> 1353 </div> 1354 </div> 1355 <div class="faq-item"> 1356 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1357 <span>What types of checks do you perform?</span> 1358 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1359 </div> 1360 <div class="faq-answer"> 1361 <p>Two main types: SERP checks (is the page indexed in Google?) and HTML checks (does the link exist, what's the anchor text, is it dofollow/nofollow?). Both are essential for complete monitoring.</p> 1362 </div> 1363 </div> 1364 <div class="faq-item"> 1365 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1366 <span>How fast are the alerts?</span> 1367 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1368 </div> 1369 <div class="faq-answer"> 1370 <p>Alerts are sent within minutes of detecting a change. You'll get notified via Email and/or Slack (your choice) with full details of what changed.</p> 1371 </div> 1372 </div> 1373 <div class="faq-item"> 1374 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1375 <span>Can I monitor competitor backlinks?</span> 1376 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1377 </div> 1378 <div class="faq-answer"> 1379 <p>LinkGuard is designed for monitoring your own purchased backlinks. For competitor research, we recommend dedicated tools like Ahrefs or SEMrush.</p> 1380 </div> 1381 </div> 1382 <div class="faq-item"> 1383 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1384 <span>Do I get free tokens to start?</span> 1385 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1386 </div> 1387 <div class="faq-answer"> 1388 <p>Yes! Every new verified user receives 1,000 free tokens credited to their account. Tokens never expire â there is no trial period or forced purchase to keep them.</p> 1389 </div> 1390 </div> 1391 <div class="faq-item"> 1392 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1393 <span>Why was VAT added to my total at checkout?</span> 1394 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1395 </div> 1396 <div class="faq-answer"> 1397 <p>Prices on this page are shown in USD without tax. If your country charges VAT, GST, or sales tax on digital services, Paddle â our payment processor and Merchant of Record â calculates the correct rate based on your billing country and adds it at checkout. Paddle remits that tax to your local authority on our behalf, and you receive an invoice with the full breakdown. We do not collect or handle any tax data ourselves.</p> 1398 </div> 1399 </div> 1400 <div class="faq-item"> 1401 <div class="faq-question" tabindex="0" role="button" aria-expanded="false"> 1402 <span>Do you offer white-label solutions?</span> 1403 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1404 </div> 1405 <div class="faq-answer"> 1406 <p>Branded PDF reports are live for every account: set your name, accent color, and logo once in Profile settings, and every report you export renders under your brand â no LinkGuard marks on it. Deeper white-label scopes â a client-portal on <code>client.linkguard.ai</code> subdomain or full UI rebrand under your own domain â are still on the roadmap. Need one of those sooner? <a href="/contact?topic=white-label">Ping us</a>.</p> 1407 </div> 1408 </div> 1409 <div class="faq-item"> 1410 <div class="faq-question" tabindex="0" role="button" aria-expanded="false">
1411 <span>What data do you collect?</span> 1412 <i data-lucide="chevron-down" style="width: 20px; height: 20px;"></i> 1413 </div> 1414 <div class="faq-answer"> 1415 <p>Only what's needed: the links you add and their monitoring data. We never sell your data or share with third parties. GDPR and CCPA compliant.</p> 1416 </div> 1417 </div> 1418 </div> 1419 </div> 1420 </section> 1421 1422 <!-- ============ FINAL CTA SECTION ============ --> 1423 <section class="final-cta" aria-labelledby="cta-heading"> 1424 <div class="container"> 1425 <div class="final-cta-content"> 1426 <h2 id="cta-heading">Ready to protect your backlinks?</h2> 1427 <p>Start monitoring in under 5 minutes. Get 1,000 free tokens on signup.</p> 1428 <a href="/register" class="btn btn-primary" aria-label="Start free with LinkGuard"> 1429 <i data-lucide="rocket" style="width: 20px; height: 20px;" aria-hidden="true"></i> 1430 Start Free 1431 </a> 1432 <p class="final-cta-note">1,000 free tokens ⢠Pay-as-you-go ⢠No subscriptions ⢠Tokens never expire</p> 1433 </div> 1434 </div> 1435 </section> 1436 1437 </main> 1438 1439 <!-- ============ FOOTER ============ --> 1440 <footer role="contentinfo" aria-label="Site footer" itemscope itemtype="https://schema.org/WPFooter"> 1441 <div class="container"> 1442 <div class="footer-grid"> 1443 <div class="footer-brand" itemscope itemtype="https://schema.org/Organization"> 1444 <a href="/" class="logo" style="color: white;" itemprop="url" aria-label="LinkGuard.ai home"> 1445 <div class="logo-icon" aria-hidden="true"> 1446 <svg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 100 100"> 1447 <defs> 1448 <linearGradient id="footerShieldBg" x1="0%" y1="0%" x2="100%" y2="100%"> 1449 <stop offset="0%" stop-color="#0d0d14"/> 1450 <stop offset="100%" stop-color="#0a0a0f"/> 1451 </linearGradient> 1452 <linearGradient id="footerCyan" x1="0%" y1="0%" x2="100%" y2="100%"> 1453 <stop offset="0%" stop-color="#00f5d4"/> 1454 <stop offset="100%" stop-color="#00d4aa"/> 1455 </linearGradient> 1456 <filter id="footerGlow" x="-50%" y="-50%" width="200%" height="200%"> 1457 <feGaussianBlur stdDeviation="2" result="blur"/> 1458 <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge> 1459 </filter> 1460 </defs> 1461 <path d="M50 5 L90 20 L90 45 C90 70 70 90 50 95 C30 90 10 70 10 45 L10 20 Z" fill="url(#footerShieldBg)" stroke="url(#footerCyan)" stroke-width="2.5" filter="url(#footerGlow)"/> 1462 <path d="M50 15 L80 27 L80 45 C80 65 65 80 50 85 C35 80 20 65 20 45 L20 27 Z" fill="none" stroke="#00f5d4" stroke-width="0.8" opacity="0.4"/> 1463 <g transform="translate(50, 50) rotate(-30)" filter="url(#footerGlow)"> 1464 <ellipse cx="-8" cy="0" rx="12" ry="8" fill="none" stroke="#00f5d4" stroke-width="4"/> 1465 <ellipse cx="8" cy="0" rx="12" ry="8" fill="none" stroke="#00f5d4" stroke-width="4"/> 1466 </g> 1467 </svg> 1468 </div> 1469 <span itemprop="name">LinkGuard</span> 1470 </a> 1471 <p itemprop="description">The operating system for protecting your link building investments. Automated monitoring with instant alerts to email and Slack.</p> 1472 </div> 1473 <div class="footer-col"> 1474 <h4>Product</h4> 1475 <ul role="list"> 1476 <li><a href="#features">Features</a></li> 1477 <li><a href="#pricing">Pricing</a></li> 1478 <li><a href="#how-it-works">How It Works</a></li> 1479 <li><a href="#faq">FAQ</a></li> 1480 <li><a href="/alternatives">Best monitors 2026</a></li> 1481 <li><a href="/vs/linkwatcher">vs Linkwatcher</a></li> 1482 <li><a href="/vs/backlinkmanager">vs BacklinkManager</a></li> 1483 <li><a href="/vs/linkody">vs Linkody</a></li> 1484 <li><a href="/vs/ahrefs">vs Ahrefs</a></li> 1485 <li><a href="/vs/semrush">vs Semrush</a></li> 1486 </ul> 1487 </div> 1488 <div class="footer-col"> 1489 <h4>Company</h4> 1490 <ul role="list"> 1491 <li><a href="/about">About</a></li> 1492 <li><a href="/blog">Blog</a></li> 1493 <li><a href="/contact">Contact</a></li> 1494 </ul> 1495 </div> 1496 <div class="footer-col"> 1497 <h4>Legal</h4> 1498 <ul role="list"> 1499 <li><a href="/privacy">Privacy Policy</a></li> 1500 <li><a href="/terms">Terms of Service</a></li> 1501 <li><a href="/refund">Refund Policy</a></li> 1502 <li><a href="/gdpr">GDPR</a></li> 1503 <li><a href="/security">Security</a></li> 1504 </ul> 1505 </div> 1506 </div> 1507 <div class="footer-bottom"> 1508 <p>© <span id="currentYear">2025</span> LinkGuard.ai. All rights reserved.</p> 1509 <div class="footer-social" role="list" aria-label="Social media links"> 1510 <a href="https://x.com/o638562538" target="_blank" rel="noopener noreferrer" aria-label="Follow us on X"><i data-lucide="twitter" style="width: 18px; height: 18px;" aria-hidden="true"></i></a> 1511 <a href="https://www.linkedin.com/in/andrievskiiandr/" target="_blank" rel="noopener noreferrer" aria-label="Connect with us on LinkedIn"><i data-lucide="linkedin" style="width: 18px; height: 18px;" aria-hidden="true"></i></a> 1512 <a href="https://github.com/Black-coffe" target="_blank" rel="noopener noreferrer" aria-label="View our GitHub"><i data-lucide="github" style="width: 18px; height: 18px;" aria-hidden="true"></i></a> 1513 <a href="https://www.youtube.com/@andrievskii" target="_blank" rel="noopener noreferrer" aria-label="Watch us on YouTube"><i data-lucide="youtube" style="width: 18px; height: 18px;" aria-hidden="true"></i></a> 1514 </div> 1515 </div> 1516 </div> 1517 </footer> 1518 1519 <!-- Video Modal --> 1520 <div id="videoModal" class="video-modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="videoModalTitle"> 1521 <div class="video-modal-backdrop"></div> 1522 <div class="video-modal-content"> 1523 <button type="button" class="video-modal-close" id="videoModalClose" aria-label="Close video"> 1524 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 1525 <line x1="18" y1="6" x2="6" y2="18"></line> 1526 <line x1="6" y1="6" x2="18" y2="18"></line> 1527 </svg> 1528 </button> 1529 <h2 id="videoModalTitle" class="visually-hidden">LinkGuard Demo Video</h2> 1530 <div class="video-modal-wrapper"> 1531 <iframe 1532 id="videoFrame" 1533 src="" 1534 title="LinkGuard Demo Video" 1535 frameborder="0" 1536 allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
1537 referrerpolicy="strict-origin-when-cross-origin" 1538 allowfullscreen> 1539 </iframe> 1540 </div> 1541 </div> 1542 </div> 1543 1544 <style> 1545 /* Video Modal Styles */ 1546 .video-modal { 1547 position: fixed; 1548 inset: 0; 1549 z-index: 10000; 1550 display: flex; 1551 align-items: center; 1552 justify-content: center; 1553 padding: 40px; 1554 opacity: 0; 1555 visibility: hidden; 1556 transition: opacity 0.4s ease, visibility 0.4s ease; 1557 } 1558 1559 .video-modal.active { 1560 opacity: 1; 1561 visibility: visible; 1562 } 1563 1564 .video-modal-backdrop { 1565 position: absolute; 1566 inset: 0; 1567 background: rgba(5, 5, 10, 0.92); 1568 backdrop-filter: blur(8px); 1569 -webkit-backdrop-filter: blur(8px); 1570 } 1571 1572 /* Animated grid overlay on backdrop */ 1573 .video-modal-backdrop::before { 1574 content: ''; 1575 position: absolute; 1576 inset: 0; 1577 background-image: 1578 linear-gradient(rgba(0, 245, 212, 0.03) 1px, transparent 1px), 1579 linear-gradient(90deg, rgba(0, 245, 212, 0.03) 1px, transparent 1px); 1580 background-size: 50px 50px; 1581 animation: gridPulse 4s ease-in-out infinite; 1582 } 1583 1584 @keyframes gridPulse { 1585 0%, 100% { opacity: 0.5; } 1586 50% { opacity: 1; } 1587 } 1588 1589 .video-modal-content { 1590 position: relative; 1591 width: 100%; 1592 max-width: 1000px; 1593 transform: scale(0.9) translateY(20px); 1594 transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); 1595 } 1596 1597 .video-modal.active .video-modal-content { 1598 transform: scale(1) translateY(0); 1599 } 1600 1601 .video-modal-wrapper { 1602 position: relative; 1603 width: 100%; 1604 padding-top: 56.25%; /* 16:9 aspect ratio */ 1605 background: linear-gradient(135deg, rgba(0, 245, 212, 0.1), rgba(247, 37, 133, 0.1)); 1606 border-radius: 4px; 1607 overflow: hidden; 1608 box-shadow: 1609 0 0 0 1px rgba(0, 245, 212, 0.3), 1610 0 0 30px rgba(0, 245, 212, 0.2), 1611 0 0 60px rgba(0, 245, 212, 0.1), 1612 0 25px 50px -12px rgba(0, 0, 0, 0.8); 1613 } 1614 1615 /* Animated border glow */ 1616 .video-modal-wrapper::before { 1617 content: ''; 1618 position: absolute; 1619 inset: -2px; 1620 background: linear-gradient( 1621 90deg, 1622 transparent, 1623 rgba(0, 245, 212, 0.5), 1624 rgba(247, 37, 133, 0.5), 1625 rgba(0, 245, 212, 0.5), 1626 transparent 1627 ); 1628 background-size: 400% 100%; 1629 border-radius: 6px; 1630 z-index: -1; 1631 animation: borderGlow 3s linear infinite; 1632 } 1633 1634 @keyframes borderGlow { 1635 0% { background-position: 100% 0; } 1636 100% { background-position: -100% 0; } 1637 } 1638 1639 .video-modal-wrapper iframe { 1640 position: absolute; 1641 top: 0; 1642 left: 0; 1643 width: 100%; 1644 height: 100%; 1645 border: none; 1646 } 1647 1648 /* Close button */ 1649 .video-modal-close { 1650 position: absolute; 1651 top: -50px; 1652 right: 0; 1653 width: 44px; 1654 height: 44px; 1655 display: flex; 1656 align-items: center; 1657 justify-content: center; 1658 background: rgba(15, 15, 25, 0.8); 1659 border: 1px solid rgba(0, 245, 212, 0.3); 1660 border-radius: 50%; 1661 cursor: pointer; 1662 transition: all 0.3s ease; 1663 z-index: 10; 1664 } 1665 1666 .video-modal-close svg { 1667 width: 20px; 1668 height: 20px; 1669 stroke: rgba(255, 255, 255, 0.7); 1670 transition: all 0.3s ease; 1671 } 1672 1673 .video-modal-close:hover { 1674 background: rgba(0, 245, 212, 0.15); 1675 border-color: var(--neon-cyan, #00f5d4); 1676 box-shadow: 1677 0 0 20px rgba(0, 245, 212, 0.4), 1678 0 0 40px rgba(0, 245, 212, 0.2),
1679 inset 0 0 15px rgba(0, 245, 212, 0.1); 1680 transform: rotate(90deg); 1681 } 1682 1683 .video-modal-close:hover svg { 1684 stroke: var(--neon-cyan, #00f5d4); 1685 filter: drop-shadow(0 0 8px rgba(0, 245, 212, 0.8)); 1686 } 1687 1688 /* Pulsing glow animation on close button */ 1689 .video-modal-close::before { 1690 content: ''; 1691 position: absolute; 1692 inset: -3px; 1693 border-radius: 50%; 1694 background: conic-gradient( 1695 from 0deg, 1696 transparent, 1697 rgba(0, 245, 212, 0.4), 1698 rgba(247, 37, 133, 0.4), 1699 transparent 1700 ); 1701 animation: closeButtonGlow 2s linear infinite; 1702 opacity: 0; 1703 transition: opacity 0.3s ease; 1704 } 1705 1706 .video-modal-close:hover::before { 1707 opacity: 1; 1708 } 1709 1710 @keyframes closeButtonGlow { 1711 0% { transform: rotate(0deg); } 1712 100% { transform: rotate(360deg); } 1713 } 1714 1715 /* Visually hidden for accessibility */ 1716 .visually-hidden { 1717 position: absolute; 1718 width: 1px; 1719 height: 1px; 1720 padding: 0; 1721 margin: -1px; 1722 overflow: hidden; 1723 clip: rect(0, 0, 0, 0); 1724 white-space: nowrap; 1725 border: 0; 1726 } 1727 1728 /* Body scroll lock when modal is open */ 1729 body.modal-open { 1730 overflow: hidden; 1731 } 1732 1733 /* Responsive adjustments */ 1734 @media (max-width: 768px) { 1735 .video-modal { 1736 padding: 20px; 1737 } 1738 1739 .video-modal-close { 1740 top: -45px; 1741 right: 0; 1742 width: 40px; 1743 height: 40px; 1744 } 1745 1746 .video-modal-close svg { 1747 width: 18px; 1748 height: 18px; 1749 } 1750 } 1751 1752 /* ============================================ 1753 Header Actions (Login + Get Started) 1754 ============================================ */ 1755 .header-actions { 1756 display: flex; 1757 align-items: center; 1758 gap: 12px; 1759 } 1760 1761 .header-login { 1762 display: flex; 1763 align-items: center; 1764 gap: 8px; 1765 padding: 10px 16px; 1766 background: transparent; 1767 border: 1px solid rgba(0, 245, 212, 0.4); 1768 border-radius: 8px; 1769 color: var(--neon-cyan); 1770 font-family: var(--font-body); 1771 font-size: 14px; 1772 font-weight: 600; 1773 text-decoration: none; 1774 transition: all 0.3s ease; 1775 cursor: pointer; 1776 } 1777 1778 .header-login svg { 1779 width: 18px; 1780 height: 18px; 1781 stroke: var(--neon-cyan); 1782 transition: all 0.3s ease; 1783 } 1784 1785 .header-login:hover { 1786 background: rgba(0, 245, 212, 0.1); 1787 border-color: var(--neon-cyan); 1788 box-shadow: 0 0 20px rgba(0, 245, 212, 0.3); 1789 transform: translateY(-2px); 1790 } 1791 1792 .header-login:hover svg { 1793 transform: translateX(3px); 1794 } 1795 1796 /* Hide login text on smaller screens */ 1797 @media (max-width: 900px) { 1798 .header-login .login-text { 1799 display: none; 1800 } 1801 1802 .header-login { 1803 padding: 10px; 1804 } 1805 } 1806 1807 /* Returning user mode - Sign Up always visible alongside Log In */ 1808 /* (no suppression rule â both buttons shown for all guest states) */ 1809 1810 /* Compact Sign Up CTA on small screens so both buttons fit the header */ 1811 @media (max-width: 640px) { 1812 .header-cta { 1813 padding: 8px 12px; 1814 font-size: 12px; 1815 letter-spacing: 0.5px; 1816 } 1817 1818 .header-actions { 1819 gap: 8px; 1820 } 1821 } 1822 1823 /* ============================================ 1824 User Menu Styles (Header Dropdown) 1825 ============================================ */ 1826 .user-menu { 1827 position: relative; 1828 } 1829 1830 .user-menu-trigger { 1831 display: flex; 1832 align-items: center; 1833 gap: 10px; 1834 padding: 6px 12px 6px 6px;
1835 background: rgba(0, 245, 212, 0.1); 1836 border: 1px solid rgba(0, 245, 212, 0.3); 1837 border-radius: 100px; 1838 cursor: pointer; 1839 transition: all 0.3s ease; 1840 color: var(--text-primary); 1841 font-family: var(--font-body); 1842 } 1843 1844 .user-menu-trigger:hover { 1845 background: rgba(0, 245, 212, 0.15); 1846 border-color: var(--neon-cyan); 1847 box-shadow: 0 0 15px rgba(0, 245, 212, 0.2); 1848 } 1849 1850 .user-avatar { 1851 width: 32px; 1852 height: 32px; 1853 background: linear-gradient(135deg, var(--neon-cyan), var(--neon-blue)); 1854 border-radius: 50%; 1855 display: flex; 1856 align-items: center; 1857 justify-content: center; 1858 font-family: var(--font-display); 1859 font-weight: 700; 1860 font-size: 14px; 1861 color: var(--bg-deep); 1862 } 1863 1864 .user-name { 1865 font-size: 14px; 1866 font-weight: 600; 1867 max-width: 120px; 1868 overflow: hidden; 1869 text-overflow: ellipsis; 1870 white-space: nowrap; 1871 } 1872 1873 .user-menu-arrow { 1874 width: 16px; 1875 height: 16px; 1876 stroke: var(--text-muted); 1877 transition: transform 0.3s ease; 1878 } 1879 1880 .user-menu.open .user-menu-arrow { 1881 transform: rotate(180deg); 1882 } 1883 1884 /* Dropdown */ 1885 .user-dropdown { 1886 position: absolute; 1887 top: calc(100% + 10px); 1888 right: 0; 1889 min-width: 240px; 1890 background: rgba(13, 13, 20, 0.98); 1891 border: 1px solid rgba(0, 245, 212, 0.3); 1892 border-radius: 12px; 1893 padding: 8px 0; 1894 opacity: 0; 1895 visibility: hidden; 1896 transform: translateY(-10px); 1897 transition: all 0.3s ease; 1898 z-index: 1000; 1899 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5), 0 0 30px rgba(0, 245, 212, 0.1); 1900 backdrop-filter: blur(10px); 1901 } 1902 1903 .user-menu.open .user-dropdown { 1904 opacity: 1; 1905 visibility: visible; 1906 transform: translateY(0); 1907 } 1908 1909 .user-dropdown-header { 1910 padding: 12px 16px; 1911 display: flex; 1912 flex-direction: column; 1913 gap: 4px; 1914 } 1915 1916 .user-dropdown-email { 1917 font-family: var(--font-mono); 1918 font-size: 13px; 1919 color: var(--text-primary); 1920 overflow: hidden; 1921 text-overflow: ellipsis; 1922 white-space: nowrap; 1923 } 1924 1925 .user-dropdown-status { 1926 display: flex; 1927 align-items: center; 1928 gap: 6px; 1929 font-family: var(--font-mono); 1930 font-size: 11px; 1931 color: var(--neon-cyan); 1932 text-transform: uppercase; 1933 letter-spacing: 0.5px; 1934 } 1935 1936 .status-dot { 1937 width: 6px; 1938 height: 6px; 1939 background: var(--neon-cyan); 1940 border-radius: 50%; 1941 box-shadow: 0 0 6px var(--glow-cyan); 1942 animation: pulse-dot 2s infinite; 1943 } 1944 1945 @keyframes pulse-dot { 1946 0%, 100% { opacity: 1; } 1947 50% { opacity: 0.5; } 1948 } 1949 1950 .user-dropdown-divider { 1951 height: 1px; 1952 background: rgba(255, 255, 255, 0.1); 1953 margin: 8px 0; 1954 } 1955 1956 .user-dropdown-item { 1957 display: flex; 1958 align-items: center; 1959 gap: 12px; 1960 padding: 10px 16px; 1961 color: var(--text-secondary); 1962 text-decoration: none; 1963 font-family: var(--font-body); 1964 font-size: 14px; 1965 font-weight: 500; 1966 transition: all 0.2s ease; 1967 cursor: pointer; 1968 background: none; 1969 border: none; 1970 width: 100%; 1971 text-align: left; 1972 } 1973 1974 .user-dropdown-item svg { 1975 width: 18px; 1976 height: 18px; 1977 stroke: var(--text-muted); 1978 transition: stroke 0.2s ease; 1979 } 1980 1981 .user-dropdown-item:hover {
1982 background: rgba(0, 245, 212, 0.1); 1983 color: var(--text-primary); 1984 } 1985 1986 .user-dropdown-item:hover svg { 1987 stroke: var(--neon-cyan); 1988 } 1989 1990 .user-dropdown-item.disabled { 1991 opacity: 0.5; 1992 cursor: not-allowed; 1993 pointer-events: none; 1994 } 1995 1996 .coming-soon-badge { 1997 margin-left: auto; 1998 font-family: var(--font-mono); 1999 font-size: 9px; 2000 padding: 2px 6px; 2001 background: rgba(255, 255, 255, 0.1); 2002 border-radius: 4px; 2003 color: var(--text-muted); 2004 text-transform: uppercase; 2005 letter-spacing: 0.5px; 2006 } 2007 2008 .user-dropdown-logout { 2009 color: var(--neon-magenta); 2010 } 2011 2012 .user-dropdown-logout svg { 2013 stroke: var(--neon-magenta); 2014 } 2015 2016 .user-dropdown-logout:hover { 2017 background: rgba(247, 37, 133, 0.1); 2018 } 2019 2020 /* Mobile adjustments for user menu */ 2021 @media (max-width: 768px) { 2022 .user-name { 2023 display: none; 2024 } 2025 2026 .user-menu-trigger { 2027 padding: 4px; 2028 border-radius: 50%; 2029 } 2030 2031 .user-menu-arrow { 2032 display: none; 2033 } 2034 2035 .user-dropdown { 2036 right: -10px; 2037 min-width: 220px; 2038 } 2039 } 2040 </style> 2041 2042 <!-- Scripts --> 2043
2043<script src="/static/landing/script.js"></script>
2043 2044 2045 <!-- Pricing Checkout (lazy-loads Paddle.js only when user clicks top-up) --> 2046
2046<script src="/static/js/dashboard/pricing-checkout.js?v=2" defer></script>
2046 2047 <!-- Toast system for 402 feedback on landing page --> 2048
2048<script src="/static/js/dashboard/toast.js" defer></script>
2048 2049 <!-- Inject pricing-cta CSS for landing page buttons --> 2050 <link rel="stylesheet" href="/static/css/dashboard/pricing-cta.css?v=2"> 2051 <link rel="stylesheet" href="/static/css/dashboard/toast.css"> 2052 2053 <!-- Video Modal Script --> 2054
2054<script> 2055 (function() { 2056 const videoModal = document.getElementById('videoModal'); 2057 const videoFrame = document.getElementById('videoFrame'); 2058 const watchDemoBtn = document.getElementById('watchDemoBtn'); 2059 const closeBtn = document.getElementById('videoModalClose'); 2060 const backdrop = videoModal.querySelector('.video-modal-backdrop'); 2061 2062 // YouTube video ID 2063 const YOUTUBE_VIDEO_ID = 'JpcUaS-M_I0'; 2064 2065 function openModal() { 2066 // Set the video source with autoplay 2067 videoFrame.src = `https://www.youtube.com/embed/${YOUTUBE_VIDEO_ID}?autoplay=1&rel=0&modestbranding=1&showinfo=0&enablejsapi=1`; 2068 2069 // Show modal 2070 videoModal.classList.add('active'); 2071 videoModal.setAttribute('aria-hidden', 'false'); 2072 document.body.classList.add('modal-open'); 2073 2074 // Focus management for accessibility 2075 closeBtn.focus(); 2076 2077 // Add escape key listener 2078 document.addEventListener('keydown', handleEscKey); 2079 } 2080 2081 function closeModal() { 2082 // Hide modal 2083 videoModal.classList.remove('active'); 2084 videoModal.setAttribute('aria-hidden', 'true'); 2085 document.body.classList.remove('modal-open'); 2086 2087 // Stop YouTube video using postMessage API 2088 if (videoFrame.contentWindow) { 2089 videoFrame.contentWindow.postMessage( 2090 JSON.stringify({ event: 'command', func: 'pauseVideo' }), 2091 '*' 2092 ); 2093 } 2094 2095 // Clear video source after short delay to ensure stop 2096 setTimeout(function() { 2097 videoFrame.src = ''; 2098 }, 100); 2099 2100 // Return focus to trigger button 2101 watchDemoBtn.focus(); 2102 2103 // Remove escape key listener 2104 document.removeEventListener('keydown', handleEscKey); 2105 } 2106 2107 function handleEscKey(e) { 2108 if (e.key === 'Escape') { 2109 closeModal(); 2110 } 2111 } 2112 2113 // Event listeners 2114 watchDemoBtn.addEventListener('click', openModal); 2115 closeBtn.addEventListener('click', closeModal); 2116 backdrop.addEventListener('click', closeModal); 2117 2118 // Prevent clicks inside content from closing modal 2119 videoModal.querySelector('.video-modal-content').addEventListener('click', function(e) { 2120 e.stopPropagation(); 2121 }); 2122 })(); 2123 </script>
2123 2124 2125 <!-- Active Navigation Highlight --> 2126
2126<script> 2127 (function() { 2128 const navLinks = document.querySelectorAll('nav a[href^="#"]'); 2129 const sections = []; 2130 2131 // Collect sections that match navigation links 2132 navLinks.forEach(function(link) { 2133 const sectionId = link.getAttribute('href').substring(1); 2134 const section = document.getElementById(sectionId); 2135 if (section) { 2136 sections.push({ id: sectionId, element: section, link: link }); 2137 } 2138 }); 2139 2140 // Function to update active link 2141 function updateActiveLink(activeId) { 2142 navLinks.forEach(function(link) { 2143 link.classList.remove('active'); 2144 }); 2145 2146 if (activeId) { 2147 const activeLink = document.querySelector('nav a[href="#' + activeId + '"]'); 2148 if (activeLink) { 2149 activeLink.classList.add('active'); 2150 } 2151 } 2152 } 2153 2154 // Intersection Observer for sections 2155 const observerOptions = { 2156 root: null, 2157 rootMargin: '-20% 0px -60% 0px', 2158 threshold: 0 2159 }; 2160 2161 let currentActiveId = null; 2162 2163 const observer = new IntersectionObserver(function(entries) { 2164 entries.forEach(function(entry) { 2165 if (entry.isIntersecting) { 2166 currentActiveId = entry.target.id; 2167 updateActiveLink(currentActiveId); 2168 } 2169 }); 2170 }, observerOptions); 2171 2172 // Observe all sections 2173 sections.forEach(function(section) { 2174 observer.observe(section.element); 2175 }); 2176 2177 // Handle click navigation (smooth scroll + immediate highlight) 2178 navLinks.forEach(function(link) { 2179 link.addEventListener('click', function(e) { 2180 const sectionId = this.getAttribute('href').substring(1); 2181 updateActiveLink(sectionId); 2182 }); 2183 }); 2184 2185 // Clear active state when at the very top (hero section) 2186 window.addEventListener('scroll', function() { 2187 if (window.scrollY < 200) { 2188 updateActiveLink(null); 2189 } 2190 }); 2191 })(); 2192 </script>
2192 2193 2194 <!-- User Authentication & Menu Script --> 2195
2195<script> 2196 (function() { 2197 'use strict'; 2198 2199 // localStorage key for tracking returning users 2200 const HAS_ACCOUNT_KEY = 'linkguard_has_account'; 2201 2202 // DOM Elements 2203 const headerActions = document.getElementById('header-actions'); 2204 const guestCta = document.getElementById('guest-cta'); 2205 const loginBtn = document.getElementById('login-btn'); 2206 const userMenu = document.getElementById('user-menu'); 2207 const userMenuTrigger = document.getElementById('user-menu-trigger'); 2208 const userDropdown = document.getElementById('user-dropdown'); 2209 const userAvatarLetter = document.getElementById('user-avatar-letter'); 2210 const userName = document.getElementById('user-name'); 2211 const userDropdownEmail = document.getElementById('user-dropdown-email'); 2212 const logoutBtn = document.getElementById('logout-btn'); 2213 2214 // Check if this browser has a registered account 2215 function hasRegisteredAccount() { 2216 try { 2217 return localStorage.getItem(HAS_ACCOUNT_KEY) === 'true'; 2218 } catch (e) { 2219 // localStorage might be disabled 2220 return false; 2221 } 2222 } 2223 2224 // Mark this browser as having a registered account 2225 function markAsRegisteredAccount() { 2226 try { 2227 localStorage.setItem(HAS_ACCOUNT_KEY, 'true'); 2228 } catch (e) { 2229 // localStorage might be disabled 2230 console.warn('Could not save account status to localStorage'); 2231 } 2232 } 2233 2234 // Shared, memoized auth probe. Uses /auth/session, which returns 200 with 2235 // {authenticated, user} for everyone â so anonymous visitors no longer 2236 // trigger a 401 "Failed to load resource" console error. Memoized so the 2237 // header and the welcome-bonus ribbon share ONE request instead of each 2238 // firing its own /auth/me call. 2239 function getSession() { 2240 if (!window.__lgSession) { 2241 window.__lgSession = fetch('/api/v1/auth/session', { 2242 method: 'GET', 2243 credentials: 'include', 2244 cache: 'no-store', 2245 headers: { 'Accept': 'application/json' } 2246 }) 2247 .then(function (r) { return r.ok ? r.json() : { authenticated: false, user: null }; }) 2248 .catch(function () { return { authenticated: false, user: null }; }); 2249 } 2250 return window.__lgSession; 2251 } 2252 // Expose so other script blocks (e.g. the welcome-bonus ribbon IIFE) can 2253 // reuse the same memoized probe instead of firing a second auth request. 2254 window.lgGetSession = getSession; 2255 2256 // Check if user is authenticated 2257 async function checkAuth() { 2258 const session = await getSession(); 2259 if (session.authenticated && session.user) { 2260 showUserUI(session.user); 2261 } else { 2262 showGuestUI(); 2263 } 2264 } 2265 2266 function showGuestUI() { 2267 // Hide user menu 2268 if (userMenu) userMenu.style.display = 'none'; 2269 2270 // Show header actions â Sign Up + Log In always visible for all guest states 2271 if (headerActions) headerActions.style.display = 'flex'; 2272 if (headerActions) headerActions.classList.remove('returning-user'); 2273 if (guestCta) guestCta.style.display = 'inline-flex'; 2274 if (loginBtn) loginBtn.style.display = 'flex'; 2275 2276 // Both returning users and new visitors see Sign Up + Log In. 2277 // hasRegisteredAccount() is preserved for analytics use only. 2278 } 2279 2280 function showUserUI(user) { 2281 // Hide guest actions, show user menu 2282 if (headerActions) headerActions.style.display = 'none'; 2283 if (userMenu) userMenu.style.display = 'block'; 2284 2285 // Mark this browser as having a registered account 2286 // This persists even after logout 2287 markAsRegisteredAccount(); 2288 2289 // Set user data 2290 const displayName = user.full_name || user.email.split('@')[0]; 2291 const firstLetter = displayName.charAt(0).toUpperCase(); 2292 2293 if (userAvatarLetter) userAvatarLetter.textContent = firstLetter; 2294 if (userName) userName.textContent = displayName; 2295 if (userDropdownEmail) userDropdownEmail.textContent = user.email; 2296 } 2297 2298 // Toggle dropdown 2299 if (userMenuTrigger) { 2300 userMenuTrigger.addEventListener('click', function(e) { 2301 e.stopPropagation(); 2302 const isOpen = userMenu.classList.toggle('open'); 2303 userMenuTrigger.setAttribute('aria-expanded', isOpen); 2304 }); 2305 } 2306 2307 // Close dropdown when clicking outside 2308 document.addEventListener('click', function(e) { 2309 if (userMenu && !userMenu.contains(e.target)) { 2310 userMenu.classList.remove('open'); 2311 if (userMenuTrigger) { 2312 userMenuTrigger.setAttribute('aria-expanded', 'false'); 2313 } 2314 } 2315 }); 2316 2317 // Close dropdown on Escape key 2318 document.addEventListener('keydown', function(e) { 2319 if (e.key === 'Escape' && userMenu) { 2320 userMenu.classList.remove('open'); 2321 if (userMenuTrigger) { 2322 userMenuTrigger.setAttribute('aria-expanded', 'false'); 2323 } 2324 } 2325 }); 2326 2327 // Logout handler 2328 if (logoutBtn) { 2329 logoutBtn.addEventListener('click', async function(e) { 2330 e.preventDefault(); 2331 2332 try { 2333 await fetch('/api/v1/auth/logout', { 2334 method: 'POST', 2335 credentials: 'include', 2336 headers: { 2337 'Content-Type': 'application/json' 2338 } 2339 }); 2340 } catch (error) { 2341 console.error('Logout error:', error); 2342 } 2343 2344 // Clear cookies and redirect 2345 document.cookie = 'access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; 2346 document.cookie = 'refresh_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; 2347 window.location.href = '/'; 2348 }); 2349 } 2350 2351 // Run auth check on page load 2352 checkAuth(); 2353 })(); 2354 </script>
2354 2355 2356 <!-- Welcome Bonus Ribbon Script --> 2357
2357<script> 2358 (function() { 2359 'use strict'; 2360 var RIBBON_KEY = 'wb-ribbon-dismissed'; 2361 var ribbon = document.getElementById('wb-ribbon'); 2362 var closeBtn = document.getElementById('wb-ribbon-close'); 2363 2364 if (!ribbon) return; 2365 2366 // Hide ribbon if dismissed this session 2367 try { 2368 if (sessionStorage.getItem(RIBBON_KEY) === '1') { 2369 ribbon.style.display = 'none'; 2370 return; 2371 } 2372 } catch (e) { /* sessionStorage blocked */ } 2373 2374 function applyRibbonOffset() { 2375 var h = ribbon.offsetHeight; 2376 var header = document.getElementById('header'); 2377 if (header) header.style.top = h + 'px'; 2378 } 2379 2380 function hideRibbon() { 2381 ribbon.style.display = 'none'; 2382 var header = document.getElementById('header'); 2383 if (header) header.style.top = ''; 2384 } 2385 2386 // Hide for authenticated users. access_token is HttpOnly so JS can't 2387 // read it â probe the session instead. Show ribbon immediately as the 2388 // optimistic default, hide it once the shared probe confirms auth. 2389 // Reuses getSession() so we don't fire a second auth request. 2390 ribbon.classList.add('wb-ribbon--visible'); 2391 applyRibbonOffset(); 2392 window.addEventListener('resize', applyRibbonOffset); 2393 2394 if (window.lgGetSession) { 2395 window.lgGetSession() 2396 .then(function (s) { if (s.authenticated) hideRibbon(); }) 2397 .catch(function () { /* keep ribbon visible */ }); 2398 } 2399 2400 // Close handler 2401 if (closeBtn) { 2402 closeBtn.addEventListener('click', function() { 2403 ribbon.style.height = ribbon.offsetHeight + 'px'; 2404 ribbon.classList.add('wb-ribbon--hiding'); 2405 setTimeout(function() { 2406 ribbon.style.display = 'none'; 2407 var header = document.getElementById('header'); 2408 if (header) header.style.top = ''; 2409 }, 300); 2410 try { sessionStorage.setItem(RIBBON_KEY, '1'); } catch (e) {} 2411 }); 2412 } 2413 })(); 2414 </script>
2414 2415</body> 2416</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.