Join now Sign in Submit
822,552,571
Searches
3,819,172
Submissions
671,982
Sites
7,692
Categories
301,874
Editors
283,040
Contributors

Outrank Every Site in Your Niche

Sydney Window Cleaning | Eastern Suburbs Specialists from 3/window</strong></a> is live in our index. Now claim the top position. Featured sites are pinned above all standard results on the homepage, in their category, and across their target keywords. Rank is determined by remaining duration: the more years you hold, the higher you appear. Choose <strong>1 year</strong> or more to secure the #1 position in <strong>Window Cleaning</strong>, or choose <strong>21 years</strong> to secure the #1 position across all of Viesearch. </p> <div id="bogo-action-banner" class="alert info" style="margin-bottom: 0; margin-top: var(--standard-gap);"> <div class="alert-content"> <div class="alert-text" style="text-align: center;"> <i class="icon star" style="width: 14px; height: 14px; margin-right: 4px; vertical-align: middle; transform: translateY(-1px);"></i> <strong>Special Offer:</strong> For the next 9 hours only, all Featured plans are Buy-One-Year-Get-One-Free! Checkout now to get your time doubled. </div> </div> </div> </div> <form class="standard-form plan-upgrade-form" novalidate> <input type="hidden" name="token" value="236ts"> <div class="pricing-table" style="max-width: 800px; margin: 0 auto calc(var(--standard-gap) * 1.5) auto;"> <div class="card pricing-card plan-option" id="plan-card-free" style="opacity: 0.85; cursor: default;"> <div class="pricing-card__badge">Basic</div> <div class="pricing-card__header"> <h2>Free</h2> <div class="pricing-card__price"> $0<span>forever</span> </div> </div> <ul class="pricing-card__features"> <li><span class="feature-indicator"><i class="icon check"></i></span>Low-priority indexing</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Low-priority queue review</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Basic text-only result</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Lifetime listing</li> <li><span class="feature-indicator off"><i class="icon close"></i></span>No screenshot thumbnail</li> <li><span class="feature-indicator off"><i class="icon close"></i></span>Unbranded listing page</li> <li><span class="feature-indicator off"><i class="icon close"></i></span>No top-of-page homepage placement</li> <li><span class="feature-indicator off"><i class="icon close"></i></span>No top-of-page category placement</li> </ul> <div class="button-group plan-card-cta"> <button type="button" class="button" disabled style="flex: 1; opacity: 0.6; cursor: not-allowed; pointer-events: none;"> <span>Already Active</span> </button> </div> <div class="pricing-card__subtext">This listing is active in the directory.</div> </div> <label class="card pricing-card active plan-option" id="plan-card-featured"> <input type="radio" name="plan" value="featured" checked style="display: none;"> <div class="pricing-card__badge">Premium</div> <div class="pricing-card__header"> <h2>Featured</h2> <div class="pricing-card__price js-dynamic-price-display"> <s class="text-muted js-dynamic-price-original" style="font-size: 0.75em; margin-right: 4px; display: none;">$24.00</s><span class="js-dynamic-price-value" style="font-size: inherit; color: inherit; font-weight: inherit;">$24.00</span><span>/year</span> </div> <div class="js-dynamic-savings-display" style="display: none; color: rgba(var(--color-text), 0.6); font-size: 0.95rem; margin-top: 6px;"></div> </div> <ul class="pricing-card__features"> <li><span class="feature-indicator"><i class="icon check"></i></span>Instant indexing</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Skip the review queue</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Screenshot thumbnail in results</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Lifetime listing</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Premium diamond badge</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Branded listing page</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Top-of-page homepage placement</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Top-of-page category placement</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Rank above shorter-duration sites</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Top placement for your target keywords</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Featured spotlight on competitor pages</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Featured-only sorted results</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Trending searches rotation</li> <li><span class="feature-indicator"><i class="icon check"></i></span>Top 100 Featured eligibility</li> </ul> <div class="featured-years-inline" id="featured-years-config"> <div class="form-group" style="margin-bottom: 0;"> <div class="featured-duration-block js-year-picker" style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px; justify-content: center; margin-bottom: var(--standard-gap);"> <div style="flex: 1 1 160px;"> <div style="font-weight: 600; font-size: 1.15rem; margin-bottom: 2px;">How many years?</div> <div class="pricing-card__subtext" style="text-align: left; margin-top: 0;">Bulk savings starting at 2 years.</div> </div> <div class="search-input-box" style="flex: 0 0 140px; width: 140px;"> <div class="tool-group" style="width: 100%; justify-content: space-between; align-items: center;"> <button type="button" class="button transparent light js-year-minus" aria-label="Decrease years" style="border-radius: 50%; aspect-ratio: 1;"><i class="icon minus"></i></button> <span class="js-year-display" style="font-size: 1.15rem; font-weight: 700; flex: 1; text-align: center;">1</span> <input type="hidden" name="featuredYears" class="js-year-input" min="1" max="24" value="1"> <button type="button" class="button transparent light js-year-plus" aria-label="Increase years" style="border-radius: 50%; aspect-ratio: 1;"><i class="icon add"></i></button> </div> </div> </div> <div class="js-order-breakdown" style="font-size: 0.95rem; margin-bottom: var(--standard-gap); display: none;"> <hr style="border: 0; border-top: 1px solid rgba(var(--color-border-subtle), 1); margin: 0 0 15px 0;"> <div style="display: flex; justify-content: space-between; align-items: center;"> <span style="font-weight: 700;">Total due today</span> <span style="font-weight: 800;" class="js-breakdown-total">$0.00</span> </div> </div> </div> </div> <div class="button-group plan-card-cta"> <button type="submit" class="button theme plan-submit-btn" data-plan="featured" style="flex: 1;"> <i class="icon shopping-cart"></i> <span>Add to Cart & Upgrade</span> </button> </div> <div class="pricing-card__subtext">One-time payment. No recurring fees.</div> </label> </div> </form> <div class="preview-section"> <h3 id="preview-title" style="text-align: center; margin: 0 0 var(--standard-gap-small) 0;">Featured Listing Preview</h3> <p id="preview-desc" class="small-text text-muted" style="text-align: center; margin: 0 0 var(--standard-gap) 0;">This is how this site will appear in search results with the Premium Featured plan.</p> <div class="card" style="padding: 0.5rem var(--standard-gap); margin-bottom: 0;"> <div id="preview-featured"> <div class="search-result-card featured "> <div class="result-main-content"> <div class="result-body"> <h3 class="result-title"> <a href="https://windowcleaningservices.com.au/servicearea/vaucluse/" class="result-title-link" target="_blank" rel="noopener" title="Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window"> <span class="line-clamp-2">Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window</span> </a> <span class="user-badge featured icon-only ms-sm" title="Featured Listing ()"><i class="icon diamond"></i></span> </h3> <p class="result-description">Professional, streak-free window cleaning across Bondi, Coogee, Randwick, Double Bay & all Sydney Eastern Suburbs. From $13 per window. Free quotes. 5-star rated.</p> </div> <div class="result-header"> <div class="resource-stats "> <div class="vote-group"> <a href="/signin" class="button light micro vote-action-btn" title="Sign in to vote" aria-label="Sign in to upvote" > <i class="icon arrow-up"></i> </a> <span class="net-score" data-token="236ts" style="color: rgba(var(--color-text), 0.45); display: none;">0</span> <a href="/signin" class="button light micro vote-action-btn" title="Sign in to vote" aria-label="Sign in to downvote" > <i class="icon arrow-down"></i> </a> </div> <a href="/signin" class="button transparent light micro like-action-btn" title="Sign in to like" aria-label="Sign in to like website" > <i class="icon heart"></i> <span class="stat-count like-count" style="display: none">0</span> </a> </div> <span class="result-site-name"> <a href="/236ts/sydney-window-cleaning-eastern-suburbs-specialists-from-title3window" title="View Listing Details for https://windowcleaningservices.com.au/servicearea/vaucluse/" style="min-width: 0;"> <span style="display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">windowcleaningservices.com.au</span> </a> </span> <span class="result-separator">·</span> <span class="result-category"> <a href="/home/cleaning_services/window_cleaning">Window Cleaning</a> </span> <a href="/236ts/sydney-window-cleaning-eastern-suburbs-specialists-from-title3window" class="button transparent light micro details-link" title="View Listing Details"><span>Details</span></a> </div> <div class="result-footer"> <div class="keyword-pills"> <a href="/?q=window+cleaning+Sydney" class="keyword-pill">window cleaning Sydney</a> <a href="/?q=window+cleaner+Eastern+Suburbs" class="keyword-pill">window cleaner Eastern Suburbs</a> <a href="/?q=window+cleaning+Bondi" class="keyword-pill">window cleaning Bondi</a> <a href="/?q=window+cleaning+Coogee" class="keyword-pill">window cleaning Coogee</a> </div> </div> </div> <div class="result-screenshot"> <a href="https://windowcleaningservices.com.au/servicearea/vaucluse/" class="screenshot-wrap large theme" target="_blank" rel="noopener" title="Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window"> <div class="screenshot-skeleton img-skeleton "><i class="icon image"></i></div> <img src="/236ts/screenshot.webp" alt="Screenshot of Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window" loading="lazy"> </a> </div> </div> </div> <div id="preview-standard" style="display: none;"> <div class="search-result-card "> <div class="result-main-content"> <div class="result-body"> <h3 class="result-title"> <a href="https://windowcleaningservices.com.au/servicearea/vaucluse/" class="result-title-link" target="_blank" rel="noopener" title="Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window"> <span class="line-clamp-2">Sydney Window Cleaning | Eastern Suburbs Specialists from <title>3/window</span> </a> </h3> <p class="result-description">Professional, streak-free window cleaning across Bondi, Coogee, Randwick, Double Bay & all Sydney Eastern Suburbs. From $13 per window. Free quotes. 5-star rated.</p> </div> <div class="result-header"> <div class="resource-stats "> <div class="vote-group"> <a href="/signin" class="button light micro vote-action-btn" title="Sign in to vote" aria-label="Sign in to upvote" > <i class="icon arrow-up"></i> </a> <span class="net-score" data-token="236ts" style="color: rgba(var(--color-text), 0.45); display: none;">0</span> <a href="/signin" class="button light micro vote-action-btn" title="Sign in to vote" aria-label="Sign in to downvote" > <i class="icon arrow-down"></i> </a> </div> <a href="/signin" class="button transparent light micro like-action-btn" title="Sign in to like" aria-label="Sign in to like website" > <i class="icon heart"></i> <span class="stat-count like-count" style="display: none">0</span> </a> </div> <span class="result-site-name"> <a href="/236ts/sydney-window-cleaning-eastern-suburbs-specialists-from-title3window" title="View Listing Details for https://windowcleaningservices.com.au/servicearea/vaucluse/" style="min-width: 0;"> <span style="display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">windowcleaningservices.com.au</span> </a> </span> <span class="result-separator">·</span> <span class="result-category"> <a href="/home/cleaning_services/window_cleaning">Window Cleaning</a> </span> <a href="/236ts/sydney-window-cleaning-eastern-suburbs-specialists-from-title3window" class="button transparent light micro details-link" title="View Listing Details"><span>Details</span></a> </div> <div class="result-footer"> <div class="keyword-pills"> <a href="/?q=window+cleaning+Sydney" class="keyword-pill">window cleaning Sydney</a> <a href="/?q=window+cleaner+Eastern+Suburbs" class="keyword-pill">window cleaner Eastern Suburbs</a> <a href="/?q=window+cleaning+Bondi" class="keyword-pill">window cleaning Bondi</a> <a href="/?q=window+cleaning+Coogee" class="keyword-pill">window cleaning Coogee</a> </div> </div> </div> </div> </div> </div> </div> </div> </div> <style> .js-year-input::-webkit-inner-spin-button, .js-year-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } </style> <script> window.PLAN_PRICING = { basePrice: 24, baseExpressPrice: 12, discountPercent: 0, discountAmount: 0 }; </script> <footer class="footer" role="contentinfo" aria-label="Site Footer"> <div class="footer-content"> <div class="footer-logo"> <a class="logo-text" href="/" aria-label="Viesearch Homepage" title="Viesearch - Community Powered Search">Viesearch</a> </div> <nav class="footer-links small-text" aria-label="Footer Navigation"> <ul> <li><a href="/about" title="About Viesearch">About</a></li> <li><a href="/privacy" title="Viesearch Privacy Policy">Privacy</a></li> <li><a href="/terms" title="Viesearch Terms of Use">Terms</a></li> <li><a href="/api" title="Viesearch API Documentation">API</a></li> <li><a href="/help" title="Help & Support">Help</a></li> <li><a href="/contact" title="Contact Viesearch">Contact</a></li> </ul> </nav> <div class="footer-copyright small-text"> <span>© 2004-2026 Viesearch. All rights reserved.</span> </div> </div> </footer> <div class="overlay" id="overlay"></div> <button class="button theme back-to-top" aria-label="Back to top"> <i class="icon up"></i> </button> <script type="module">import '/script.js';</script> <script type="module"> import { handleForm, FormUtils, confirmModal, formatBogoTimeRemaining } from '/script.js'; // Dynamic price calculation const updateDynamicPrice = (container, years) => { if (!window.PLAN_PRICING) return; const { basePrice, discountPercent, discountAmount } = window.PLAN_PRICING; let finalPrice = basePrice * years; let multiYearDiscount = 0; if (years > 1) { multiYearDiscount = Math.min(years * 0.025, 0.5); // Cap at 50% finalPrice = finalPrice * (1 - multiYearDiscount); } if (discountPercent > 0) { finalPrice = finalPrice * (1 - discountPercent); } else if (discountAmount > 0) { finalPrice = Math.max(0, finalPrice - discountAmount); } const priceValue = container.querySelector('.js-dynamic-price-value'); const originalPrice = container.querySelector('.js-dynamic-price-original'); const savingsDisplay = container.querySelector('.js-dynamic-savings-display'); if (priceValue) { const perYear = finalPrice / years; priceValue.textContent = `$${perYear.toFixed(2)}`; if (originalPrice) { if (years > 1 || discountPercent > 0 || discountAmount > 0) { originalPrice.style.display = 'inline-block'; } else { originalPrice.style.display = 'none'; } } } if (savingsDisplay) { if (years > 1) { const totalSavings = (basePrice * years) - finalPrice; const displayPercent = Number((multiYearDiscount * 100).toFixed(1)); let savingsText = `Save $${totalSavings.toFixed(2)}`; if (discountPercent > 0 || discountAmount > 0) { savingsText += ` (additional ${displayPercent}% off)`; } else { savingsText += ` (${displayPercent}% off)`; } savingsDisplay.innerHTML = `<span style="font-weight: 700; color: rgb(var(--color-green));">${savingsText}</span>`; savingsDisplay.style.display = 'block'; } else { savingsDisplay.style.display = 'none'; } } // Update new order breakdown component const breakdown = container.querySelector('.js-order-breakdown'); if (breakdown) { if (years > 1) { breakdown.style.display = 'block'; const totalEl = breakdown.querySelector('.js-breakdown-total'); if (totalEl) totalEl.textContent = `$${finalPrice.toFixed(2)}`; } else { breakdown.style.display = 'none'; } } }; const initPlanForms = () => { const forms = document.querySelectorAll('.plan-upgrade-form'); forms.forEach(form => { const planOptions = form.querySelectorAll('.pricing-card'); const planInputs = form.querySelectorAll('input[name="plan"]'); const formFields = [ { name: 'token', required: true }, { name: 'plan', required: true }, { name: 'featuredYears', required: false } ]; const featuredYearsConfig = document.getElementById('featured-years-config'); const resetAllCards = () => { planOptions.forEach(card => { card.classList.remove('active'); }); }; const activateCard = (planValue) => { resetAllCards(); const radio = form.querySelector(`input[name="plan"][value="${planValue}"]`); if (radio) radio.checked = true; const card = radio ? radio.closest('.pricing-card') : null; if (!card) return; card.classList.add('active'); const featuredPreview = document.getElementById('preview-featured'); const standardPreview = document.getElementById('preview-standard'); const previewTitle = document.getElementById('preview-title'); const previewDesc = document.getElementById('preview-desc'); if (featuredPreview && standardPreview && previewTitle) { const isTour = window.VIESEARCH_CONFIG?.IS_ACTIVE_TOUR === true; const siteRef = isTour ? 'this site' : 'your site'; if (planValue === 'featured') { featuredPreview.style.display = 'block'; standardPreview.style.display = 'none'; previewTitle.textContent = 'Featured Listing Preview'; if (previewDesc) previewDesc.textContent = `This is how ${siteRef} will appear in search results with the Premium Featured plan.`; } else { featuredPreview.style.display = 'none'; standardPreview.style.display = 'block'; previewTitle.textContent = planValue === 'express' ? 'Express Listing Preview' : 'Free Listing Preview'; if (previewDesc) { previewDesc.textContent = planValue === 'express' ? `This is how ${siteRef} will appear in search results with the Priority Express plan.` : `This is how ${siteRef} will appear in search results with the Basic Free plan.`; } } } }; form.querySelectorAll('.plan-submit-btn').forEach(btn => { btn.addEventListener('click', async (e) => { form.querySelectorAll('.plan-submit-btn').forEach(b => b.setAttribute('type', 'button')); btn.setAttribute('type', 'submit'); const planValue = btn.getAttribute('data-plan'); if (planValue) { activateCard(planValue); if (planValue === 'free') { e.preventDefault(); const pendingCount = window.VIESEARCH_CONFIG?.PENDING_COUNT || "500"; const rejectionRate = window.VIESEARCH_CONFIG?.REJECTION_RATE || 82; const averageDailySubmit = window.VIESEARCH_CONFIG?.AVERAGE_DAILY_SUBMIT || "0.0"; const approvedCount = window.VIESEARCH_CONFIG?.APPROVED_COUNT || "0"; const rejectedCount = window.VIESEARCH_CONFIG?.REJECTED_COUNT || "0"; const banner = document.getElementById('fast-action-banner'); const submittedAtStr = banner ? banner.getAttribute('data-submitted-at') : null; const submittedAt = submittedAtStr ? parseInt(submittedAtStr, 10) : null; const duration = 15 * 60 * 1000; const isFastActionActive = submittedAt && (Date.now() - submittedAt < duration); const isBogoActive = Boolean(window.BOGO_SALE_ENDS && window.BOGO_SALE_ENDS > Date.now()); let couponNudge = ''; const bogoDuration = formatBogoTimeRemaining(window.BOGO_SALE_ENDS); const bogoOfferText = (bogoDuration && bogoDuration !== 'expired' && bogoDuration !== 'less than a minute') ? `For the next ${bogoDuration} only, all Featured plans are Buy-One-Year-Get-One-Free!` : 'All Featured plans are Buy-One-Year-Get-One-Free!'; if (isFastActionActive) { couponNudge = ` <div style="display: flex; flex-direction: column; gap: 8px; margin-top: 12px;"> <div class="alert info" style="margin: 0; padding: 10px; font-size: 0.85rem; display: block; text-align: left;"> <i class="icon party"></i> <strong>Introductory Offer:</strong> Activate now using either Express or Featured to save 30% automatically! Coupon <strong style="background: rgba(var(--color-theme), 0.2); padding: 2px 6px; border-radius: 4px; user-select: all;">OFFER-7X9B</strong> will be applied at checkout. </div> ${isBogoActive ? ` <div class="alert info" style="margin: 0; padding: 10px; font-size: 0.85rem; display: block; text-align: left;"> <i class="icon star" style="width: 14px; height: 14px; margin-right: 4px; vertical-align: middle; transform: translateY(-1px);"></i> <strong>Bonus:</strong> ${bogoOfferText} Checkout now to get your time doubled. </div> ` : ''} </div> `; } else if (isBogoActive) { couponNudge = ` <div class="alert info" style="margin-top: 12px; margin-bottom: 0; padding: 10px; font-size: 0.85rem; display: block; text-align: center;"> <i class="icon star" style="width: 14px; height: 14px; margin-right: 4px; vertical-align: middle; transform: translateY(-1px);"></i> <strong>Special Offer:</strong> ${bogoOfferText} Checkout now to get your time doubled. </div> `; } const modalHtml = ` <div style="text-align: left; margin-top: 15px;"> <p style="margin-bottom: 10px; line-height: 1.5;">Since 2004, we have averaged <strong>${averageDailySubmit}</strong> submissions every day and it may be a long time before we review your website.</p> <p style="margin-bottom: 10px; line-height: 1.5;">Our free text listing rejection ratio is over <strong>${rejectionRate}%</strong>. (<strong>${approvedCount}</strong> approved, <strong>${rejectedCount}</strong> rejected)</p> <p style="margin-bottom: 10px; line-height: 1.5;"><strong>${pendingCount}</strong> sites are waiting to be reviewed. Featured and Express submissions completely bypass the queue and receive guaranteed instant indexing.</p> <p style="margin-bottom: 0; line-height: 1.5;">Featured and Express listings help keep Viesearch completely ad-free!</p> ${couponNudge} </div> `; const confirmed = await confirmModal( 'Are you sure you want to wait in line?', modalHtml, { confirmText: 'Activate Now', cancelText: "Wait in Line", cancelValue: 'submit_free', type: 'primary' } ); if (confirmed === true) { const secondModalHtml = ` <div style="text-align: left; margin-top: 15px;"> <p style="margin-bottom: 10px; line-height: 1.5;"><strong>Express activation</strong> skips the queue and guarantees instant indexing into our search results.</p> <p style="margin-bottom: 15px; line-height: 1.5;"><strong>Featuring it</strong> gives you the same instant indexing, but also places your website link directly on our homepage, at the top of your specific category, and across the top of relevant search results.</p> ${couponNudge} </div> `; const secondConfirm = await confirmModal( 'Which upgrade would you like?', secondModalHtml, { confirmText: 'Feature It', cancelText: 'Express Activate', cancelValue: 'express', type: 'primary' } ); if (secondConfirm === true) { activateCard('featured'); form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true })); } else if (secondConfirm === 'express') { activateCard('express'); form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true })); } } else if (confirmed === 'submit_free') { form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true })); } } } }); }); const banner = document.getElementById('fast-action-banner'); const timerSpan = document.getElementById('countdown-timer'); if (banner && timerSpan) { const submittedAtStr = banner.getAttribute('data-submitted-at'); const submittedAt = submittedAtStr ? parseInt(submittedAtStr, 10) : Date.now(); const duration = 15 * 60 * 1000; const endTime = submittedAt + duration; const updateTimer = () => { const now = Date.now(); const remaining = Math.max(0, endTime - now); if (remaining === 0) { const bogoBonus = document.getElementById('bogo-action-banner-bonus'); if (bogoBonus) bogoBonus.style.display = 'none'; if (window.BOGO_SALE_ENDS > Date.now()) { banner.style.display = 'block'; const bogoDuration = formatBogoTimeRemaining(window.BOGO_SALE_ENDS); const bogoOfferText = (bogoDuration && bogoDuration !== 'expired' && bogoDuration !== 'less than a minute') ? `For the next ${bogoDuration} only, all Featured plans are Buy-One-Year-Get-One-Free!` : 'All Featured plans are Buy-One-Year-Get-One-Free!'; banner.innerHTML = ` <div class="alert-content"> <div class="alert-text" style="text-align: center;"> <i class="icon star" style="width: 14px; height: 14px; margin-right: 4px; vertical-align: middle; transform: translateY(-1px);"></i> <strong>Special Offer:</strong> ${bogoOfferText} Checkout now to get your time doubled. </div> </div> `; } else { banner.style.display = 'none'; } if (window.PLAN_PRICING) { window.PLAN_PRICING.discountPercent = 0; window.PLAN_PRICING.discountAmount = 0; const expressContainer = document.getElementById('plan-card-express'); if (expressContainer) { const priceDiv = expressContainer.querySelector('.pricing-card__price'); if (priceDiv) priceDiv.innerHTML = `$${window.PLAN_PRICING.baseExpressPrice.toFixed(2)}<span>forever</span>`; } const featuredContainer = document.getElementById('plan-card-featured'); if (featuredContainer) { const priceDiv = featuredContainer.querySelector('.pricing-card__price'); if (priceDiv) priceDiv.innerHTML = `<span class="js-dynamic-price-value" style="font-size: inherit; color: inherit; font-weight: inherit;">$${window.PLAN_PRICING.basePrice.toFixed(2)}</span><span>/year</span>`; } document.querySelectorAll('.js-bulk-select').forEach(card => { const years = parseInt(card.getAttribute('data-value'), 10); let finalPrice = window.PLAN_PRICING.basePrice * years; if (years > 1) { finalPrice = finalPrice * (1 - Math.min(years * 0.025, 0.5)); } const priceDiv = card.querySelector('div'); if (priceDiv) priceDiv.innerHTML = `$${(finalPrice / years).toFixed(2)}<span style="font-size: 0.85rem; font-weight: 500; color: rgba(var(--color-text), 0.5); margin-left: 0.2rem;">/year</span>`; }); const featuredYearsInput = document.getElementById('featuredYears'); if (featuredContainer && featuredYearsInput) { updateDynamicPrice(featuredContainer, parseInt(featuredYearsInput.value, 10)); } } return; } banner.style.display = 'block'; const minutes = Math.floor(remaining / 60000); const seconds = Math.floor((remaining % 60000) / 1000); timerSpan.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; requestAnimationFrame(updateTimer); }; updateTimer(); } planOptions.forEach(card => { card.addEventListener('click', (e) => { if ( e.target.tagName === 'BUTTON' || e.target.tagName === 'SELECT' || e.target.tagName === 'OPTION' || e.target.tagName === 'INPUT' || e.target.closest('button') || e.target.closest('select') ) return; const radio = card.querySelector('input[name="plan"]'); if (radio) { activateCard(radio.value); } else if (card.id === 'plan-card-free') { resetAllCards(); card.classList.add('active'); const featuredPreview = document.getElementById('preview-featured'); const standardPreview = document.getElementById('preview-standard'); const previewTitle = document.getElementById('preview-title'); const previewDesc = document.getElementById('preview-desc'); if (featuredPreview && standardPreview && previewTitle) { featuredPreview.style.display = 'none'; standardPreview.style.display = 'block'; previewTitle.textContent = 'Standard Listing Preview'; const isTour = window.VIESEARCH_CONFIG?.IS_ACTIVE_TOUR === true; const siteRef = isTour ? 'this site' : 'your site'; if (previewDesc) previewDesc.textContent = `This is how ${siteRef} appears in search results with the Basic Free plan.`; } } }); }); planInputs.forEach(input => { input.addEventListener('change', () => { if (input.checked) activateCard(input.value); }); }); handleForm({ formSelector: form, endpoint: '/api/plan', fields: formFields, showSuccessAlert: false, onSuccess: (result) => { if (result.redirect) { window.location.href = result.redirect; return; } const article = form.closest('article') || form.closest('.plan-page'); document.querySelectorAll('.plan-upgrade-form').forEach(f => f.style.display = 'none'); const banner = document.getElementById('fast-action-banner'); if (banner) banner.remove(); const h1 = article.querySelector('h1'); const p = article.querySelector('p'); if (h1 && p) { h1.textContent = 'Plan Selected!'; p.textContent = result.message || 'Thank you for selecting your URL plan. Your submission is now in the review queue.'; } article.classList.add('plan-selected-success'); const listingHref = window.VIESEARCH_CONFIG?.LISTING_URL || `/${form.querySelector('input[name="token"]')?.value || ''}`; const primaryButton = result.isUnconfirmed ? `<a href="/" class="button theme"><i class="icon left"></i><span>Return Home</span></a>` : `<a class="button theme js-back-listing"><i class="icon left"></i><span>Back to Listing</span></a>`; const successMsg = document.createElement('div'); successMsg.className = 'submission-result success'; successMsg.innerHTML = ` <div class="button-group" style="justify-content: center;"> ${primaryButton} <a href="/submit" class="button"><span>Submit Another</span><i class="icon right"></i></a> </div> `; if (!result.isUnconfirmed) { successMsg.querySelector('.js-back-listing').href = listingHref; } article.appendChild(successMsg); } }); }); document.querySelectorAll('.js-year-picker').forEach(picker => { const input = picker.querySelector('.js-year-input'); const container = picker.closest('.pricing-card') || picker.closest('.form-group') || picker.parentElement; const bulkCards = picker.querySelectorAll('.js-bulk-select'); const display = picker.querySelector('.js-year-display'); const minusBtn = picker.querySelector('.js-year-minus'); const plusBtn = picker.querySelector('.js-year-plus'); bulkCards.forEach(card => { card.addEventListener('click', () => { const val = parseInt(card.dataset.value, 10); input.value = val; input.dispatchEvent(new Event('input')); }); }); if (minusBtn && plusBtn) { minusBtn.addEventListener('click', (e) => { e.preventDefault(); let val = parseInt(input.value, 10) || 1; if (val > 1) { input.value = val - 1; input.dispatchEvent(new Event('input')); } }); plusBtn.addEventListener('click', (e) => { e.preventDefault(); let val = parseInt(input.value, 10) || 1; const max = parseInt(input.max, 10) || 20; if (val < max) { input.value = val + 1; input.dispatchEvent(new Event('input')); } }); } input.addEventListener('input', () => { let val = parseInt(input.value, 10) || 1; const max = parseInt(input.max, 10); if (val > max) { val = max; input.value = max; } if (display) display.textContent = val; updateDynamicPrice(container, val); }); input.addEventListener('blur', () => { let val = parseInt(input.value, 10); const min = parseInt(input.min, 10) || 1; if (isNaN(val) || val < min) { input.value = min; input.dispatchEvent(new Event('input')); } }); // Initialize UI state input.dispatchEvent(new Event('input')); }); }; initPlanForms(); </script> </body> </html>