(function initializeLandingInteractions() { const prefersReducedMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches; function pad(value) { return String(Math.max(0, value)).padStart(2, "0"); } function startCountdown() { const root = document.querySelector("[data-countdown]"); if (!root) return; const target = new Date(root.dataset.countdown).getTime(); const units = Object.fromEntries( [...root.querySelectorAll("[data-countdown-unit]")].map((node) => [ node.dataset.countdownUnit, node, ]), ); function update() { const remaining = Math.max(0, target - Date.now()); const totalSeconds = Math.floor(remaining / 1000); const values = { days: Math.floor(totalSeconds / 86400), hours: Math.floor((totalSeconds % 86400) / 3600), minutes: Math.floor((totalSeconds % 3600) / 60), seconds: totalSeconds % 60, }; Object.entries(values).forEach(([unit, value]) => { if (units[unit]) units[unit].textContent = pad(value); }); return remaining > 0; } update(); const timer = window.setInterval(() => { if (!update()) window.clearInterval(timer); }, 1000); } function startBoarGame() { const boar = document.querySelector("[data-boar]"); if (!boar) return; let catches = 0; boar.addEventListener("click", () => { catches += 1; if (prefersReducedMotion) { boar.setAttribute("aria-label", `Кабан найден ${catches} раз. Попробовать снова`); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "boar_catch"); return; } boar.classList.add("is-running"); window.setTimeout(() => { const maxRight = window.innerWidth < 640 ? 48 : 68; const maxBottom = window.innerWidth < 640 ? 62 : 72; boar.style.right = `${5 + Math.random() * maxRight}%`; boar.style.bottom = `${5 + Math.random() * maxBottom}%`; boar.classList.remove("is-running"); boar.setAttribute("aria-label", `Кабан найден ${catches} раз. Попробовать снова`); }, 160); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "boar_catch"); }); } function startEligibilityQuiz() { const root = document.querySelector("[data-eligibility-quiz]"); if (!root) return; const intro = root.querySelector("[data-quiz-intro]"); const stage = root.querySelector("[data-quiz-stage]"); const startButton = root.querySelector("[data-quiz-start]"); const progress = root.querySelector("[data-quiz-progress]"); const steps = [...root.querySelectorAll("[data-quiz-step]")]; const results = [...root.querySelectorAll("[data-quiz-result]")]; let answers = []; let currentStep = 0; function showStep(index, shouldFocus = true) { currentStep = index; steps.forEach((step, stepIndex) => { step.hidden = stepIndex !== index; }); results.forEach((result) => { result.hidden = true; }); if (progress) progress.style.width = `${((index + 1) / steps.length) * 100}%`; if (shouldFocus) steps[index]?.querySelector("h3")?.focus({ preventScroll: true }); } function resetQuiz() { answers = []; intro.hidden = false; stage.hidden = true; showStep(0, false); startButton?.focus({ preventScroll: true }); } startButton?.addEventListener("click", () => { intro.hidden = true; stage.hidden = false; showStep(0); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "eligibility_quiz_start"); }); root.addEventListener("click", (event) => { const target = event.target; if (!(target instanceof Element)) return; const answerButton = target.closest("[data-quiz-answer]"); if (answerButton) { answers[currentStep] = answerButton.dataset.quizAnswer; if (currentStep < steps.length - 1) { showStep(currentStep + 1); return; } steps.forEach((step) => { step.hidden = true; }); if (progress) progress.style.width = "100%"; const outcome = answers.every((answer) => answer === "yes") ? "positive" : "negative"; const result = root.querySelector(`[data-quiz-result="${outcome}"]`); result.hidden = false; result.querySelector("h3")?.setAttribute("tabindex", "-1"); result.querySelector("h3")?.focus({ preventScroll: true }); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", `eligibility_quiz_${outcome}`); } if (target.closest("[data-quiz-restart]")) resetQuiz(); }); } function startNatureSignHunt() { const journal = document.querySelector("[data-hunt-journal]"); const panel = document.querySelector("[data-hunt-panel]"); const toggle = document.querySelector("[data-hunt-toggle]"); const count = document.querySelector("[data-hunt-count]"); const complete = document.querySelector("[data-hunt-complete]"); const signs = [...document.querySelectorAll("[data-nature-sign]")]; if (!journal || !panel || !toggle || !count || !complete || signs.length === 0) return; const ids = ["spruce", "feather", "bear", "boar"]; const storageKey = "pfp-nature-signs-v1"; let found = new Set(); try { const saved = JSON.parse(window.localStorage.getItem(storageKey) || "[]"); found = new Set(saved.filter((id) => ids.includes(id))); } catch { found = new Set(); } function save() { try { window.localStorage.setItem(storageKey, JSON.stringify([...found])); } catch { // The hunt still works for the current page when storage is unavailable. } } function update() { count.textContent = `${found.size}/${ids.length}`; signs.forEach((sign) => { const isFound = found.has(sign.dataset.natureSign); sign.classList.toggle("is-found", isFound); sign.setAttribute("aria-pressed", String(isFound)); }); ids.forEach((id) => { document.querySelector(`[data-hunt-item="${id}"]`)?.classList.toggle("is-found", found.has(id)); }); } function setPanel(open) { panel.hidden = !open; toggle.setAttribute("aria-expanded", String(open)); } toggle.addEventListener("click", () => setPanel(panel.hidden)); signs.forEach((sign) => { sign.addEventListener("click", () => { const id = sign.dataset.natureSign; if (!id || found.has(id)) return; found.add(id); save(); update(); journal.classList.add("is-notifying"); window.setTimeout(() => journal.classList.remove("is-notifying"), 650); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "nature_sign_found", { sign: id }); if (found.size === ids.length) { complete.hidden = false; complete.querySelector("[data-hunt-close]")?.focus({ preventScroll: true }); window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "nature_sign_hunt_complete"); } }); }); document.querySelector("[data-hunt-reset]")?.addEventListener("click", () => { found.clear(); save(); update(); complete.hidden = true; }); complete.querySelectorAll("[data-hunt-close]").forEach((button) => { button.addEventListener("click", () => { complete.hidden = true; toggle.focus({ preventScroll: true }); }); }); update(); } function startNotifyForm() { const form = document.querySelector("[data-notify-form]"); const status = document.querySelector("[data-notify-status]"); if (!form || !status) return; form.addEventListener("submit", async (event) => { event.preventDefault(); const input = form.querySelector('input[name="email"]'); const button = form.querySelector('button[type="submit"]'); if (!input?.reportValidity()) return; button.disabled = true; status.textContent = "Сохраняем адрес…"; try { const response = await fetch(form.action, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: input.value, website: "" }), }); if (!response.ok) throw new Error("request_failed"); input.value = ""; status.textContent = "Готово! Напомним перед открытием приёма заявок."; window.ym?.(window.__PFP_METRIKA_ID__, "reachGoal", "notify_signup"); } catch { status.textContent = "Не получилось сохранить адрес. Попробуйте ещё раз чуть позже."; } finally { button.disabled = false; } }); } startCountdown(); startBoarGame(); startEligibilityQuiz(); startNatureSignHunt(); startNotifyForm(); })();