Working hours Mon–Fri: 10:00 – 18:00

SEO Glossary: 65+ Search Terms Defined A to Z

65+ SEO terms defined A to Z — from 301 redirect to zero-click search. Built for B2B teams getting up to speed on SEO vocabulary.

Search engine optimisation has a lot of jargon. This A-to-Z glossary covers 65+ terms B2B teams encounter when working with an SEO agency or doing SEO in-house. Each definition is one to three sentences, with practical context where relevant.

#

301 redirect
A permanent HTTP redirect that passes most link equity to the new URL. Use when permanently moving content to preserve rankings.
404 error
HTTP status code returned when a page is not found. Excessive 404s waste crawl budget and signal a maintenance problem.

A

Algorithm update
A change to Google's ranking algorithm. Major updates (core updates, helpful content) typically roll out 3-4 times per year.
Alt text
Text description of an image used by screen readers and Google Image search. Should describe the image and include relevant keywords naturally.
Anchor text
The clickable text of a hyperlink. Over-optimised anchor text (exact-match keywords across many links) can trigger Penguin-style penalties.
Authority
Trust signals Google associates with a domain or page. Built through quality content, backlinks from credible sources, and user engagement.

B

Backlink
A hyperlink from another site pointing to your site. Editorial backlinks from credible sources are one of the strongest ranking signals.
Black hat SEO
Tactics that violate Google's guidelines (private blog networks, cloaking, link buying). Risks manual penalty and ranking loss.
Bounce rate
Percentage of visitors who leave after viewing one page. Not a direct ranking factor, but high bounce rate often correlates with poor content match.
Breadcrumbs
Navigation showing a page's position in the site hierarchy. Schema markup (BreadcrumbList) enables rich result in SERP.

C

Cache
Stored copy of a page. Google's cached version may differ from your live page if it has not crawled recently.
Canonical tag
tells Google which URL is the authoritative version when duplicate or similar content exists across URLs.
Click-through rate (CTR)
Percentage of SERP impressions that result in a click. Improving title and meta description typically lifts CTR.
Content gap analysis
Identifying topics competitors cover that you do not. Tools like Ahrefs Content Gap or manual analysis using GSC + competitor scraping.
Conversion rate
Percentage of visitors who complete a desired action (form fill, demo request, signup). Higher CR multiplies SEO ROI.
Core Web Vitals
Google's set of user-experience metrics: LCP (loading), INP (interactivity), CLS (visual stability). Direct ranking factor since 2021.
Crawl budget
Number of URLs Googlebot will crawl on your site in a given timeframe. Large sites must prioritise high-value pages.
Crawler
Software that systematically browses the web. Google's crawler is Googlebot; others include Bingbot, Applebot, GPTBot.

D

Domain authority (DA)
Moz's proprietary 0-100 score predicting ranking ability. Often confused with Google's internal authority signals.
Duplicate content
Substantially similar content across multiple URLs. Hurts ranking when Google cannot identify the canonical version.

E

E-E-A-T
Experience, Expertise, Authoritativeness, Trustworthiness. Google's evaluation framework for content quality, especially YMYL topics.

F

Featured snippet
A SERP result with answer text extracted above standard results. Optimising for featured snippets typically requires direct question + concise answer.

G

GA4
Google Analytics 4, the current version of Google's analytics. Event-based model replacing Universal Analytics.
GSC
Google Search Console — free Google tool showing how your site performs in Search. Includes Search Analytics, Coverage, Core Web Vitals.

H

H1 tag
Main heading of a page. Should match the primary keyword cluster intent. Per Markin methodology, H1 is a clean 3-5 word marker, distinct from Title tag.
HTTPS
Encrypted HTTP. Google has used HTTPS as a ranking signal since 2014. All modern sites should be HTTPS-only with HSTS.
Headless CMS
Content management system that exposes content via API, decoupled from presentation. Examples: Contentful, Sanity, Strapi.
Hreflang
tag indicating language and regional targeting of alternate URLs. Critical for multi-country sites.

I

Index
Google's database of pages eligible to appear in search results. Pages not in the index cannot rank.
Internal linking
Hyperlinks between pages on the same domain. Strategic internal linking distributes authority and helps Google understand site structure.

J

JSON-LD
JavaScript Object Notation for Linked Data — Google's preferred format for structured data. Goes in the page or .

K

Keyword cluster
Group of related keywords that should be targeted together on one page. Per Markin methodology, each cluster has one marker and 5-15 LSI terms.
Keyword difficulty
Estimated competitiveness of ranking for a query. Tools like Ahrefs and Semrush each have their own KD score.
Keyword research
Process of identifying queries to target. Combines search volume, competition, intent classification, and business relevance.

L

LLM SEO
Optimising content to be cited by Large Language Models (ChatGPT, Perplexity, Claude, Gemini, AI Overviews). Often called Generative Engine Optimisation.
Latent Semantic Indexing (LSI)
Old IR concept referring to semantically related terms. In modern SEO, LSI loosely means topical breadth — covering related concepts within a topic.
Link equity
The ranking power passed via links. Internal and external links pass equity; nofollow attempts to block it.
Long-tail keyword
Multi-word query with lower search volume but higher specificity and conversion. Easier to rank, often better ROI.

M

Manual penalty
Action Google takes when reviewers identify guideline violations. Shows in GSC Manual Actions. Usually requires reconsideration request.
Markin methodology
Anton Markin's SEO framework: marker selection, keyword density, LSI breadth, anti-AI style. Popular in Russian-speaking SEO.
Meta description
tag. Not a ranking factor but affects SERP CTR. Recommended length 120-160 characters.
Mobile-first indexing
Google primarily uses the mobile version of a page for indexing and ranking. Active for all sites since 2019.

N

Nofollow
rel='nofollow' attribute telling Google not to pass link equity. Use for sponsored or user-generated links.

O

On-page SEO
Optimisation done on the page itself: title, meta, headings, content, internal links, schema.
Organic traffic
Visitors arriving from unpaid search results. Distinct from paid (ads), referral, direct, and social.

P

PageRank
Original Google ranking algorithm using link analysis. Concept still influences modern ranking via link equity.
Position 0
Featured snippet position above the standard #1 result. Can deliver high CTR or zero clicks depending on query.

Q

Query intent
What the user actually wants from a search. Classified as informational, navigational, transactional, or commercial investigation.

R

Rel canonical
Tag indicating the preferred URL when duplicate or similar content exists. See canonical tag.
Rich result
SERP listing with enhanced display (star ratings, FAQ accordion, sitelinks, image carousel). Powered by schema markup.
Robots.txt
File at /robots.txt that instructs crawlers which URLs to access. Cannot prevent indexing — only crawling.

S

SERP
Search Engine Results Page — the page Google returns for a query. Includes organic results, ads, rich results, knowledge panel.
Schema markup
Structured data using Schema.org vocabulary. Tells search engines about content meaning. Most commonly JSON-LD format.
Search volume
Estimated monthly searches for a query. Tools like Ahrefs, Semrush, Google Keyword Planner provide different estimates.
Sitemap
XML file listing site URLs to help crawlers discover content. Submit via GSC. WordPress generates automatically via SEO plugins.
Snippet
Text excerpt shown in SERP under the title. Usually meta description; sometimes Google pulls text from page content.
Structured data
Standardised format for providing information about a page. See schema markup.

T

Technical SEO
Backend optimisations: crawlability, indexability, site speed, Core Web Vitals, mobile-friendliness, structured data.
Title tag
tag — the clickable headline in SERP. Strongest on-page ranking signal. Recommended length 45-60 characters.</div> </div> <div class="glossary-entry"> <div class="term">Topical authority</div> <div class="def">Site's depth of coverage on a topic. Built by publishing comprehensive, expert content within a content cluster.</div> </div> </div> <div class="glossary-section" id="letter-U"></article><article class="godlf-card"><span class="godlf-card-icon"><svg width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor"><path d="m20 20-3.5-3.5" /></svg></span><h3>U</h3><div class="glossary-entry"> <div class="term">URL structure</div> <div class="def">How URLs are organised on a site. Flat, short, descriptive URLs typically rank better than deep, parameter-heavy ones.</div> </div> <div class="glossary-entry"> <div class="term">User experience (UX)</div> <div class="def">How users interact with your site. Affects ranking through Core Web Vitals, bounce rate, dwell time, conversion.</div> </div> </div> <div class="glossary-section" id="letter-V"></article><article class="godlf-card"><span class="godlf-card-icon"><svg width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor"><path d="M13 2 4 14h7l-1 8 9-12h-7z" /></svg></span><h3>V</h3><div class="glossary-entry"> <div class="term">Voice search</div> <div class="def">Searches initiated by voice (Siri, Alexa, Google Assistant). Tends to favour conversational long-tail queries and featured snippets.</div> </div> </div> <div class="glossary-section" id="letter-X"></article><article class="godlf-card"><span class="godlf-card-icon"><svg width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5" /></svg></span><h3>X</h3><div class="glossary-entry"> <div class="term">XML sitemap</div> <div class="def">Sitemap file in XML format. See sitemap.</div> </div> </div> <div class="glossary-section" id="letter-Y"></article><article class="godlf-card"><span class="godlf-card-icon"><svg width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor"><path d="M4 12h8M4 18V6M12 18V6M17 10v8M17 10c2 0 3 1 3 2s-1 2-3 2" /></svg></span><h3>Y</h3><div class="glossary-entry"> <div class="term">YMYL</div> <div class="def">Your Money or Your Life — content categories (medical, financial, legal) where Google applies stricter E-E-A-T evaluation.</div> </div> </div> <div class="glossary-section" id="letter-Z"></article><article class="godlf-card"><span class="godlf-card-icon"><svg width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor"><path d="M3 12h4l3 8 4-16 3 8h4" /></svg></span><h3>Z</h3><div class="glossary-entry"> <div class="term">Zero-click search</div> <div class="def">SERP impression where the user does not click any result, often because Google's rich result or AI Overview answered the query directly.</div> </div> </div> </div></article></div></div></div> </div> </div> </section> <section class="god-section god-process" id="process"> <div class="container"> <h2 class="section-title">How it works</h2> <div class="god-process-steps"> <div class="god-step"> <div class="god-step-num">1</div> <div class="god-step-body"> <div class="step-title">Browse alphabetically</div> <div class="step-desc"></div> </div> </div> <div class="god-step"> <div class="god-step-num">2</div> <div class="god-step-body"> <div class="step-title">Read the definitions</div> <div class="step-desc"></div> </div> </div> <div class="god-step"> <div class="god-step-num">3</div> <div class="god-step-body"> <div class="step-title">Use in your own work</div> <div class="step-desc"></div> </div> </div> <div class="god-step"> <div class="god-step-num">4</div> <div class="god-step-body"> <div class="step-title">Suggest a missing term</div> <div class="step-desc"></div> </div> </div> </div> </div> </section> <section id="section-faq-content" class="god-section"> <div class="container"> <div class="faq_list"> <div class="faq_ittem active"> <div class="ask"> <div class="icon"> -</div> <div class="til">Who is this glossary for?</div> </div> <div class="reqest"> <p>B2B teams working with an SEO agency or doing SEO in-house. Founders, marketing managers, and product teams typically use it as a primer before kicking off an SEO programme. We deliberately kept definitions short and practical rather than academic.</p> </div> </div> <div class="faq_ittem"> <div class="ask"> <div class="icon"> +</div> <div class="til">How often is the glossary updated?</div> </div> <div class="reqest"> <p>We update the glossary every few months. SEO terminology evolves slowly, but Google's algorithm updates and the rise of LLM SEO (Generative Engine Optimisation) introduce new terms over time.</p> </div> </div> <div class="faq_ittem"> <div class="ask"> <div class="icon"> +</div> <div class="til">Can I link to or quote from this glossary?</div> </div> <div class="reqest"> <p>Yes, no attribution required. If you find it useful and want to credit us, a link to /seo-tools/seo-glossary/ is appreciated but not necessary.</p> </div> </div> <div class="faq_ittem"> <div class="ask"> <div class="icon"> +</div> <div class="til">Why is term X missing?</div> </div> <div class="reqest"> <p>We focused on terms B2B teams actually encounter day-to-day. Highly technical or rarely-used terms were left out to keep the glossary practical. Email info@development-web.com if there is a term you think should be added.</p> </div> </div> </div> </div> </section> <section class="god-section god-upsell"> <div class="container"> <h2 class="section-title">Related free SEO tools</h2> <div class="god-upsell-grid"> <div class="god-upsell-item"> <div class="up-title"><a href="/seo-tools/">All SEO Tools</a></div> <div class="up-desc"></div> <a href="/seo-tools/" class="up-link">Learn more →</a> </div> <div class="god-upsell-item"> <div class="up-title"><a href="/seo-tools/serp-preview-tool/">SERP Preview</a></div> <div class="up-desc"></div> <a href="/seo-tools/serp-preview-tool/" class="up-link">Learn more →</a> </div> <div class="god-upsell-item"> <div class="up-title"><a href="/seo-tools/schema-markup-generator/">Schema Generator</a></div> <div class="up-desc"></div> <a href="/seo-tools/schema-markup-generator/" class="up-link">Learn more →</a> </div> <div class="god-upsell-item"> <div class="up-title"><a href="/seo-tools/meta-description-checker/">Meta Description Checker</a></div> <div class="up-desc"></div> <a href="/seo-tools/meta-description-checker/" class="up-link">Learn more →</a> </div> <div class="god-upsell-item"> <div class="up-title"><a href="/seo-tools/seo-roi-calculator/">SEO ROI Calculator</a></div> <div class="up-desc"></div> <a href="/seo-tools/seo-roi-calculator/" class="up-link">Learn more →</a> </div> </div> </div> </section> <span id="contact" class="god-anchor" aria-hidden="true"></span> <section id="ms15"> <div class="container"> <div class="row big-form"> <!-- Левая колонка --> <div class="col-lg-5 col-12 big-form-left"> <p>Want this done for you?</p> <p class="bf-sub">Pipeline-First B2B SaaS SEO • deployed 260605-gloss</p> <div class="bf-brief-actions"> <a class="bf-brief-link" href="https://development-web.com/wp-content/themes/VZOR/directory/brif.pdf" rel="alternate" download="brief-Global-One-Digital"> <img src="https://development-web.com/wp-content/themes/VZOR/img/download-brif-white.png" alt="" aria-hidden="true" loading="lazy" decoding="async"> Download brief </a> <a class="bf-brief-link print-doc" href="javascript:(print());"> <img src="https://development-web.com/wp-content/themes/VZOR/img/printer-white.png" alt="" aria-hidden="true" loading="lazy" decoding="async"> Print brief </a> </div> <div class="bf-illustration-wrap"> <img src="https://development-web.com/wp-content/themes/VZOR/img/order-a-website-hand.webp" alt="" class="bf-illustration" width="639" height="679" loading="eager" decoding="async"> </div> </div> <!-- Правая колонка: Форма --> <div class="col-lg-7 col-12"> <p>Choose the most convenient way to contact us:</p> <div class="bf-socials"> <button type="button" class="bf-channel circle" data-channel="phone" aria-label="Phone"> <img src="https://development-web.com/wp-content/themes/VZOR/img/white-phon.png" alt="Phone" width="24" height="24" loading="lazy" decoding="async"> </button> <button type="button" class="bf-channel circle" data-channel="telegram" aria-label="Telegram"> <img src="https://development-web.com/wp-content/themes/VZOR/img/telegram-white.png" alt="Telegram" width="24" height="24" loading="lazy" decoding="async"> </button> <button type="button" class="bf-channel circle" data-channel="whatsapp" aria-label="WhatsApp"> <img src="https://development-web.com/wp-content/themes/VZOR/img/whatsapp-white.png" alt="WhatsApp" width="24" height="24" loading="lazy" decoding="async"> </button> <button type="button" class="bf-channel circle" data-channel="viber" aria-label="Viber"> <img src="https://development-web.com/wp-content/themes/VZOR/img/viber-white.png" alt="Viber" width="24" height="24" loading="lazy" decoding="async"> </button> <button type="button" class="bf-channel circle" data-channel="skype" aria-label="Skype"> <img src="https://development-web.com/wp-content/themes/VZOR/img/skype-white.png" alt="Skype" width="24" height="24" loading="lazy" decoding="async"> </button> <button type="button" class="bf-channel meet" data-channel="meet" aria-pressed="true"> <img src="https://development-web.com/wp-content/themes/VZOR/img/views_ico.png" alt="" aria-hidden="true" loading="lazy" decoding="async"> <span>Personal meeting</span> </button> </div> <script> (function(){ var wrap = document.querySelector('#ms15 .bf-socials'); if(!wrap) return; var btns = wrap.querySelectorAll('.bf-channel'); // По умолчанию активируем "Личная встреча" var def = wrap.querySelector('.bf-channel.meet'); if(def){ def.classList.add('is-active'); } btns.forEach(function(b){ b.addEventListener('click', function(){ btns.forEach(function(x){ x.classList.remove('is-active'); x.removeAttribute('aria-pressed'); }); b.classList.add('is-active'); b.setAttribute('aria-pressed','true'); }); }); })(); </script> <form action="#" method="post" class="bf-form"> <div class="col-12"> <label for="option-big-form">Which service do you need?</label><br> <select name="option-big-form" class="input_form container" id="option-big-form"> <option>SEO Glossary</option> <option>SEO promotion</option> <option>SEO audit</option> <option>Technical optimisation</option> <option>Content and semantics</option> <option>Link building</option> <option>Something else</option> </select> <input type="hidden" name="page_topic" value="SEO Glossary"> <input type="hidden" name="page_url" value="https://development-web.com/seo-tools/seo-glossary/"> </div> <div class="form_big-blok-line"> <div class="row col-12"> <div class="col-lg-12 col-12"> <label for="name-big-form">Your name:</label><br> <input type="text" name="name" id="name-big-form" class="input_form container" placeholder="John Smith"> </div> <div class="col-lg-12 col-12"> <label for="tel-big-form">Your phone:</label><br> <input type="tel" name="tel" required class="input_form container" id="tel-big-form" placeholder="+1 (___) ___‑__‑__"> </div> </div> </div> <div class="form_big-blok-line"> <div class="row col-12"> <div class="col-lg-12 col-12"> <label for="email">Your email (optional):</label> <input type="email" name="email" id="email" class="input_form container" placeholder="youremail@mail.com"> </div> <div class="col-lg-12 col-12"> <label for="input__file">Attach brief (optional)</label> <div class="input__wrapper"> <input name="file" type="file" id="input__file" class="input input__file"> <label for="input__file" id="tz-min-form" class="input__file-button"> <img class="input__file-icon" src="https://development-web.com/wp-content/themes/VZOR/img/upload-brif.png" alt="" aria-hidden="true" loading="lazy" decoding="async"> <span class="input__file-button-text">Your Brief</span> </label> </div> </div> </div> </div> <div class="form_big-blok-line"> <span> <label for="text-big-form">Your message (optional):</label><br> <textarea name="message" class="text-big col-12 input_form auto-size" id="text-big-form" placeholder="Type your message"></textarea> </span> </div> <p class="center"> <input id="remember" class="checkbox" type="checkbox" checked> <label for="remember"><span class="text-approval">I agree to the <a href="https://development-web.com/privacy/" target="_blank" rel="noopener">Privacy Policy</a></span></label> </p> <div class="form_big-blok-line"> <button type="submit" class="button-color form-button">SEND</button> </div> </form> </div> </div> </div> </section> <!-- Scroll to top button --> <button id="god-scroll-top" aria-label="Scroll to top" style="display:none;position:fixed;bottom:32px;right:32px;z-index:9999; width:48px;height:48px;border-radius:50%;border:none;cursor:pointer; background:linear-gradient(180deg,#4158D0 0%,#CD5BB9 100%); color:#fff;font-size:22px;box-shadow:0 4px 16px rgba(65,88,208,.35); transition:.3s;">↑</button> <script> (function(){ var btn = document.getElementById('god-scroll-top'); if (!btn) return; window.addEventListener('scroll', function(){ btn.style.display = window.scrollY > 400 ? 'block' : 'none'; }, {passive:true}); btn.addEventListener('click', function(){ window.scrollTo({top:0, behavior:'smooth'}); }); })(); </script> <section class="god-analyzer-cta" style="background:#F7F9FF;padding:52px 0;"> <div class="container" style="max-width:900px;margin:0 auto;padding:0 20px;"> <div style="display:flex;gap:28px;align-items:center;flex-wrap:wrap;background:#fff;border:1px solid #E4EAFB;border-radius:16px;padding:30px 32px;"> <div style="flex:1;min-width:280px;"> <div style="display:inline-block;background:#EEF3FF;color:#548AEE;font:700 11px/1 Inter,Arial,sans-serif;letter-spacing:.07em;text-transform:uppercase;padding:6px 11px;border-radius:20px;margin-bottom:12px;"> Free tool </div> <h2 style="font:800 clamp(19px,2.1vw,25px)/1.3 Inter,Montserrat,Arial,sans-serif;color:#2A2B4B;margin:0 0 10px;"> See what is holding your own page back </h2> <p style="font-size:15px;line-height:1.65;color:#555;margin:0;"> Paste a URL and get about twenty checks on the live page — indexing, meta, headings, markup, speed. Every finding on screen, the fixes by email. </p> </div> <div style="flex:0 0 auto;"> <a href="https://development-web.com/site-analyzer/" style="display:inline-block;background:#548AEE;color:#fff;font:600 15px/1 Inter,Arial,sans-serif;padding:15px 30px;border-radius:30px;text-decoration:none;white-space:nowrap;"> Check my page → </a> </div> </div> </div> </section> <style> .god-lead-cta { background: linear-gradient(135deg, #2a2b4b 0%, #3a5298 100%); border-radius: 16px; padding: 32px; margin: 32px auto; max-width: 1200px; font-family: Inter, system-ui, sans-serif; color: white; } .god-lead-cta .glc-inner { display: grid; grid-template-columns: 1.2fr 1fr; gap: 32px; align-items: center; } @media (max-width: 768px){ .god-lead-cta .glc-inner { grid-template-columns: 1fr; } } .god-lead-cta .glc-tag { display: inline-block; background: rgba(255,255,255,.15); padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; } .god-lead-cta h3 { font-size: 26px; font-weight: 700; margin: 0 0 10px; line-height: 1.25; color: white; } .god-lead-cta p { font-size: 15px; line-height: 1.6; color: rgba(255,255,255,.85); margin: 0; } .god-lead-cta .glc-form { background: white; border-radius: 12px; padding: 22px; } .god-lead-cta .glc-form input { width: 100%; padding: 12px 14px; border: 1px solid #d4d8df; border-radius: 8px; font-size: 15px; box-sizing: border-box; margin-bottom: 10px; font-family: inherit; color: #2a2b4b; } .god-lead-cta .glc-form input:focus { border-color: #548AEE; outline: 0; } .god-lead-cta .glc-form button { width: 100%; background: #548AEE; color: white; border: none; padding: 13px; border-radius: 8px; font-size: 15px; font-weight: 700; cursor: pointer; } .god-lead-cta .glc-form button:hover { background: #3a6fce; } .god-lead-cta .glc-form button:disabled { background: #9ca3af; cursor: not-allowed; } .god-lead-cta .glc-hp { position: absolute; left: -9999px; } .god-lead-cta .glc-success { text-align: center; padding: 24px 12px; color: #166534; font-weight: 600; font-size: 16px; line-height: 1.5; } .god-lead-cta .glc-small { font-size: 12px; color: #6b7280; text-align: center; margin-top: 8px; } </style> <div class="god-lead-cta" id="god-lead-cta"> <div class="glc-inner"> <div> <div class="glc-tag">Free SEO audit</div> <h3>Get a free SEO audit</h3> <p>See exactly what is holding your B2B SaaS site back in organic search. We review technical SEO, content gaps, and competitor positioning — no strings attached.</p> </div> <div class="glc-form" id="glc-form-wrap"> <form id="glc-form" onsubmit="return glcSubmit(event)"> <input type="text" id="glc-name" placeholder="Your name" autocomplete="name"> <input type="email" id="glc-email" placeholder="Work email" required autocomplete="email"> <input type="text" id="glc-website" placeholder="Your website (e.g. yoursite.com)" autocomplete="url"> <input type="text" class="glc-hp" id="glc-hp" tabindex="-1" autocomplete="off" aria-hidden="true"> <button type="submit" id="glc-btn">Get my free audit</button> <div class="glc-small">No spam. We reply within one business day.</div> </form> </div> </div> </div> <script> function glcNormalizeUrl(v){ v=(v||'').trim(); if(!v)return ''; if(!/^https?:\/\//i.test(v))v='https://'+v; return v; } function glcSubmit(e){ e.preventDefault(); var btn=document.getElementById('glc-btn'); var hp=document.getElementById('glc-hp').value; if(hp){return false;} var compEl=document.getElementById('glc-competitor'); btn.disabled=true; btn.textContent='Sending…'; var payload={ name: document.getElementById('glc-name').value, email: document.getElementById('glc-email').value, website: glcNormalizeUrl(document.getElementById('glc-website').value), website_hp: hp, message: compEl ? ('Competitor to analyse: '+compEl.value) : '', source_tool: 'seo-glossary', source_category: 'seo', offer: 'Free SEO audit', source_url: window.location.href.split('?')[0], utm_source: new URLSearchParams(window.location.search).get('utm_source')||'', utm_medium: new URLSearchParams(window.location.search).get('utm_medium')||'', utm_campaign: new URLSearchParams(window.location.search).get('utm_campaign')||'', meta: { offer_type: 'audit' } }; var isCall = false; var calendly = 'https://calendly.com/atggbt/30min'; fetch('/wp-json/god/v1/leads/capture',{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) }).then(function(r){return r.json();}).then(function(d){ if(d.ok){ var msg; if(isCall && calendly){ var cal=calendly+'?name='+encodeURIComponent(payload.name)+'&email='+encodeURIComponent(payload.email); msg='<div style="font-size:18px;margin-bottom:14px">✓ Almost there — pick a time:</div><a href="'+cal+'" target="_blank" style="display:inline-block;background:#548AEE;color:white;padding:13px 28px;border-radius:8px;font-weight:700;text-decoration:none">Book your 30-min call →</a><div style="font-size:12px;color:#6b7280;margin-top:10px">A confirmation will land in your inbox.</div>'; // auto-open Calendly in new tab setTimeout(function(){window.open(cal,'_blank');},400); }else if(isCall){ msg='✓ Thanks! We received your request and will send you a booking link within one business day.'; }else{ msg='✓ Thanks! We received your request and will reply within one business day.'; } document.getElementById('glc-form-wrap').innerHTML='<div class="glc-success">'+msg+'</div>'; if(window.gtag)gtag('event','generate_lead',{source_tool:payload.source_tool,category:payload.source_category,offer_type:payload.meta.offer_type}); }else{ btn.disabled=false; btn.textContent='Try again'; alert(d.message||'Something went wrong. Please try again.'); } }).catch(function(){btn.disabled=false; btn.textContent='Try again'; alert('Network error. Please try again.');}); return false; } </script> </main> <footer class="footer-main" style=" background-image:url(https://development-web.com/wp-content/themes/VZOR/img/footer-fon.png);"> <div class="prefoter_section"> <div class="container"> <div class="left_block"> <p></p> </div> <div class="center_block"> <p></p> </div> </div> </div> <div class="bookmark_block"> <div class="container bookmark_grid"> <div class="bookmark_left"> <div class="bookmark_title">To keep our site, save it to your bookmarks</div> </div> <div class="bookmark_center"> <div class="heart_icon"><img src="https://development-web.com/wp-content/themes/VZOR/img/heart.png" alt="heart" loading="lazy" decoding="async"></div> <div class="heart_text">Add to bookmarks <span>(in your browser)</span></div> </div> <div class="bookmark_right"> <div class="kbd_help">Or press the shortcut</div> <div class="kbd_row"> <div class="kbd">Ctrl + D</div> <div class="kbd">⌘ + D</div> </div> </div> </div> </div> <div class="footer_section"> <div class="container"> <div class="first_line"> <div class="logo_block"> <a href="https://development-web.com/" class="custom-logo-link" rel="home" aria-label="Global One Digital"><img src="https://development-web.com/wp-content/themes/VZOR/img/logoG1.png" class="custom-logo" alt="Global One Digital" / loading="lazy" decoding="async"></a> <div class="brand-text brand-text--footer"> <div class="brand-title">Global One Digital</div> <div class="brand-subtitle">Digital agency for global growth</div> </div> </div> <div class="search_block"> <form action="/" method="get"> <input type="image" alt="Search" src="https://development-web.com/wp-content/themes/VZOR/img/search.png" /> <input type="text" name="s" id="search" value="" placeholder="Type what you need" /> </form> </div> <div class="files_block"> </div> <!-- phones removed to avoid duplication; show them only in footer_bottom --> <div class="phones_block" style="display:none;"></div> <!-- Контакты в верхней строке подвала, справа от поиска. --> <div class="footer_contacts footer_contacts--top"> <a class="fc fc-phone" href="tel:+995599288712" aria-label="Phone"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M6.62 10.79a15.053 15.053 0 006.59 6.59l2.2-2.2a1 1 0 011.01-.24c1.12.37 2.33.57 3.58.57a1 1 0 011 1V21a1 1 0 01-1 1C10.3 22 2 13.7 2 3a1 1 0 011-1h3.5a1 1 0 011 1c0 1.25.2 2.46.57 3.58a1 1 0 01-.24 1.01l-2.21 2.2z"/></svg> <span>+995 599 288 712</span> </a> <a class="fc fc-mail" href="mailto:info@development-web.com" aria-label="Email"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M20 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V6a2 2 0 00-2-2zm0 2v.01L12 13 4 6.01V6h16zM4 18V8.236l8 6.764 8-6.764V18H4z"/></svg> <span>info@development-web.com</span> </a> <a class="fc fc-tg" href="https://t.me/globalonedigital" target="_blank" rel="noopener nofollow" aria-label="Telegram"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M9.03 15.47l-.39 5.49c.56 0 .8-.24 1.09-.53l2.62-2.51 5.43 3.98c.99.55 1.69.26 1.95-.92l3.54-16.58.01-.01c.31-1.44-.52-2-1.48-1.65l-20.7 7.98c-1.41.55-1.39 1.33-.24 1.69l5.29 1.65L19.47 6.2c.58-.38 1.11-.17.68.21l-11.12 9.06z"/></svg> <span>@globalonedigital</span> </a> </div> </div> <!-- Quick Links --> <div class="footer_top_row"> <div class="quick_links" aria-label="Quick Links"> <ul class="quick_links__list"> <li><a href="#section-services-content">Services</a></li> <li><a href="#section-portfolio-content">Case Studies</a></li> <li><a href="#section-whuy-content">Approach</a></li> <li><a href="/tools/">Free marketing calculators</a></li> <li><a href="/blog/">Blog</a></li> <li><a href="/about/">About Us</a></li> <li><a href="/vacancies/">Careers</a></li> <li><a href="/contacts/">Contact</a></li> <li><a href="/sitemap/">Sitemap</a></li> <li><a href="/privacy/">Privacy Policy</a></li> </ul> </div> </div> <div class="last_line"> <div class="contact_block"> <div class="dop_info"></div> </div> <div class="menu_block"> <div class="menu_title">Marketing</div> <ul> <li><a href="/google-ads/">Google Ads</a></li> <li><a href="/meta-ads/">Meta Ads</a></li> <li><a href="/seo/">SEO</a></li> <li><a href="/seo-audit/">SEO Audit</a></li> <li><a href="/content-marketing/">Content Marketing</a></li> <li><a href="/smm/">SMM</a></li> <li><a href="/email-marketing/">Email Marketing</a></li> <li><a href="/pr/">PR</a></li> <li><a href="/web-analytics/">Web Analytics</a></li> </ul> </div> <div class="menu_block"> <div class="menu_title">Website development</div> <ul> <li><a href="/website-development/">Website development</a></li> <li><a href="/landing-page/">Landing page</a></li> <li><a href="/corporate-website/">Corporate website</a></li> <li><a href="/online-store/">Online store</a></li> <li><a href="/portals/">Portals</a></li> <li><a href="/mobile-apps/">Mobile apps</a></li> <li><a href="/bitrix-website/">Bitrix website</a></li> <li><a href="/wordpress-website/">WordPress website</a></li> <li><a href="/social-media-integration/">Social media</a></li> </ul> </div> <div class="menu_block"> <div class="menu_title">Programming</div> <ul> <li><a href="/maintenance/">Website support</a></li> <li><a href="/cms-migration/">CMS migration</a></li> <li><a href="/site-optimization/">Site optimization</a></li> <li><a href="/modernization/">Modernization</a></li> <li><a href="/maintenance/">Administration</a></li> <li><a href="/feature-extension/">Feature extension</a></li> </ul> </div> <div class="menu_block"> <div class="menu_title">Design</div> <ul> <li><a href="/website-redesign/">Website redesign</a></li> <li><a href="/mobile-apps/">Mobile apps</a></li> <li><a href="/android-apps/">Android apps</a></li> <li><a href="/ios-apps/">iOS apps</a></li> <li><a href="/app-maintenance/">App maintenance</a></li> <li><a href="/custom-components/">Custom components</a></li> <li><a href="/pwa-applications/">PWA applications</a></li> </ul> </div> <div class="menu_block"> <div class="menu_title">Business Automation Services</div> <ul> <li><a href="/marketing-automation/">Marketing Automation</a></li> <li><a href="/sales-process-automation/">Sales Process Automation</a></li> <li><a href="/customer-support-automation/">Customer Support Automation</a></li> <li><a href="/data-reporting-automation/">Data & Reporting Automation</a></li> <li><a href="/custom-business-automation/">Custom Business Automation</a></li> <li><a href="/ai-chatbot-development/">AI Chatbot Development</a></li> </ul> </div> <div class="menu_block menu_block--company"> <div class="menu_title">Company</div> <ul> <li><a href="/about/">About Us</a></li> <li><a href="/vacancies/">Careers</a></li> <li><a href="/contacts/">Contacts</a></li> <li><a href="/sitemap/">Sitemap</a></li> <li><a href="/privacy/">Privacy Policy</a></li> </ul> </div> <div class="socials_block"> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="Behance"> <img src="https://development-web.com/wp-content/themes/VZOR/img/behance.png" alt="Behance" loading="lazy" decoding="async"> </a> <a href="https://github.com/GlobalOneDigital" target="_blank" rel="noopener noreferrer me" aria-label="Global One Digital on GitHub"> <img src="https://development-web.com/wp-content/themes/VZOR/img/github.jpg" alt="GitHub" loading="lazy" decoding="async"> </a> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="Facebook"> <img src="https://development-web.com/wp-content/themes/VZOR/img/facebook.png" alt="Facebook" loading="lazy" decoding="async"> </a> <a href="https://global1digital.livejournal.com/" target="_blank" rel="noopener noreferrer me" aria-label="Global One Digital on LiveJournal"> <img src="https://development-web.com/wp-content/themes/VZOR/img/livejournal.png" alt="LiveJournal" loading="lazy" decoding="async"> </a> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="Pinterest"> <img src="https://development-web.com/wp-content/themes/VZOR/img/pinterest.png" alt="Pinterest" loading="lazy" decoding="async"> </a> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="Twitter"> <img src="https://development-web.com/wp-content/themes/VZOR/img/twitter.png" alt="Twitter" loading="lazy" decoding="async"> </a> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="Instagram"> <img src="https://development-web.com/wp-content/themes/VZOR/img/insta.png" alt="Instagram" loading="lazy" decoding="async"> </a> <a href="#" target="_blank" rel="nofollow noopener noreferrer" aria-label="RSS"> <img src="https://development-web.com/wp-content/themes/VZOR/img/rss.png" alt="RSS" loading="lazy" decoding="async"> </a> </div> <div class="mobile_last_block"> <a href="https://development-web.com/privacy/">Privacy Policy</a> <p>© 2026 Global One Digital. All rights reserved.</p> </div> <!-- Bottom copyright only — contacts moved to top row --> <div class="footer_bottom footer_bottom--mini"> <div class="copyright">© 2026 Global One Digital.</div> </div> </div> </div> </div> </footer> <!-- Global popups --> <div id="popup-calc" class="god-modal" aria-hidden="true" style="display:none;"> <div class="god-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="popup-calc-title" style="max-width:460px;"> <button class="god-modal__close" type="button" data-modal-close>×</button> <div class="god-modal__title" id="popup-calc-title" style="text-align:center;font-weight:800;font-size:22px;color:#2A2B4B;">Free consultation</div> <p style="text-align:center;color:#666;margin:8px 0 18px;font-size:14px;">Leave your contact and we will call you back to discuss your case. No obligations, no hard sell.</p> <form class="god-modal__form god-lead-form" data-offer="consultation" data-lang="en"> <div class="field" style="margin-bottom:12px;"><input type="text" name="name" required placeholder="Your name" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;"></div> <div class="field" style="margin-bottom:12px;"><input type="tel" name="phone" required placeholder="Phone or messenger" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;"></div> <div class="field" style="margin-bottom:10px;"><textarea name="message" rows="2" placeholder="Briefly about your task (optional)" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;resize:vertical;"></textarea></div> <input type="text" name="website_hp" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;"> <label class="agree" style="display:block;font-size:12px;color:rgba(255,255,255,.85);margin:6px 0 14px;"><input type="checkbox" required checked> I agree to the <a href="https://development-web.com/privacy/" target="_blank" rel="noopener">Privacy Policy</a></label> <button type="submit" class="btn-grad" style="width:100%;">Get consultation</button> <div class="god-lead-status" hidden style="text-align:center;padding:20px 10px;font-weight:600;color:#2A8A4A;font-size:16px;"></div> </form> </div> </div> <div id="popup-audit" class="god-modal" aria-hidden="true" style="display:none;"> <div class="god-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="popup-audit-title" style="max-width:480px;"> <button class="god-modal__close" type="button" data-modal-close>×</button> <div class="god-modal__title" id="popup-audit-title" style="text-align:center;font-weight:800;font-size:22px;color:#2A2B4B;">Free SEO audit</div> <p style="text-align:center;color:#666;margin:8px 0 18px;font-size:14px;">Leave your website and email. Within 2 business days you get a written review: what holds the site back in Google and what to fix first.</p> <form class="god-modal__form god-lead-form" data-offer="free_audit" data-lang="en" data-thanks="Thanks! The audit will land in your inbox within 2 business days."> <div class="field" style="margin-bottom:12px;"><input type="url" name="website" required inputmode="url" autocomplete="url" placeholder="Website: https://…" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;"></div> <div class="field" style="margin-bottom:12px;"><input type="email" name="email" required autocomplete="email" placeholder="Work email" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;"></div> <div class="field" style="margin-bottom:12px;"><input type="text" name="name" autocomplete="name" placeholder="Your name (optional)" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;"></div> <div class="field" style="margin-bottom:10px;"><textarea name="message" rows="2" placeholder="What to look at first: market, competitors, target queries (optional)" style="width:100%;padding:13px 16px;border:1px solid #D9E0EC;border-radius:10px;font-size:15px;resize:vertical;"></textarea></div> <input type="text" name="website_hp" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;"> <label class="agree" style="display:block;font-size:12px;color:rgba(255,255,255,.85);margin:6px 0 14px;"><input type="checkbox" required checked> I agree to the <a href="https://development-web.com/privacy/" target="_blank" rel="noopener">privacy policy</a></label> <button type="submit" class="btn-grad" style="width:100%;">Get my free audit</button> <div class="god-lead-status" hidden style="text-align:center;padding:20px 10px;font-weight:600;color:#2A8A4A;font-size:16px;"></div> <p style="text-align:center;color:rgba(255,255,255,.8);margin:14px 0 0;font-size:12px;">Need it right now? <a href="https://development-web.com/site-analyzer/" style="color:#fff;text-decoration:underline;">Run the instant page check</a></p> </form> </div> </div> <script> // Открытие попапов по атрибуту data-modal-open="#id" (function(){ function openModal(sel){ var m = document.querySelector(sel); if(!m) return; m.classList.add('is-active'); m.style.display = 'flex'; document.documentElement.classList.add('modal-open'); } function closeModal(node){ var m = node.closest('.god-modal'); if(!m) return; m.classList.remove('is-active'); m.style.display = 'none'; document.documentElement.classList.remove('modal-open'); } document.addEventListener('click', function(e){ var btn = e.target.closest('[data-modal-open]'); if(btn){ e.preventDefault(); var target = btn.getAttribute('data-modal-open'); var svc = btn.getAttribute('data-service'); if (target === '#popup-calc' && svc){ var t = document.getElementById('popup-calc-title'); if (t){ t.innerHTML = 'Order “' + svc + '”<br><span style="display:block;font-size:14px;font-weight:500;opacity:.85;margin-top:6px;">Fill the form and our manager will contact you shortly.</span>'; } } openModal(target); return; } if(e.target.matches('[data-modal-close]') || e.target.classList.contains('god-modal')){ e.preventDefault(); closeModal(e.target); } }); // Esc закрытие document.addEventListener('keydown', function(e){ if(e.key === 'Escape'){ var opened = document.querySelector('.god-modal.is-active'); if(opened){ opened.classList.remove('is-active'); document.documentElement.classList.remove('modal-open');} } }); // File-input → update .file-title with chosen filename (popups + main form) document.addEventListener('change', function(e){ if(e.target && e.target.matches('input[type="file"]')){ var wrap = e.target.closest('.file_b, .input__wrapper'); if(!wrap) return; var title = wrap.querySelector('.file-title, .input__file-button-text'); if(title){ title.textContent = (e.target.files && e.target.files.length) ? e.target.files[0].name : (title.dataset.original || title.textContent); } } }); })(); </script> <!-- Popup: Двухэкранный квиз --> <div id="popup-quiz" class="god-modal" aria-hidden="true" style="display:none;"> <div class="god-modal__dialog god-modal__dialog--wide" role="dialog" aria-modal="true" aria-labelledby="popup-quiz-title"> <button class="god-modal__close" type="button" data-modal-close>×</button> <div class="quiz"> <!-- Шаг 1 --> <div class="quiz__step quiz__step--1 is-active"> <div class="quiz__title" id="popup-quiz-title">Choose the required website type</div> <div class="quiz__cards"> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Corporate website"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/corporate-website.png" alt="Corporate website" loading="lazy" decoding="async"> <span class="quiz-card__title">Corporate website</span> </span> </label> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Landing page"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/landing-page.png" alt="Landing page" loading="lazy" decoding="async"> <span class="quiz-card__title">Landing page</span> </span> </label> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Online store"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/e-commerce.png" alt="Online store" loading="lazy" decoding="async"> <span class="quiz-card__title">Online store</span> </span> </label> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Business website"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/slide-1.png" alt="Business website" loading="lazy" decoding="async"> <span class="quiz-card__title">Business website</span> </span> </label> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Portal website"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/razrabotka-sajtov.png" alt="Portal website" loading="lazy" decoding="async"> <span class="quiz-card__title">Portal website</span> </span> </label> <label class="quiz-card"> <input type="radio" name="quiz_type" value="Mobile application"> <span class="quiz-card__body"> <img src="https://development-web.com/wp-content/themes/VZOR/img/order-a-website.png" alt="Mobile application" loading="lazy" decoding="async"> <span class="quiz-card__title">Mobile application</span> </span> </label> </div> <div class="quiz__actions"> <button class="btn-grad" data-quiz-next disabled>Continue</button> </div> </div> <!-- Шаг 2 --> <div class="quiz__step quiz__step--2"> <div class="quiz__title">Enter your details</div> <form class="quiz-form" id="quiz-form"> <input type="hidden" name="option-big-form" data-quiz-mirror value=""> <div class="bf-row"> <div class="bf-col"> <label>Your name:</label> <input type="text" name="name" placeholder="John Smith"> </div> <div class="bf-col"> <label>Your phone:</label> <input type="tel" name="tel" placeholder="+995 ___ ___‑__‑__"> </div> </div> <div class="bf-row"> <div class="bf-col"> <label>Your email:</label> <input type="email" name="email" placeholder="youremail@mail.com"> </div> <div class="bf-col file"> <label>Attach brief</label> <div class="file_b"> <input type="file" name="file"> <span class="file-title">Your brief</span> </div> </div> </div> <div class="bf-text"> <label>Your message:</label> <textarea name="message" placeholder="Type your message"></textarea> </div> <label class="bf-accept"><input type="checkbox" checked> I agree to the Privacy Policy</label> <button type="submit" class="btn-grad">Send</button> </form> </div> </div> </div> </div> <script> // Логика квиза (2 шага) (function(){ var quiz = document.getElementById('popup-quiz'); if(!quiz) return; var step1 = quiz.querySelector('.quiz__step--1'); var step2 = quiz.querySelector('.quiz__step--2'); var nextBtn = quiz.querySelector('[data-quiz-next]'); var radios = quiz.querySelectorAll('input[name="quiz_type"]'); var mirror = quiz.querySelector('[data-quiz-mirror]'); radios.forEach(function(r){ r.addEventListener('change', function(){ nextBtn.disabled = false; // радиокнопки лежат вне <form>, поэтому сами в запрос не попадают if (mirror) { mirror.value = r.value; } }); }); nextBtn && nextBtn.addEventListener('click', function(){ step1.classList.remove('is-active'); step2.classList.add('is-active'); }); })(); </script> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/VZOR/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script id="dcw-widget-js-extra"> var DCW_CONFIG = {"usernameTelegram":"globalonedigital","phoneIntl":"995599288712","phones":{"whatsapp":"995599288712","viber":"995599288712","call":"995599288712"},"email":"info@development-web.com","enabled":{"telegram":true,"whatsapp":true,"viber":false,"phone":true,"email":true},"iconPack":"bootstrap","position":"right","vertical":"bottom","offsetX":"20","offsetY":"24","rotateIntervalMs":"3000","autoHideOnScroll":"1","forceRotate":"1","mainColorful":"1","ctaEnabled":"1","ctaText":"Free Consultation","highlightLast":"1","reorderLast":"1","throttleMs":"800","analytics":{"datalayer":false,"gtag":true,"pixel":false,"eventName":"dcw_click"},"targeting":{"delaySec":0,"scrollPercent":0,"exitIntent":false,"minVisits":1},"ab":{"enabled":false,"mode":"auto","bCtaText":"","variants":[]},"metrika":{"id":"","goal":"dcw_click"},"iconBase":"https://development-web.com/wp-content/plugins/dc-contact-widgetV5/assets/icons/","lazy":{"enabled":true,"idleMs":0},"debug":"","wpContext":{"page_type":"page","post_id":342,"post_type":"page","taxonomy":"","term":"","locale":"ru_RU","timezone":"+03:00","currency":""},"presets":[],"extraChannels":{"instagram":{"enabled":false,"username":""},"messenger":{"enabled":false,"username":""},"imessage":{"enabled":false,"address":""},"facetime":{"enabled":false,"address":""},"yandextaxi":{"enabled":false},"bolt":{"enabled":false},"navigator":{"enabled":false,"label":"","lat":"","lng":""},"callback":{"enabled":false},"contact":{"enabled":false,"title":"\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u043d\u0430\u043c","subtitle":"\u041e\u0442\u0432\u0435\u0442\u0438\u043c \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f","emailTo":""}}}; var DCW_AJAX = {"url":"https://development-web.com/wp-admin/admin-ajax.php","nonce":"9ef7b28bcc","rest_url":"https://development-web.com/wp-json/dcw/v1/click","rest_nonce":"7d9ba9dbc1"}; //# sourceURL=dcw-widget-js-extra </script> <script id="dcw-widget-js" src="https://development-web.com/wp-content/plugins/dc-contact-widgetV5/assets/js/contact-widget.js?ver=1.0.0"></script> <script data-wp-strategy="defer" defer id="hostinger-reach-embed-js" src="https://cdn-reach.hostinger.com/js/embed.js"></script> <script defer id="js-intltel-js" src="https://cdn.jsdelivr.net/npm/intl-tel-input@18/build/js/intlTelInput.min.js"></script> <script defer id="js-scripts-js" src="https://development-web.com/wp-content/themes/VZOR/js/scripts.js?ver=1789417338"></script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://development-web.com/wp-includes/js/wp-emoji-release.min.js?ver=7.1.3"}} </script> <script type="module"> /*! This file is auto-generated */ var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,r){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!r(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,r){let a;const s=(a="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),o=(s.textBaseline="top",s.font="600 32px Arial",{});return e.forEach(e=>{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(o),u.toString(),c.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"});const a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=e=>{i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))}); //# sourceURL=https://development-web.com/wp-includes/js/wp-emoji-loader.min.js </script> <script> (function(){ var el=document.querySelector('[data-geo-label]');if(!el)return; var ru=(document.documentElement.lang||'').slice(0,2)==='ru'; var apply=function(d){if(d&&d.en){el.textContent=ru?(d.ru||d.en):d.en;}}; var m=document.cookie.match(/(?:^|; )god_cc=([^;]*)/); if(m){try{apply(JSON.parse(decodeURIComponent(m[1])));return;}catch(e){}} fetch("https:\/\/development-web.com\/wp-json\/god\/v1\/geo",{credentials:'same-origin'}).then(function(r){return r.json();}).then(function(d){ apply(d); document.cookie='god_cc='+encodeURIComponent(JSON.stringify({cc:d.cc||'',en:d.en||'',ru:d.ru||''}))+';path=/;max-age=2592000;SameSite=Lax;Secure'; }).catch(function(){}); })(); </script> <style id="god-mcta-css"> .god-mcta{display:none} @media (max-width:768px){ .god-mcta{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:2100;gap:8px;padding:8px 10px calc(8px + env(safe-area-inset-bottom));background:rgba(255,255,255,.96);backdrop-filter:blur(8px);border-top:1px solid #E6EEFF;box-shadow:0 -6px 20px rgba(42,43,75,.08);transition:transform .25s} .god-mcta.is-hidden{transform:translateY(110%)} .god-mcta a{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;min-height:46px;border-radius:999px;font:700 14px/1 Montserrat,Arial,sans-serif;text-decoration:none;letter-spacing:.3px} .god-mcta .god-mcta-wa{background:#25D366;color:#fff} .god-mcta .god-mcta-audit{background:linear-gradient(98deg,#9D53C5 0%,#506DD4 100%);color:#fff} .god-mcta svg{width:18px;height:18px;flex:0 0 18px} body{padding-bottom:70px} /* у виджета чата inset задан инлайном с !important — двигаем трансформом */ html body .dcw-widget{transform:translateY(-62px)!important} html body .to-top,html body button.to-top{bottom:140px!important} } </style> <nav class="god-mcta" aria-label="Quick contact"> <a class="god-mcta-wa" href="https://wa.me/995599288712?text=Hi%21%20Writing%20from%20development-web.com" target="_blank" rel="noopener" data-god-contact="whatsapp"> <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.3A10 10 0 1 0 12 2zm0 18.2a8.2 8.2 0 0 1-4.2-1.2l-.3-.2-3 .8.8-2.9-.2-.3A8.2 8.2 0 1 1 12 20.2zm4.5-6.1c-.2-.1-1.5-.7-1.7-.8s-.4-.1-.6.1-.6.8-.8 1c-.1.2-.3.2-.5.1a6.7 6.7 0 0 1-3.3-2.9c-.3-.4.3-.4.7-1.3.1-.2 0-.3 0-.4l-.8-1.8c-.2-.5-.4-.4-.6-.4h-.5a1 1 0 0 0-.7.3 3 3 0 0 0-.9 2.2 5.2 5.2 0 0 0 1.1 2.7 11.8 11.8 0 0 0 4.5 4c1.7.7 2.3.8 3.1.6a2.6 2.6 0 0 0 1.7-1.2 2.1 2.1 0 0 0 .2-1.2c-.1-.1-.3-.2-.5-.3z"/></svg> WhatsApp </a> <a class="god-mcta-audit" href="https://development-web.com/site-analyzer/" data-modal-open="#popup-audit"> Free audit </a> </nav> <script> (function(){ var bar=document.querySelector('.god-mcta'), form=document.getElementById('ms15'); if(!bar||!('IntersectionObserver' in window))return; var hide=function(v){bar.classList.toggle('is-hidden',v);}; if(form){ new IntersectionObserver(function(es){ hide(es[0].isIntersecting); },{threshold:0.05}).observe(form); } document.addEventListener('click',function(e){ var b=e.target.closest('[data-modal-open]'); if(b&&bar.contains(b)){ hide(true); setTimeout(function(){ hide(false); },1500); } }); })(); </script> <style id="god-trust-chips-css"> /* !important на раскладке: LiteSpeed собирает этот inline-стиль в общий CSS-файл и ставит его выше темы, поэтому по порядку правило проигрывало бы column-count. */ #section-whuy_inside-content .to_block .right_list{ column-count:auto!important;-webkit-column-count:auto!important;-moz-column-count:auto!important; display:flex!important;flex-wrap:wrap!important;gap:10px!important;align-content:flex-start; } #section-whuy_inside-content .to_block .right_list span{ /* Ширина у плашки своя, по тексту: заполняет ряд не растягивание, а подбор — в остаток ряда скрипт ставит ту плашку, которая туда влезает. */ display:inline-flex!important;align-items:center;flex:0 0 auto;max-width:100%; padding:10px 18px 10px 38px!important;margin:0!important; font-size:15px!important;font-weight:500;line-height:1.3;color:#2A2B4B; background:linear-gradient(180deg,#fff 0%,#FBFCFF 100%); border:1px solid #E4EAFB;border-radius:999px; position:relative; box-shadow:0 1px 2px rgba(42,43,75,.04); transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease, opacity .45s ease,translate .45s ease; } /* Галочка нарисована рамками, без иконочного шрифта и без лишнего тега. */ #section-whuy_inside-content .to_block .right_list span::before{ content:"";position:absolute;left:16px;top:50%; width:5px;height:9px;margin-top:-6px; border:solid #548AEE;border-width:0 2px 2px 0; transform:rotate(45deg); } #section-whuy_inside-content .to_block .right_list span:hover{ transform:translateY(-2px);border-color:#C9D3F0; box-shadow:0 8px 20px rgba(65,88,208,.12); } /* Появление по очереди. Стартовое состояние вешаем только когда есть JS-класс, иначе при выключенном JS список остался бы невидимым. */ #section-whuy_inside-content .to_block .right_list.god-chips span{ opacity:0;translate:0 10px; transition-delay:calc(var(--i, 0) * 40ms); } #section-whuy_inside-content .to_block .right_list.god-chips.is-in span{ opacity:1;translate:0 0; } @media (prefers-reduced-motion: reduce){ #section-whuy_inside-content .to_block .right_list.god-chips span{ opacity:1;translate:0 0;transition-delay:0s; } #section-whuy_inside-content .to_block .right_list span:hover{ transform:none; } } @media (max-width: 768px){ #section-whuy_inside-content .to_block .right_list{ gap:8px!important; } #section-whuy_inside-content .to_block .right_list span{ font-size:13px!important;padding:8px 14px 8px 32px!important; } #section-whuy_inside-content .to_block .right_list span::before{ left:13px; } } </style> <script> (function(){ var list = document.querySelector('#section-whuy_inside-content .to_block .right_list'); if (!list) return; var items = list.querySelectorAll('span'); if (!items.length) return; for (var i = 0; i < items.length; i++) items[i].style.setProperty('--i', i); list.classList.add('god-chips'); /** * Раскладка подбором. Плашки разной ширины, и при обычной укладке в конце * каждого ряда оставался рваный хвост пустоты. Здесь для остатка ряда * подбирается самая широкая из оставшихся плашек, которая туда влезает. * * Порядок в разметке НЕ меняется — двигаем только свойство order, то есть * визуальную очерёдность. Поисковик и читалка с экрана видят тот же порядок * строк, что и раньше; смысловой последовательности у этого перечня нет. */ function pack(){ var cs = getComputedStyle(list); // clientWidth включает внутренние отступы, а у списка слева их 40 пикселей. // Без вычитания расчёт считал ряд шире, чем он есть, ряды рвались раньше // плана — и в конце каждого всё равно оставалась пустота. var W = list.clientWidth - (parseFloat(cs.paddingLeft) || 0) - (parseFloat(cs.paddingRight) || 0); if (W <= 0) return; var gap = parseFloat(cs.columnGap || cs.gap) || 0; var pool = []; for (var i = 0; i < items.length; i++) { items[i].style.order = ''; pool.push({ el: items[i], w: Math.ceil(items[i].getBoundingClientRect().width) }); } var rows = [], row = [], left = W, first = true; while (pool.length) { var pick = -1; for (var k = 0; k < pool.length; k++) { var need = pool[k].w + (first ? 0 : gap); if (need <= left + 0.5 && (pick === -1 || pool[k].w > pool[pick].w)) pick = k; } if (pick === -1) { // ничего не влезло — закрываем ряд if (first) pick = 0; // плашка шире контейнера: отдаём ей ряд целиком else { rows.push({items: row, left: left}); row = []; left = W; first = true; continue; } } left -= pool[pick].w + (first ? 0 : gap); first = false; row.push(pool[pick].el); pool.splice(pick, 1); } if (row.length) rows.push({items: row, left: left}); // Неполные ряды уводим вниз. Самая узкая плашка — 176 пикселей, поэтому // просвет меньше этого закрыть физически нечем; но короткий ряд внизу // читается как последняя строка абзаца, а посреди блока — как дырка. rows.sort(function(a, b){ return a.left - b.left; }); var order = 0; for (var r = 0; r < rows.length; r++) { for (var j = 0; j < rows[r].items.length; j++) rows[r].items[j].style.order = order++; } } pack(); if (document.fonts && document.fonts.ready) document.fonts.ready.then(pack); var t; window.addEventListener('resize', function(){ clearTimeout(t); t = setTimeout(pack, 150); }); if (!('IntersectionObserver' in window)) { list.classList.add('is-in'); return; } var io = new IntersectionObserver(function(en){ if (en[0].isIntersecting) { list.classList.add('is-in'); io.disconnect(); } }, {threshold: 0.15}); io.observe(list); })(); </script> <style id="god-steps-nav-css"> @media (max-width: 768px){ #section-steps-content .steps_nav{ margin-bottom:22px!important; } #section-steps-content .steps_nav ul{ flex-wrap:nowrap!important;justify-content:flex-start!important; gap:20px!important;overflow-x:auto!important;scroll-behavior:smooth; -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain; scrollbar-width:none;-ms-overflow-style:none; padding:2px 50%!important;margin:0!important; } #section-steps-content .steps_nav ul::-webkit-scrollbar{ display:none; } #section-steps-content .steps_nav ul li{ flex:0 0 auto!important;white-space:nowrap; } /* Активный этап крупнее и контрастнее: в ленте он должен читаться сразу. */ #section-steps-content .steps_nav ul li.slick-active a, #section-steps-content .steps_nav ul li.slick-active button{ font-size:15px!important; } #section-steps-content .steps_nav ul li a, #section-steps-content .steps_nav ul li button{ transition:color .2s,font-size .2s; } } </style> <script> (function(){ function center(list){ var li = list.querySelector('li.slick-active'); if (!li) return; var target = li.offsetLeft - (list.clientWidth - li.offsetWidth) / 2; list.scrollTo ? list.scrollTo({left: target, behavior: 'smooth'}) : (list.scrollLeft = target); } function attach(){ var list = document.querySelector('#section-steps-content .steps_nav ul'); if (!list) return false; if (list.dataset.godSteps) return true; list.dataset.godSteps = '1'; // Слик перевешивает класс на другой li — ловим это, а не его событие. new MutationObserver(function(){ if (window.matchMedia('(max-width: 768px)').matches) center(list); }).observe(list, {subtree:true, attributes:true, attributeFilter:['class']}); if (window.matchMedia('(max-width: 768px)').matches) center(list); return true; } // Слайдер инициализируется лениво, когда секция доезжает до экрана, поэтому // ждать его по таймеру бесполезно: список точек может появиться через минуту // после загрузки. Наблюдаем за секцией и подключаемся в момент появления. if (!attach()) { var sec = document.getElementById('section-steps-content'); if (sec) { var mo = new MutationObserver(function(){ if (attach()) mo.disconnect(); }); mo.observe(sec, {childList: true, subtree: true}); } } })(); </script> <script data-no-optimize="1" data-cfasync="false"> (function () { if (window.__godbrief) return; window.__godbrief = true; var T = {"up":"Uploading\u2026","ok":"Attached: ","err":"Upload failed. Please send the file in a reply."}; // Грузим в момент выбора, а не при отправке: чужой обработчик формы файлы // пропускает, и встраиваться в него пришлось бы гонкой за порядок событий. document.addEventListener('change', function (e) { var inp = e.target; if (!inp || inp.type !== 'file' || !inp.files || !inp.files.length) return; var form = inp.closest('form'); if (!form) return; var file = inp.files[0]; var note = form.querySelector('.god-brief-note'); if (!note) { note = document.createElement('div'); note.className = 'god-brief-note'; note.style.cssText = 'margin-top:6px;font-size:13px;opacity:.9;'; inp.parentNode.appendChild(note); } note.textContent = T.up; var fd = new FormData(); fd.append('file', file); fetch('/wp-json/god/v1/brief-upload', { method: 'POST', body: fd }) .then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }); }) .then(function (res) { if (!res.ok || !res.j || !res.j.ok) throw new Error((res.j && res.j.message) || 'fail'); note.textContent = T.ok + res.j.name; // Скрытые поля читает сборщик форм god-api как обычные поля с name. ['brief_url', 'brief_name'].forEach(function (k, i) { var h = form.querySelector('input[name="' + k + '"]'); if (!h) { h = document.createElement('input'); h.type = 'hidden'; h.name = k; form.appendChild(h); } h.value = i === 0 ? res.j.url : res.j.name; }); }) .catch(function () { note.textContent = T.err; }); }, true); })(); </script> <style id="god-portfolio-slider-css"> @media (max-width: 768px){ /* !important на каждом свойстве не от лени: LiteSpeed собирает этот inline-стиль в общий CSS-файл и ставит его ВЫШЕ темы, так что по порядку правило проигрывает. */ #section-portfolio-content .naw_to{ display:flex!important;flex-wrap:nowrap!important;justify-content:flex-start!important; align-items:stretch!important;gap:10px!important;overflow-x:auto!important; overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch; scrollbar-width:none;-ms-overflow-style:none;padding:2px 16px 10px!important; margin-bottom:24px!important; } #section-portfolio-content .naw_to::-webkit-scrollbar{display:none} #section-portfolio-content .naw_to a{ flex:0 0 auto!important;white-space:nowrap!important;padding:11px 16px!important; min-height:42px;display:flex!important;align-items:center;font-size:13px;border-radius:4px; } } </style> <script> (function(){ var row = document.querySelector('#section-portfolio-content .naw_to'); if (!row) return; // Системная настройка «меньше движения» включена на многих машинах ради // производительности, а не из-за чувствительности к анимации, и полностью // выключать ленту из-за неё — потерять функцию у большинства. Движение здесь // медленное и без вспышек, поэтому при этой настройке просто замедляемся вдвое. var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var SPEED = reduced ? 13 : 26; // пикселей в секунду var RESUME_AFTER = 3000; // пауза после касания var dir = 1, last = 0, pos = 0, paused = false, resumeAt = 0, visible = false, raf = 0; function wide(){ return window.matchMedia('(max-width: 768px)').matches; } function scrollable(){ return row.scrollWidth - row.clientWidth > 8; } function step(ts){ raf = 0; if (!last) last = ts; var dt = Math.min(ts - last, 64) / 1000; last = ts; if (visible && wide() && scrollable() && (!paused || ts > resumeAt)) { paused = false; var max = row.scrollWidth - row.clientWidth; // Позицию держим отдельным числом с дробной частью: scrollLeft округляется, // а 26 px/с при 60 кадрах — это 0,43 px за кадр, то есть ноль после округления, // и лента стояла бы на месте. if (Math.abs(pos - row.scrollLeft) > 2) pos = row.scrollLeft; // палец подвинул — подхватываем pos += dir * SPEED * dt; if (pos >= max) { pos = max; dir = -1; } else if (pos <= 0) { pos = 0; dir = 1; } row.scrollLeft = pos; } schedule(); } function schedule(){ if (!raf) raf = requestAnimationFrame(step); } function hold(){ paused = true; resumeAt = performance.now() + RESUME_AFTER; } ['pointerdown','touchstart','wheel','mouseenter'].forEach(function(e){ row.addEventListener(e, hold, {passive:true}); }); row.addEventListener('mouseleave', function(){ resumeAt = performance.now(); }, {passive:true}); if ('IntersectionObserver' in window) { new IntersectionObserver(function(en){ visible = en[0].isIntersecting; last = 0; if (visible) schedule(); }, {threshold: 0.05}).observe(row); } else { visible = true; } schedule(); })(); </script> <style id="god-file-input-css"> .god-file{position:relative;display:inline-block;vertical-align:middle;max-width:100%;width:100%} .god-file input[type="file"]{color:transparent!important;text-shadow:none!important} .god-file .god-file-name{position:absolute;left:0;top:50%;transform:translateY(-50%); pointer-events:none;font:inherit;color:inherit;opacity:.9;white-space:nowrap; overflow:hidden;text-overflow:ellipsis;max-width:100%} </style> <script> (function(){ var EMPTY = "No file chosen"; function decorate(inp){ if (inp.closest('.god-file')) return; // Поле, спрятанное под свою кнопку-label: системной надписи там и так не видно, // а наш span разрывал строку и уводил иконку с подписью на разные строки. var cs = getComputedStyle(inp); if (parseFloat(cs.opacity) < 0.05 || cs.visibility === 'hidden' || cs.display === 'none' || inp.getBoundingClientRect().width < 4) return; if (inp.id && document.querySelector('label[for="' + inp.id + '"].input__file-button')) return; // Цвет и выключку берём у самого поля ДО того, как навесим обёртку: наше правило // красит текст в прозрачный, а подпись потом наследовала бы цвет контейнера — // в форме на градиенте это давало чёрные буквы там, где все подписи белые. // Эталон — плейсхолдер соседнего текстового поля той же формы: у поля файла // своего плейсхолдера нет, а его собственный шрифт крупнее и без курсива, // из-за чего подпись выбивалась из ряда («16px Montserrat» против // «italic 500 12px Montserrat» у соседей). var form = inp.closest('form'); var twin = form && form.querySelector('input[type="text"], input[type="email"], input[type="tel"]'); var twinCs = twin ? getComputedStyle(twin) : null; var twinPh = twin ? getComputedStyle(twin, '::placeholder') : null; var inherited = { color: (twinPh && twinPh.color) || cs.color, font: (twinPh && twinPh.font) || (twinCs && twinCs.font) || '', align: (twinCs && twinCs.textAlign) || ((cs.textAlign === 'start' || cs.textAlign === 'left') ? '' : cs.textAlign) }; var wrap = document.createElement('span'); wrap.className = 'god-file'; inp.parentNode.insertBefore(wrap, inp); wrap.appendChild(inp); var name = document.createElement('span'); name.className = 'god-file-name'; name.textContent = EMPTY; name.style.color = inherited.color; if (inherited.font) name.style.font = inherited.font; if (inherited.align && inherited.align !== 'start') { name.style.textAlign = inherited.align; name.style.left = '0'; name.style.right = '0'; name.style.maxWidth = 'none'; } wrap.appendChild(name); inp.addEventListener('change', function(){ name.textContent = (inp.files && inp.files.length) ? inp.files[0].name : EMPTY; }); } function run(){ document.querySelectorAll('input[type="file"]').forEach(decorate); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run(); // Формы в модальных окнах собираются позже — обходим ещё раз после первого клика. document.addEventListener('click', function(){ setTimeout(run, 300); }, true); })(); </script> <script> (function(){ document.addEventListener('submit', function(e){ var f = e.target && e.target.closest ? e.target.closest('.god-lead-form') : null; if(!f) return; e.preventDefault(); var ru = f.getAttribute('data-lang') === 'ru'; var status = f.querySelector('.god-lead-status'); var btn = f.querySelector('[type=submit]'); function val(n){ var el=f.querySelector('[name="'+n+'"]'); return el ? (el.value||'').trim() : ''; } var data = { name:val('name'), phone:val('phone'), email:val('email'), website:val('website'), message:val('message'), website_hp:val('website_hp'), offer: f.getAttribute('data-offer')||'consultation', source_url: location.href }; // Обязательные поля — те, что помечены required в разметке: у консультации // это имя и телефон, у аудита — адрес сайта и почта, телефона там нет. var missing = Array.prototype.filter.call(f.querySelectorAll('input[required],textarea[required]'), function(el){ return el.type === 'checkbox' ? !el.checked : (!el.value.trim() || (el.checkValidity && !el.checkValidity())); }); if(missing.length){ missing.forEach(function(el){ el.style.borderColor='#e74c3c'; }); return; } if(btn){ btn.disabled=true; btn.setAttribute('data-t', btn.textContent); btn.textContent = ru ? 'Отправляем…' : 'Sending…'; } fetch('/wp-json/god/v1/leads/capture', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(data) }) // Раньше «Спасибо» показывалось на ЛЮБОЙ ответ, включая 429 и 500: человек // был уверен, что заявка ушла, а её не было. Не-2xx — это ошибка, ветка ниже. .then(function(r){ if(!r.ok) throw new Error('HTTP '+r.status); return r.json().catch(function(){return {};}); }) .then(function(){ f.querySelectorAll('.field, label.agree, button[type=submit]').forEach(function(el){ el.style.display='none'; }); if(status){ status.hidden=false; status.style.display='block'; status.textContent = f.getAttribute('data-thanks') || (ru ? 'Спасибо! Мы свяжемся с вами в ближайшее время.' : 'Thank you! We will get back to you shortly.'); } if(typeof gtag !== 'undefined'){ gtag('event','generate_lead',{ event_category:'lead', event_label:data.offer }); } }) .catch(function(){ if(btn){ btn.disabled=false; btn.textContent = btn.getAttribute('data-t') || 'Send'; } if(status){ status.hidden=false; status.style.display='block'; status.style.color='#c0392b'; status.textContent = ru ? 'Ошибка отправки. Попробуйте ещё раз или позвоните нам.' : 'Submission error. Please try again or call us.'; } }); }); })(); </script> <style id="god-sdr-css"> #god-sdr-btn{position:fixed;right:22px;bottom:22px;z-index:99998;width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,#2563eb,#1e40af);box-shadow:0 8px 24px rgba(37,99,235,.4);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .15s} #god-sdr-btn:hover{transform:scale(1.06)} #god-sdr-btn svg{width:28px;height:28px;fill:#fff} #god-sdr-panel{position:fixed;right:22px;bottom:22px;z-index:99999;width:380px;max-width:calc(100vw - 32px);height:560px;max-height:calc(100vh - 40px);background:#fff;border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.25);display:none;flex-direction:column;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif} #god-sdr-panel.open{display:flex} .god-sdr-head{background:linear-gradient(135deg,#2563eb,#1e40af);color:#fff;padding:16px 18px;display:flex;align-items:center;justify-content:space-between} .god-sdr-head h4{margin:0;font-size:15px;font-weight:600} .god-sdr-head small{opacity:.85;font-size:11.5px} .god-sdr-x{background:none;border:none;color:#fff;font-size:22px;cursor:pointer;line-height:1;opacity:.85} .god-sdr-msgs{flex:1;overflow-y:auto;padding:16px;background:#f7f8fa;display:flex;flex-direction:column;gap:10px} .god-sdr-m{max-width:82%;padding:10px 13px;border-radius:14px;font-size:14px;line-height:1.45;white-space:pre-wrap;word-wrap:break-word} .god-sdr-m.bot{align-self:flex-start;background:#fff;color:#1f2937;border:1px solid #e5e7eb;border-bottom-left-radius:4px} .god-sdr-m.me{align-self:flex-end;background:#2563eb;color:#fff;border-bottom-right-radius:4px} .god-sdr-typing{align-self:flex-start;color:#9ca3af;font-size:13px;padding:4px 6px} .god-sdr-foot{padding:10px;border-top:1px solid #eef0f3;display:flex;gap:8px;background:#fff} .god-sdr-foot textarea{flex:1;resize:none;border:1px solid #d1d5db;border-radius:10px;padding:9px 12px;font-size:14px;font-family:inherit;max-height:90px;outline:none} .god-sdr-foot textarea:focus{border-color:#2563eb} .god-sdr-send{background:#2563eb;border:none;border-radius:10px;color:#fff;width:42px;cursor:pointer;display:flex;align-items:center;justify-content:center} .god-sdr-send svg{width:18px;height:18px;fill:#fff} .god-sdr-foot .god-sdr-note{display:none} </style> <button id="god-sdr-btn" aria-label="Open chat"><svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 5.94 2 10.8c0 2.6 1.3 4.93 3.36 6.5-.1 1.2-.5 2.6-1.36 3.7 1.7-.2 3.3-.9 4.5-1.9.95.27 1.96.4 3 .4 5.52 0 10-3.94 10-8.8S17.52 2 12 2z"/></svg></button> <div id="god-sdr-panel" role="dialog" aria-label="Chat with Global One Digital"> <div class="god-sdr-head"><div><h4>Chat with Global One Digital</h4><small>AI assistant · replies in seconds</small></div><button class="god-sdr-x" aria-label="Close">×</button></div> <div class="god-sdr-msgs" id="god-sdr-msgs"></div> <div class="god-sdr-foot"><textarea id="god-sdr-in" rows="1" placeholder="Type a message…"></textarea><button class="god-sdr-send" id="god-sdr-send" aria-label="Send"><svg viewBox="0 0 24 24"><path d="M2 21l21-9L2 3v7l15 2-15 2z"/></svg></button></div> </div> <script id="god-sdr-js"> (function(){ var REST="https:\/\/development-web.com\/wp-json\/god\/v1\/sdr\/chat", LANG="en", GREET="Hi! I\u2019m Global One Digital\u2019s AI assistant. Need help with SEO, a website, or automation?"; var btn=document.getElementById('god-sdr-btn'),panel=document.getElementById('god-sdr-panel'), msgs=document.getElementById('god-sdr-msgs'),input=document.getElementById('god-sdr-in'), send=document.getElementById('god-sdr-send'),x=panel.querySelector('.god-sdr-x'),started=false,busy=false; function sk(){var k=localStorage.getItem('god_sdr_sk');if(!k){k='s_'+Math.random().toString(36).slice(2)+Date.now().toString(36);localStorage.setItem('god_sdr_sk',k);}return k;} function add(text,cls){var d=document.createElement('div');d.className='god-sdr-m '+cls;d.textContent=text;msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d;} function open(){panel.classList.add('open');btn.style.display='none';if(!started){started=true;add(GREET,'bot');}input.focus();} function close(){panel.classList.remove('open');btn.style.display='flex';} btn.addEventListener('click',open);x.addEventListener('click',close); function typing(){var d=document.createElement('div');d.className='god-sdr-typing';d.textContent='…';d.id='god-sdr-typing';msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;} function untype(){var t=document.getElementById('god-sdr-typing');if(t)t.remove();} function sendMsg(){ var v=input.value.trim();if(!v||busy)return;busy=true;input.value='';input.style.height='auto'; add(v,'me');typing(); fetch(REST,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({session_key:sk(),message:v,lang:LANG})}) .then(function(r){return r.json();}) .then(function(d){untype();add((d&&d.reply)?d.reply:(LANG==='ru'?'Извините, попробуйте ещё раз.':'Sorry, please try again.'),'bot');}) .catch(function(){untype();add(LANG==='ru'?'Сбой связи. Попробуйте ещё раз.':'Connection error. Please try again.','bot');}) .finally(function(){busy=false;input.focus();}); } send.addEventListener('click',sendMsg); input.addEventListener('keydown',function(e){if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();sendMsg();}}); input.addEventListener('input',function(){input.style.height='auto';input.style.height=Math.min(input.scrollHeight,90)+'px';}); })(); </script> <script> (function() { // Selectors for forms that weren't already wired (skip quick-book + quiz which work) var SELECTORS = '.bf-form, .contact-form, .calc-form, .god-modal__form, .god-final-cta form, .quiz-form'; var ENDPOINT = '/wp-json/god/v1/contact-submit'; function setStatus(form, type, text) { var msg = form.querySelector('.god-form-msg'); if (!msg) { msg = document.createElement('div'); msg.className = 'god-form-msg'; msg.style.cssText = 'margin-top:12px;padding:10px 14px;border-radius:8px;font-size:14px;text-align:center;'; form.appendChild(msg); } msg.textContent = text; if (type === 'ok') { msg.style.cssText += 'background:#E8F8EE;color:#157144;border:1px solid #BFE7CB;'; } if (type === 'err') { msg.style.cssText += 'background:#FDF1F1;color:#B23B3B;border:1px solid #F4C6C6;'; } if (type === 'pending') { msg.style.cssText += 'background:#F4F8FF;color:#2A2B4B;'; } } document.addEventListener('submit', function(e) { var form = e.target; if (!form || !form.matches(SELECTORS)) return; // Skip forms already wired to specific endpoints (qbook, quiz inside page-prose) if (form.id === 'pp-qbook-form' || form.closest('#quiz')) return; e.preventDefault(); // Collect all named fields var payload = { page: window.location.href, form_id: form.className || 'unknown', }; var inputs = form.querySelectorAll('input[name], select[name], textarea[name]'); inputs.forEach(function(inp) { if (inp.type === 'checkbox' || inp.type === 'radio') { if (inp.checked) payload[inp.name] = inp.value || '1'; } else if (inp.type === 'file') { // Skip file in this basic handler — would need multipart upload } else { payload[inp.name] = inp.value; } }); // Detect btn + show pending state var btn = form.querySelector('button[type="submit"], input[type="submit"], .btn-grad, .button-color, button.form-button'); var btnOrigText = btn ? (btn.textContent || btn.value) : ''; if (btn) { btn.disabled = true; if (btn.tagName === 'BUTTON') btn.textContent = 'Sending…'; else btn.value = 'Sending…'; } setStatus(form, 'pending', 'Sending…'); fetch(ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(payload), }).then(function(r) { return r.json().then(function(j) { return { ok: r.ok, j: j }; }); }).then(function(res) { if (res.ok && res.j.success) { setStatus(form, 'ok', '✓ Thank you — we will be in touch within 24 hours.'); // Reset form after success setTimeout(function() { form.reset(); if (btn) { btn.disabled = false; if (btn.tagName === 'BUTTON') btn.textContent = btnOrigText; else btn.value = btnOrigText; } }, 4000); } else { setStatus(form, 'err', '⚠ ' + (res.j.message || 'Could not send — please email hello@global1digital.com')); if (btn) { btn.disabled = false; if (btn.tagName === 'BUTTON') btn.textContent = btnOrigText; else btn.value = btnOrigText; } } }).catch(function() { setStatus(form, 'err', '⚠ Network error — please email hello@global1digital.com'); if (btn) { btn.disabled = false; if (btn.tagName === 'BUTTON') btn.textContent = btnOrigText; else btn.value = btnOrigText; } }); }, true); })(); </script> <style id="god-chat-in-widget-css"> #god-sdr-btn{display:none!important} /* «Наверх» стояла ровно под виджетом связи и перекрывала его нижний край. Поднимаем её над виджетом: 24 снизу + 46 высота + 12 зазор. */ .to-top{bottom:82px!important} .dcw-icon[data-key="chat"] a{ display:flex;align-items:center;justify-content:center; background:linear-gradient(135deg,#2563eb,#1e40af);border-radius:50%; } .dcw-icon[data-key="chat"] img{width:60%;height:60%;display:block} </style> <script> (function(){ var ICON = 'data:image/svg+xml;utf8,' + encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff">' + '<path d="M12 2C6.48 2 2 5.94 2 10.8c0 2.6 1.3 4.93 3.36 6.5-.1 1.2-.5 2.6-1.36 3.7 ' + '1.7-.2 3.3-.9 4.5-1.9.95.27 1.96.4 3 .4 5.52 0 10-3.94 10-8.8S17.52 2 12 2z"/></svg>'); var LABEL = "Chat"; function inject(){ var menu = document.querySelector('.dcw-widget .dcw-menu'); var chat = document.getElementById('god-sdr-btn'); if (!menu || !chat) return false; if (menu.querySelector('.dcw-icon[data-key="chat"]')) return true; var item = document.createElement('div'); item.className = 'dcw-icon'; item.setAttribute('data-key', 'chat'); var a = document.createElement('a'); a.href = '#'; a.title = LABEL; a.setAttribute('aria-label', LABEL); a.setAttribute('data-messenger', 'chat'); a.addEventListener('click', function(e){ e.preventDefault(); chat.click(); }); var img = document.createElement('img'); img.src = ICON; img.alt = LABEL; a.appendChild(img); item.appendChild(a); menu.appendChild(item); return true; } // Виджет и чат подключаются своими скриптами, порядок не гарантирован — // пробуем несколько раз и прекращаем, как только вставили. var tries = 0; (function attempt(){ if (inject() || ++tries > 20) return; setTimeout(attempt, 300); })(); })(); </script> <script data-no-optimize="1">window.lazyLoadOptions=Object.assign({},{threshold:300},window.lazyLoadOptions||{});!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function o(t){return e({},at,t)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,vt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,vt,e)}function i(t){return s(t,null),0}function r(t){return null===c(t)}function u(t){return c(t)===_t}function d(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function f(t,e){et?t.classList.add(e):t.className+=(t.className?" ":"")+e}function _(t,e){et?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function v(t,e){!e||(e=e._observer)&&e.unobserve(t)}function b(t,e){t&&(t.loadingCount+=e)}function p(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function h(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function m(t){return!!t[lt]}function E(t){return t[lt]}function I(t){return delete t[lt]}function y(e,t){var n;m(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[lt]=n)}function L(a,t){var o;m(a)&&(o=E(a),t.forEach(function(t){var e,n;e=a,(t=o[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function k(t,e,n){f(t,e.class_loading),s(t,st),n&&(b(n,1),d(e.callback_loading,t,n))}function A(t,e,n){n&&t.setAttribute(e,n)}function O(t,e){A(t,rt,l(t,e.data_sizes)),A(t,it,l(t,e.data_srcset)),A(t,ot,l(t,e.data_src))}function w(t,e,n){var a=l(t,e.data_bg_multi),o=l(t,e.data_bg_multi_hidpi);(a=nt&&o?o:a)&&(t.style.backgroundImage=a,n=n,f(t=t,(e=e).class_applied),s(t,dt),n&&(e.unobserve_completed&&v(t,e),d(e.callback_applied,t,n)))}function x(t,e){!e||0<e.loadingCount||0<e.toLoadCount||d(t.callback_finish,e)}function M(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function N(t){return!!t.llEvLisnrs}function z(t){if(N(t)){var e,n,a=t.llEvLisnrs;for(e in a){var o=a[e];n=e,o=o,t.removeEventListener(n,o)}delete t.llEvLisnrs}}function C(t,e,n){var a;delete t.llTempImage,b(n,-1),(a=n)&&--a.toLoadCount,_(t,e.class_loading),e.unobserve_completed&&v(t,n)}function R(i,r,c){var l=g(i)||i;N(l)||function(t,e,n){N(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";M(t,a,e),M(t,"error",n)}(l,function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_loaded),s(e,ut),d(n.callback_loaded,e,a),o||x(n,a),z(l)},function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_error),s(e,ft),d(n.callback_error,e,a),o||x(n,a),z(l)})}function T(t,e,n){var a,o,i,r,c;t.llTempImage=document.createElement("IMG"),R(t,e,n),m(c=t)||(c[lt]={backgroundImage:c.style.backgroundImage}),i=n,r=l(a=t,(o=e).data_bg),c=l(a,o.data_bg_hidpi),(r=nt&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),k(a,o,i)),w(t,e,n)}function G(t,e,n){var a;R(t,e,n),a=e,e=n,(t=Et[(n=t).tagName])&&(t(n,a),k(n,a,e))}function D(t,e,n){var a;a=t,(-1<It.indexOf(a.tagName)?G:T)(t,e,n)}function S(t,e,n){var a;t.setAttribute("loading","lazy"),R(t,e,n),a=e,(e=Et[(n=t).tagName])&&e(n,a),s(t,_t)}function V(t){t.removeAttribute(ot),t.removeAttribute(it),t.removeAttribute(rt)}function j(t){h(t,function(t){L(t,mt)}),L(t,mt)}function F(t){var e;(e=yt[t.tagName])?e(t):m(e=t)&&(t=E(e),e.style.backgroundImage=t.backgroundImage)}function P(t,e){var n;F(t),n=e,r(e=t)||u(e)||(_(e,n.class_entered),_(e,n.class_exited),_(e,n.class_applied),_(e,n.class_loading),_(e,n.class_loaded),_(e,n.class_error)),i(t),I(t)}function U(t,e,n,a){var o;n.cancel_on_exit&&(c(t)!==st||"IMG"===t.tagName&&(z(t),h(o=t,function(t){V(t)}),V(o),j(t),_(t,n.class_loading),b(a,-1),i(t),d(n.callback_cancel,t,e,a)))}function $(t,e,n,a){var o,i,r=(i=t,0<=bt.indexOf(c(i)));s(t,"entered"),f(t,n.class_entered),_(t,n.class_exited),o=t,i=a,n.unobserve_entered&&v(o,i),d(n.callback_enter,t,e,a),r||D(t,n,a)}function q(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function H(t,o,i){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?$(t.target,t,o,i):(e=t.target,n=t,a=o,t=i,void(r(e)||(f(e,a.class_exited),U(e,n,a,t),d(a.callback_exit,e,n,t))));var e,n,a})}function B(e,n){var t;tt&&!q(e)&&(n._observer=new IntersectionObserver(function(t){H(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function J(t){return Array.prototype.slice.call(t)}function K(t){return t.container.querySelectorAll(t.elements_selector)}function Q(t){return c(t)===ft}function W(t,e){return e=t||K(e),J(e).filter(r)}function X(e,t){var n;(n=K(e),J(n).filter(Q)).forEach(function(t){_(t,e.class_error),i(t)}),t.update()}function t(t,e){var n,a,t=o(t);this._settings=t,this.loadingCount=0,B(t,this),n=t,a=this,Y&&window.addEventListener("online",function(){X(n,a)}),this.update(e)}var Y="undefined"!=typeof window,Z=Y&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),tt=Y&&"IntersectionObserver"in window,et=Y&&"classList"in document.createElement("p"),nt=Y&&1<window.devicePixelRatio,at={elements_selector:".lazy",container:Z||Y?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",it="srcset",rt="sizes",ct="poster",lt="llOriginalAttrs",st="loading",ut="loaded",dt="applied",ft="error",_t="native",gt="data-",vt="ll-status",bt=[st,ut,dt,ft],pt=[ot],ht=[ot,ct],mt=[ot,it,rt],Et={IMG:function(t,e){h(t,function(t){y(t,mt),O(t,e)}),y(t,mt),O(t,e)},IFRAME:function(t,e){y(t,pt),A(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){y(t,pt),A(t,ot,l(t,e.data_src))}),y(t,ht),A(t,ct,l(t,e.data_poster)),A(t,ot,l(t,e.data_src)),t.load()}},It=["IMG","IFRAME","VIDEO"],yt={IMG:j,IFRAME:function(t){L(t,pt)},VIDEO:function(t){a(t,function(t){L(t,pt)}),L(t,ht),t.load()}},Lt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,o=this._settings,i=W(t,o);{if(p(this,i.length),!Z&&tt)return q(o)?(e=o,n=this,i.forEach(function(t){-1!==Lt.indexOf(t.tagName)&&S(t,e,n)}),void p(n,0)):(t=this._observer,o=i,t.disconnect(),a=t,void o.forEach(function(t){a.observe(t)}));this.loadAll(i)}},destroy:function(){this._observer&&this._observer.disconnect(),K(this._settings).forEach(function(t){I(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;W(t,n).forEach(function(t){v(t,e),D(t,n,e)})},restoreAll:function(){var e=this._settings;K(e).forEach(function(t){P(t,e)})}},t.load=function(t,e){e=o(e);D(t,e)},t.resetStatus=function(t){i(t)},t}),function(t,e){"use strict";function n(){e.body.classList.add("litespeed_lazyloaded")}function a(){console.log("[LiteSpeed] Start Lazy Load"),o=new LazyLoad(Object.assign({},t.lazyLoadOptions||{},{elements_selector:"[data-lazyloaded]",callback_finish:n})),i=function(){o.update()},t.MutationObserver&&new MutationObserver(i).observe(e.documentElement,{childList:!0,subtree:!0,attributes:!0})}var o,i;t.addEventListener?t.addEventListener("load",a,!1):t.attachEvent("onload",a)}(window,document);</script></body> </html> <!-- Page cached by LiteSpeed Cache 7.9.1 on 2026-10-24 01:00:37 -->