/* Дом Дракона — main.js */ (function () { 'use strict'; /* ---------- Бургер-меню ---------- */ var burger = document.getElementById('burger'); var mnav = document.getElementById('mobile-nav'); if (burger && mnav) { burger.addEventListener('click', function () { var open = burger.classList.toggle('open'); mnav.classList.toggle('open', open); burger.setAttribute('aria-expanded', open ? 'true' : 'false'); document.body.style.overflow = open ? 'hidden' : ''; }); mnav.querySelectorAll('a').forEach(function (a) { a.addEventListener('click', function () { burger.classList.remove('open'); mnav.classList.remove('open'); document.body.style.overflow = ''; }); }); } /* ---------- Тлеющие угли в hero ---------- */ var embers = document.getElementById('embers'); if (embers && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) { var count = window.innerWidth < 600 ? 14 : 26; for (var i = 0; i < count; i++) { var p = document.createElement('span'); p.className = 'ember-particle'; p.style.left = Math.random() * 100 + '%'; var dur = 6 + Math.random() * 8; p.style.animationDuration = dur + 's'; p.style.animationDelay = -(Math.random() * dur) + 's'; var size = 2 + Math.random() * 2.5; p.style.width = size + 'px'; p.style.height = size + 'px'; if (Math.random() > 0.6) p.style.background = 'var(--gold)'; embers.appendChild(p); } } /* ---------- Хедер: тень при скролле ---------- */ var header = document.getElementById('site-header'); if (header) { var onScroll = function () { if (window.scrollY > 20) header.style.boxShadow = '0 10px 40px -20px rgba(0,0,0,.9)'; else header.style.boxShadow = 'none'; }; window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); } /* ---------- Scroll reveal ---------- */ var reveals = document.querySelectorAll('.reveal'); if ('IntersectionObserver' in window && reveals.length) { var io = new IntersectionObserver(function (entries) { entries.forEach(function (en) { if (en.isIntersecting) { en.target.style.animationDelay = (Math.random() * 0.15) + 's'; en.target.classList.add('in'); io.unobserve(en.target); } }); }, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }); reveals.forEach(function (el) { io.observe(el); }); } else { reveals.forEach(function (el) { el.classList.add('in'); }); } /* ---------- Голосование ---------- */ document.querySelectorAll('.vote-widget').forEach(function (w) { var type = w.getAttribute('data-type'); var id = w.getAttribute('data-id'); w.querySelectorAll('.vote-btn').forEach(function (btn) { btn.addEventListener('click', function () { var vote = btn.getAttribute('data-vote'); var fd = new FormData(); fd.append('action', 'vote'); fd.append('type', type); fd.append('id', id); fd.append('vote', vote); btn.disabled = true; fetch('/ajax', { method: 'POST', body: fd }) .then(function (r) { return r.json(); }) .then(function (d) { btn.disabled = false; if (!d.ok) return; w.querySelector('.vote-likes .v-count').textContent = d.likes; w.querySelector('.vote-dislikes .v-count').textContent = d.dislikes; w.querySelector('.vote-likes').classList.toggle('voted', d.user === 'like'); w.querySelector('.vote-dislikes').classList.toggle('voted', d.user === 'dislike'); }) .catch(function () { btn.disabled = false; }); }); }); }); /* ---------- Комментарии ---------- */ var cform = document.getElementById('comment-form'); if (cform) { cform.addEventListener('submit', function (ev) { ev.preventDefault(); var type = cform.getAttribute('data-type'); var id = cform.getAttribute('data-id'); var author = cform.querySelector('[name=author]').value.trim(); var content = cform.querySelector('[name=content]').value.trim(); if (author.length < 2 || content.length < 3) return; var fd = new FormData(); fd.append('action', 'comment'); fd.append('type', type); fd.append('id', id); fd.append('author', author); fd.append('content', content); var btn = cform.querySelector('button[type=submit]'); btn.disabled = true; btn.textContent = 'Отправка…'; fetch('/ajax', { method: 'POST', body: fd }) .then(function (r) { return r.json(); }) .then(function (d) { btn.disabled = false; btn.textContent = 'Отправить комментарий'; if (!d.ok) { var msg = d.error === 'too_fast' ? 'Слишком часто. Подождите немного.' : d.error === 'too_short' ? 'Заполните поля корректно.' : 'Ошибка отправки.'; showFormNote(cform, msg, false); return; } cform.reset(); showFormNote(cform, d.moderated ? 'Комментарий отправлен на модерацию. Спасибо!' : 'Комментарий опубликован!', true); }) .catch(function () { btn.disabled = false; btn.textContent = 'Отправить комментарий'; showFormNote(cform, 'Ошибка соединения.', false); }); }); } function showFormNote(form, text, ok) { var note = form.querySelector('.form-note-dynamic'); if (!note) { note = document.createElement('div'); note.className = 'form-note-dynamic'; note.style.cssText = 'margin-top:12px;padding:12px 16px;border-radius:8px;font-size:.9rem'; form.appendChild(note); } note.style.background = ok ? 'rgba(201,168,106,.12)' : 'rgba(185,29,12,.12)'; note.style.color = ok ? 'var(--gold-bright)' : 'var(--ember)'; note.textContent = text; setTimeout(function () { if (note) note.remove(); }, 6000); } })();