sektaotekpetrapp.js
Blameapp.js135 lines
(() => { "use strict"; const stepNumbers = { rise: "01", water: "02", cool: "03", move: "04", breakfast: "05" }; const stepLooks = { rise: [2, "Встала. Уже хорошо"], water: [1, "Попить воды — всегда хорошая идея"], cool: [3, "Прохладный компресс приятно бодрит"], move: [4, "Мягкое движение — сегодня можно без подвигов"], breakfast: [5, "Позавтракала. Петровна на ногах"] }; const videos = { training: ["Мягкая тренировка Soft&Power", "https://kinescope.io/skSt4VXuMPoo1P6ZDB8GpY"], massage: ["Массаж лица", "https://kinescope.io/bgXFcid5Fd58WmdchV1dLx"], guasha: ["Гуаша-эксперимент с Олей Маркес", "https://kinescope.io/ebMtPvrvzqGTgiwddmZXF4"] }; const done = new Set(); const recent = []; let lastVideoButton = null; document.querySelectorAll("img[src$='.webp']").forEach((image) => { image.addEventListener("error", () => { const fallback = image.src.replace(/\.webp$/, image.dataset.state !== undefined ? ".png" : ".jpg"); if (image.src !== fallback) image.src = fallback; }, { once: true }); }); const card = document.querySelector(".pet-card"); const finish = document.getElementById("finish-section"); const practice = document.getElementById("practice-section"); const modal = document.getElementById("video-modal"); const frame = document.getElementById("video-frame"); const videoTitle = document.getElementById("video-title"); const videoLink = document.getElementById("video-link"); function currentLook() { if (!done.size) return [0, "Петровна проснулась. Пока просто лежит"]; if (done.size === 5) return [5, "Петровна проснулась и готова к своему дню"]; const last = [...recent].reverse().find((id) => done.has(id)); return stepLooks[last]; } function renderProgress() { const count = done.size; const progress = Math.round((count / 5) * 100); const [sprite, caption] = currentLook(); card.className = `pet-card pet-level-${count}`; document.getElementById("progress-value").textContent = `${progress}%`; document.getElementById("progress-bar").style.width = `${Math.max(progress, 6)}%`; document.getElementById("pet-mode").textContent = `${count} из 5`; document.getElementById("pet-state").textContent = caption; document.querySelectorAll(".pet-sprite").forEach((image) => image.classList.toggle("active", Number(image.dataset.state) === sprite)); finish.hidden = count !== 5; practice.hidden = count !== 5; } document.querySelectorAll("[data-step]").forEach((button) => { button.addEventListener("click", () => { const id = button.dataset.step; if (done.has(id)) { done.delete(id); const index = recent.indexOf(id); if (index >= 0) recent.splice(index, 1); } else { done.add(id); const index = recent.indexOf(id); if (index >= 0) recent.splice(index, 1); recent.push(id); } const checked = done.has(id); const item = document.querySelector(`[data-item="${id}"]`); item.classList.toggle("checked", checked); button.setAttribute("aria-pressed", String(checked)); button.querySelector(".check-number").textContent = checked ? "✓" : stepNumbers[id]; button.querySelector(".check-action").textContent = checked ? "готово" : "отметить"; renderProgress(); }); }); document.querySelectorAll("[data-feeling]").forEach((button) => button.addEventListener("click", () => { document.querySelectorAll("[data-feeling]").forEach((item) => item.classList.remove("active")); button.classList.add("active"); })); document.querySelectorAll("[data-tomorrow]").forEach((button) => button.addEventListener("click", () => { document.querySelectorAll("[data-tomorrow]").forEach((item) => { item.classList.remove("selected"); item.querySelector("i").textContent = ""; }); button.classList.add("selected"); button.querySelector("i").textContent = "✓"; document.getElementById("tomorrow-result").hidden = false; })); function lockPage(lock) { document.documentElement.style.overflow = lock ? "hidden" : ""; document.body.style.overflow = lock ? "hidden" : ""; } function closeVideo() { modal.hidden = true; frame.src = "about:blank"; lockPage(false); if (lastVideoButton) lastVideoButton.focus({ preventScroll: true }); } document.querySelectorAll("[data-video]").forEach((button) => button.addEventListener("click", () => { const [title, url] = videos[button.dataset.video]; lastVideoButton = button; videoTitle.textContent = title; frame.title = title; frame.src = url.replace("kinescope.io/", "kinescope.io/embed/"); videoLink.href = url; modal.hidden = false; lockPage(true); if (!window.matchMedia("(pointer: coarse)").matches) document.getElementById("close-video").focus(); })); document.getElementById("close-video").addEventListener("click", closeVideo); document.getElementById("video-backdrop").addEventListener("click", closeVideo); document.addEventListener("keydown", (event) => { if (event.key === "Escape" && !modal.hidden) closeVideo(); }); const nudge = document.getElementById("course-nudge"); let nudgeClosed = false; let heroVisible = true; let courseVisible = false; const updateNudge = () => { nudge.hidden = nudgeClosed || heroVisible || courseVisible; }; const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.target.classList.contains("hero")) heroVisible = entry.isIntersecting; if (entry.target.classList.contains("course-bridge")) courseVisible = entry.isIntersecting; }); updateNudge(); }, { threshold: 0.01 }); observer.observe(document.querySelector(".hero")); observer.observe(document.querySelector(".course-bridge")); document.getElementById("close-nudge").addEventListener("click", () => { nudgeClosed = true; updateNudge(); }); })();