/* =============================================
   WEDDING SITE — АЛЕКСАНДР & ЮЛИЯ
   ============================================= */

// ---- Обратный отсчёт ----
const WEDDING_DATE = new Date('2026-08-22T16:00:00+03:00');

function updateCountdown() {
  const now = new Date();
  const diff = WEDDING_DATE - now;

  if (diff <= 0) {
    document.getElementById('countdown').innerHTML =
      '<p style="font-size:1.5rem;font-weight:700;color:var(--purple)">🎉 Сегодня наша свадьба!</p>';
    return;
  }

  const days    = Math.floor(diff / (1000 * 60 * 60 * 24));
  const hours   = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((diff % (1000 * 60)) / 1000);

  document.getElementById('cd-days').textContent    = String(days);
  document.getElementById('cd-hours').textContent   = String(hours).padStart(2, '0');
  document.getElementById('cd-minutes').textContent = String(minutes).padStart(2, '0');
  document.getElementById('cd-seconds').textContent = String(seconds).padStart(2, '0');
}

updateCountdown();
setInterval(updateCountdown, 1000);


// ---- Конфетти ----
const CONFETTI_COLORS = ['#FFD166', '#06D6A0', '#9B5DE5', '#F15BB5', '#00BBF9', '#FF6B6B'];
const CONFETTI_SHAPES = ['border-radius:2px', 'border-radius:50%', 'clip-path:polygon(50% 0%,0% 100%,100% 100%)'];

// Фоновый дождь конфетти на герое
(function spawnConfetti() {
  const container = document.getElementById('confetti');
  for (let i = 0; i < 60; i++) {
    const el = document.createElement('div');
    el.className = 'confetti-piece';
    const size = Math.random() * 8 + 6;
    el.style.cssText = `
      left: ${Math.random() * 100}%;
      width: ${size}px;
      height: ${size}px;
      background: ${CONFETTI_COLORS[Math.floor(Math.random() * CONFETTI_COLORS.length)]};
      ${CONFETTI_SHAPES[Math.floor(Math.random() * CONFETTI_SHAPES.length)]};
      animation-duration: ${Math.random() * 6 + 5}s;
      animation-delay: ${Math.random() * 8}s;
    `;
    container.appendChild(el);
  }
})();

// Взрыв конфетти из заданной точки
function burstConfetti(x, y, count = 40) {
  for (let i = 0; i < count; i++) {
    const el = document.createElement('div');
    el.className = 'confetti-burst';
    const size   = Math.random() * 9 + 5;
    const angle  = Math.random() * 360;
    const dist   = Math.random() * 160 + 60;
    const color  = CONFETTI_COLORS[Math.floor(Math.random() * CONFETTI_COLORS.length)];
    const shape  = CONFETTI_SHAPES[Math.floor(Math.random() * CONFETTI_SHAPES.length)];
    const dur    = Math.random() * 600 + 700;
    el.style.cssText = `
      position: fixed;
      left: ${x}px;
      top: ${y}px;
      width: ${size}px;
      height: ${size}px;
      background: ${color};
      ${shape};
      pointer-events: none;
      z-index: 9999;
      transform: translate(-50%, -50%);
      animation: burst ${dur}ms ease-out forwards;
      --dx: ${Math.cos(angle * Math.PI / 180) * dist}px;
      --dy: ${Math.sin(angle * Math.PI / 180) * dist}px;
    `;
    document.body.appendChild(el);
    setTimeout(() => el.remove(), dur + 50);
  }
}

// Взрыв при клике в любом месте страницы
document.addEventListener('click', (e) => {
  burstConfetti(e.clientX, e.clientY, 35);
});



// ===== ДИСКО ШАР =====
(function initDiscoBall() {
  const BALL_R   = 45;   // радиус шара (в 3 раза больше прежнего)
  const ROPE_LEN = 18;   // верёвка от низа шапки до верха шара
  const WIRE_MAX = 26;   // максимальная длина провода прожектора
  const TILE_S   = 7;    // размер зеркального тайла
  const TILE_G   = 1;    // зазор между тайлами
  const LERP_SPD = 0.10; // скорость выезда/уезда прожектора (0..1)
  const DISC_COLORS = ['#ff6b9d','#ffd166','#06d6a0','#00bbf9','#9b5de5','#ffffff','#ff9f43','#a8e6cf'];

  const cvs = document.createElement('canvas');
  cvs.id = 'disco-canvas';
  cvs.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:998;';
  document.body.appendChild(cvs);
  const ctx = cvs.getContext('2d');

  let CW = window.innerWidth, CH = 280;
  cvs.width = CW; cvs.height = CH;

  let rot    = 0;
  let glints = [];   // разлетающиеся блики
  let ballPos = null;

  // Для каждой нав-ссылки храним прогресс выезда (0 = спрятан, 1 = полностью выехал)
  // и флаг — стреляли ли мы уже бликами при этом появлении
  const projState = new Map(); // link → { progress, target, glintFired }

  function refreshPos() {
    const logo = document.querySelector('.nav-logo');
    const nav  = document.getElementById('navbar');
    if (!logo || !nav) return;
    const lr = logo.getBoundingClientRect();
    const nh = nav.getBoundingClientRect().height;
    ballPos = {
      x:        lr.left + lr.width / 2,
      ropeTopY: nh,
      ballY:    nh + ROPE_LEN + BALL_R,
      navH:     nh,
    };
  }

  window.addEventListener('resize', () => { CW = cvs.width = window.innerWidth; refreshPos(); });
  refreshPos();

  // Инициализируем состояние для каждой ссылки
  document.querySelectorAll('.nav-links a').forEach(link => {
    projState.set(link, { progress: 0, target: 0, glintFired: false });

    link.addEventListener('mouseenter', e => {
      const s = projState.get(e.currentTarget);
      if (s) { s.target = 1; }
    });
    link.addEventListener('mouseleave', e => {
      const s = projState.get(e.currentTarget);
      if (s) { s.target = 0; s.glintFired = false; }
    });
  });

  // ---- корпус прожектора Fresnel в локальных координатах (линза смотрит вправо) ----
  function drawFresnelBody() {
    const BW = 46, BH = 32, FW = 20, LR = 11;
    const FLAP_L = 22, FLAP_T = 5.5;

    ctx.shadowColor = 'rgba(0,0,0,.7)';
    ctx.shadowBlur = 14;

    // ── Шторки-барндоры (рисуем ДО корпуса — они «выходят» из него) ─
    // Верхняя шторка
    ctx.save();
    ctx.translate(BW / 2 - FW * 0.5, -BH / 2);
    ctx.rotate(-0.52);
    ctx.fillStyle = '#161616';
    ctx.strokeStyle = '#353535';
    ctx.lineWidth = 0.7;
    ctx.beginPath();
    ctx.rect(-3, -FLAP_T / 2, FLAP_L + 3, FLAP_T);
    ctx.fill(); ctx.stroke();
    // Шарнир
    ctx.fillStyle = '#444'; ctx.strokeStyle = '#666'; ctx.lineWidth = 0.5;
    ctx.beginPath(); ctx.arc(0, 0, 2.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
    // Рёбра жёсткости
    for (let i = 6; i < FLAP_L; i += 7) {
      ctx.strokeStyle = '#0e0e0e'; ctx.lineWidth = 0.6;
      ctx.beginPath(); ctx.moveTo(i, -FLAP_T / 2 + 1); ctx.lineTo(i, FLAP_T / 2 - 1); ctx.stroke();
    }
    ctx.restore();

    // Нижняя шторка
    ctx.save();
    ctx.translate(BW / 2 - FW * 0.5, BH / 2);
    ctx.rotate(0.52);
    ctx.fillStyle = '#161616';
    ctx.strokeStyle = '#353535'; ctx.lineWidth = 0.7;
    ctx.beginPath(); ctx.rect(-3, -FLAP_T / 2, FLAP_L + 3, FLAP_T);
    ctx.fill(); ctx.stroke();
    ctx.fillStyle = '#444'; ctx.strokeStyle = '#666'; ctx.lineWidth = 0.5;
    ctx.beginPath(); ctx.arc(0, 0, 2.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
    for (let i = 6; i < FLAP_L; i += 7) {
      ctx.strokeStyle = '#0e0e0e'; ctx.lineWidth = 0.6;
      ctx.beginPath(); ctx.moveTo(i, -FLAP_T / 2 + 1); ctx.lineTo(i, FLAP_T / 2 - 1); ctx.stroke();
    }
    ctx.restore();

    // Боковая шторка (правая, видна при боковом ракурсе)
    ctx.save();
    ctx.translate(BW / 2, 0);
    ctx.rotate(-0.14);
    ctx.fillStyle = '#1a1a1a'; ctx.strokeStyle = '#2e2e2e'; ctx.lineWidth = 0.7;
    ctx.beginPath(); ctx.rect(0, -BH / 2 - 1, FLAP_L * 0.55, BH + 2);
    ctx.fill(); ctx.stroke();
    ctx.restore();

    // ── Основной корпус ───────────────────────────────────────────
    // Внешний кант (тень)
    ctx.fillStyle = '#070707';
    ctx.fillRect(-BW / 2 - 1.5, -BH / 2 - 1.5, BW + 3, BH + 3);

    // Корпус с градиентом
    const bg = ctx.createLinearGradient(-BW / 2, -BH / 2, -BW / 2, BH / 2);
    bg.addColorStop(0,    '#2f2f2f');
    bg.addColorStop(0.42, '#1d1d1d');
    bg.addColorStop(1,    '#111');
    ctx.fillStyle = bg;
    ctx.fillRect(-BW / 2, -BH / 2, BW, BH);

    // Металлическая фаска сверху
    ctx.fillStyle = 'rgba(255,255,255,.08)';
    ctx.fillRect(-BW / 2, -BH / 2, BW, 2.5);
    // Тень снизу
    ctx.fillStyle = 'rgba(0,0,0,.18)';
    ctx.fillRect(-BW / 2, BH / 2 - 2.5, BW, 2.5);

    // Задняя затемнённая секция (радиатор охлаждения)
    ctx.fillStyle = 'rgba(0,0,0,.28)';
    ctx.fillRect(-BW / 2, -BH / 2, BW * 0.22, BH);
    // Рёбра радиатора
    ctx.strokeStyle = '#0c0c0c'; ctx.lineWidth = 1.2;
    for (let i = 0; i < 3; i++) {
      const sx = -BW / 2 + 4 + i * 4.5;
      ctx.beginPath(); ctx.moveTo(sx, -BH / 2 + 5); ctx.lineTo(sx, BH / 2 - 5); ctx.stroke();
    }

    // Вентиляционные прорези (средняя часть корпуса)
    ctx.strokeStyle = '#0a0a0a'; ctx.lineWidth = 1.8;
    for (let i = 0; i < 4; i++) {
      const sx = -BW / 2 + 17 + i * 6;
      if (sx > BW / 2 - FW - 5) break;
      ctx.beginPath(); ctx.moveTo(sx, -BH / 2 + 6); ctx.lineTo(sx, BH / 2 - 6); ctx.stroke();
    }

    // Логотип / шильдик на корпусе
    ctx.fillStyle = 'rgba(255,255,255,.04)';
    ctx.fillRect(-BW / 2 + 18, BH / 2 - 9, 14, 5);

    // Ручка/рукоятка сверху корпуса
    ctx.fillStyle = '#252525'; ctx.strokeStyle = '#3e3e3e'; ctx.lineWidth = 0.9;
    ctx.beginPath(); ctx.rect(-10, -BH / 2 - 10, 20, 10); ctx.fill(); ctx.stroke();
    // Насечки на ручке
    ctx.strokeStyle = '#4a4a4a'; ctx.lineWidth = 0.55;
    for (let i = -7; i <= 7; i += 3.5) {
      ctx.beginPath(); ctx.moveTo(i, -BH / 2 - 9); ctx.lineTo(i, -BH / 2 - 2); ctx.stroke();
    }

    // ── Передняя секция (корпус линзы + рамка шторок) ─────────────
    ctx.fillStyle = '#0d0d0d';
    ctx.fillRect(BW / 2 - FW, -BH / 2, FW, BH);

    // Квадратный фланец под шторки
    ctx.strokeStyle = '#2c2c2c'; ctx.lineWidth = 2;
    ctx.strokeRect(BW / 2 - FW + 2, -BH / 2 + 2, FW - 4, BH - 4);

    // Болты фланца
    [
      [BW / 2 - FW + 5, -BH / 2 + 5], [BW / 2 - FW + 5, BH / 2 - 5],
      [BW / 2 - 4,      -BH / 2 + 5], [BW / 2 - 4,       BH / 2 - 5],
    ].forEach(([bx2, by2]) => {
      ctx.beginPath(); ctx.arc(bx2, by2, 1.8, 0, Math.PI * 2);
      ctx.fillStyle = '#404040'; ctx.fill();
      ctx.strokeStyle = '#666'; ctx.lineWidth = 0.5; ctx.stroke();
      // Крест болта
      ctx.strokeStyle = '#555'; ctx.lineWidth = 0.4;
      ctx.beginPath(); ctx.moveTo(bx2 - 1.2, by2); ctx.lineTo(bx2 + 1.2, by2); ctx.stroke();
      ctx.beginPath(); ctx.moveTo(bx2, by2 - 1.2); ctx.lineTo(bx2, by2 + 1.2); ctx.stroke();
    });

    // ── Линза Fresnel ─────────────────────────────────────────────
    const lx = BW / 2 - FW / 2, ly = 0;

    // Чёрная оправа линзы
    ctx.beginPath(); ctx.arc(lx, ly, LR + 3.5, 0, Math.PI * 2);
    ctx.fillStyle = '#060606'; ctx.fill();
    ctx.strokeStyle = '#424242'; ctx.lineWidth = 1.3; ctx.stroke();

    // Внутренняя тень оправы
    ctx.beginPath(); ctx.arc(lx, ly, LR + 2, 0, Math.PI * 2);
    ctx.strokeStyle = '#1a1a1a'; ctx.lineWidth = 1; ctx.stroke();

    // Концентрические кольца Fresnel (физическая текстура линзы)
    for (let ri = LR - 0.5; ri > 1.5; ri -= 2.3) {
      ctx.beginPath(); ctx.arc(lx, ly, ri, 0, Math.PI * 2);
      const alpha = 0.05 + (LR - ri) * 0.05;
      ctx.strokeStyle = `rgba(255,200,60,${alpha})`;
      ctx.lineWidth = 1;
      ctx.stroke();
    }

    // Свечение линзы — тёплый вольфрамовый цвет
    const lg = ctx.createRadialGradient(lx - 2.5, ly - 2.5, 0, lx, ly, LR + 3.5);
    lg.addColorStop(0,    'rgba(255,255,230,1)');
    lg.addColorStop(0.22, 'rgba(255,230,140,.97)');
    lg.addColorStop(0.55, 'rgba(255,150,20,.78)');
    lg.addColorStop(0.82, 'rgba(210,60,0,.32)');
    lg.addColorStop(1,    'rgba(150,30,0,0)');
    ctx.beginPath(); ctx.arc(lx, ly, LR + 3.5, 0, Math.PI * 2);
    ctx.fillStyle = lg; ctx.fill();

    // Зеркальный блик на линзе
    ctx.beginPath(); ctx.arc(lx - 4, ly - 4, 3, 0, Math.PI * 2);
    ctx.fillStyle = 'rgba(255,255,255,.75)'; ctx.fill();
    ctx.beginPath(); ctx.arc(lx - 3, ly - 3, 1, 0, Math.PI * 2);
    ctx.fillStyle = 'rgba(255,255,255,.95)'; ctx.fill();

    // ── Вилка-держатель (yoke / U-кронштейн) ─────────────────────
    ctx.shadowBlur = 0;
    ctx.strokeStyle = '#3c3c3c'; ctx.lineWidth = 3.5;
    ctx.lineCap = 'round'; ctx.lineJoin = 'round';
    ctx.beginPath();
    ctx.moveTo(-BW / 4 + 2, -BH / 2 - 2);
    ctx.lineTo(-BW / 4 + 2, -BH / 2 - 15);
    ctx.lineTo( BW / 4 - 2, -BH / 2 - 15);
    ctx.lineTo( BW / 4 - 2, -BH / 2 - 2);
    ctx.stroke();

    // Скоба кронштейна соединяется горизонтально с креплением
    ctx.strokeStyle = '#4a4a4a'; ctx.lineWidth = 2.5;
    ctx.beginPath();
    ctx.moveTo(-BW / 4 + 2, -BH / 2 - 15);
    ctx.lineTo( BW / 4 - 2, -BH / 2 - 15);
    ctx.stroke();

    // Шарнирный болт (точка поворота прожектора в кронштейне)
    ctx.beginPath(); ctx.arc(0, -BH / 2 - 15, 4.5, 0, Math.PI * 2);
    ctx.fillStyle = '#5a5a5a'; ctx.fill();
    ctx.strokeStyle = '#888'; ctx.lineWidth = 0.9; ctx.stroke();
    ctx.strokeStyle = '#777'; ctx.lineWidth = 0.8;
    ctx.beginPath(); ctx.moveTo(-2.5, -BH / 2 - 15); ctx.lineTo(2.5, -BH / 2 - 15); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(0, -BH / 2 - 17.5); ctx.lineTo(0, -BH / 2 - 12.5); ctx.stroke();

    ctx.shadowBlur = 0;
    ctx.lineCap = 'butt';
  }

  // ---- рисуем прожектор с учётом прогресса (0..1) ----
  function drawSpotlight(link, progress) {
    if (progress < 0.01) return;

    const r       = link.getBoundingClientRect();
    const px      = r.left + r.width / 2;
    const wireY0  = ballPos.navH;
    const wireLen = WIRE_MAX * progress;
    const projX   = px;
    const projY   = wireY0 + wireLen;

    const bx = ballPos.x, by = ballPos.ballY;
    // Угол от центра прожектора к диско-шару
    const angle = Math.atan2(by - projY, bx - projX);

    // Позиция линзы в мировых координатах
    const BW = 46, FW = 20;
    const lensLocalX  = BW / 2 - FW / 2;
    const lensWX = projX + Math.cos(angle) * lensLocalX;
    const lensWY = projY + Math.sin(angle) * lensLocalX;

    ctx.save();
    ctx.globalAlpha = Math.pow(progress, 0.65);

    // ── Конус света (рисуем ДО корпуса, чтобы корпус был поверх) ──
    const dx      = bx - lensWX, dy = by - lensWY;
    const beamLen = Math.sqrt(dx * dx + dy * dy);
    const beamAng = Math.atan2(dy, dx);
    const ha      = 0.20;

    const beam = ctx.createLinearGradient(lensWX, lensWY, bx, by);
    beam.addColorStop(0,    'rgba(255,245,180,.60)');
    beam.addColorStop(0.5,  'rgba(255,230,120,.15)');
    beam.addColorStop(1,    'rgba(255,200,50,.02)');

    ctx.beginPath();
    ctx.moveTo(lensWX, lensWY);
    ctx.lineTo(lensWX + Math.cos(beamAng - ha) * beamLen, lensWY + Math.sin(beamAng - ha) * beamLen);
    ctx.lineTo(lensWX + Math.cos(beamAng + ha) * beamLen, lensWY + Math.sin(beamAng + ha) * beamLen);
    ctx.closePath();
    ctx.fillStyle = beam;
    ctx.fill();

    // ── Провод (прямо вниз, к центру корпуса) ────────────────────
    ctx.strokeStyle = 'rgba(45,45,45,.92)';
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(px, wireY0);
    ctx.lineTo(projX, projY);
    ctx.stroke();

    // ── Корпус прожектора ─────────────────────────────────────────
    ctx.translate(projX, projY);
    ctx.rotate(angle);
    drawFresnelBody();

    ctx.restore();
  }

  // ---- рисуем шар ----
  function drawBall() {
    const cx = ballPos.x, cy = ballPos.ballY;

    // Верёвка
    ctx.save();
    ctx.strokeStyle = 'rgba(110,85,60,.9)';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(cx, ballPos.ropeTopY);
    ctx.lineTo(cx, cy - BALL_R);
    ctx.stroke();
    ctx.restore();

    // Клип по кругу
    ctx.save();
    ctx.beginPath();
    ctx.arc(cx, cy, BALL_R, 0, Math.PI * 2);
    ctx.clip();

    // Металлическая основа
    const base = ctx.createRadialGradient(cx - BALL_R * 0.28, cy - BALL_R * 0.3, 0, cx, cy, BALL_R);
    base.addColorStop(0,   '#e8e8e8');
    base.addColorStop(0.35,'#999');
    base.addColorStop(1,   '#0e0e0e');
    ctx.fillStyle = base;
    ctx.fillRect(cx - BALL_R, cy - BALL_R, BALL_R * 2, BALL_R * 2);

    // Суммарный прогресс всех прожекторов (0 = ни одного, 1+ = полностью активны)
    let totalProj = 0;
    projState.forEach(s => { totalProj += s.progress; });
    const colorMix = Math.min(1, totalProj); // 0 = только белый, 1 = полные цвета

    // Вспомогательная функция: смешать hex-цвет с белым по коэффициенту t (0=белый, 1=цвет)
    function mixWithWhite(hex, t) {
      const r = parseInt(hex.slice(1, 3), 16);
      const g = parseInt(hex.slice(3, 5), 16);
      const b = parseInt(hex.slice(5, 7), 16);
      const ri = Math.round(r + (255 - r) * (1 - t));
      const gi = Math.round(g + (255 - g) * (1 - t));
      const bi = Math.round(b + (255 - b) * (1 - t));
      return `rgb(${ri},${gi},${bi})`;
    }

    // Зеркальные тайлы
    const step = TILE_S + TILE_G;
    for (let ty = -BALL_R; ty < BALL_R; ty += step) {
      for (let tx = -BALL_R; tx < BALL_R; tx += step) {
        if (tx * tx + ty * ty >= BALL_R * BALL_R) continue;

        const angle = Math.atan2(ty, tx);
        const dist  = Math.sqrt(tx * tx + ty * ty) / BALL_R;

        const ci = (
          (Math.floor((angle + rot * 2.5) / (Math.PI / 4)) % DISC_COLORS.length + DISC_COLORS.length)
          % DISC_COLORS.length + Math.floor(dist * 3)
        ) % DISC_COLORS.length;

        const bright = 0.18 + 0.82 * Math.max(0, Math.cos(angle - rot * 1.5));
        const boost  = Math.min(0.35, totalProj * 0.25);

        // Без прожектора — серебристо-белые тайлы; с прожектором — цветные
        const tileColor = colorMix < 0.01
          ? `hsl(0,0%,${Math.round(55 + bright * 45)}%)`
          : mixWithWhite(DISC_COLORS[ci], colorMix);

        ctx.fillStyle   = tileColor;
        ctx.globalAlpha = Math.min(1, bright + boost) * 0.90;
        ctx.fillRect(cx + tx, cy + ty, TILE_S, TILE_S);
      }
    }
    ctx.globalAlpha = 1;

    // Глянцевый блик (объём)
    const shine = ctx.createRadialGradient(cx - BALL_R * 0.32, cy - BALL_R * 0.38, 0, cx, cy, BALL_R);
    shine.addColorStop(0,    'rgba(255,255,255,.72)');
    shine.addColorStop(0.25, 'rgba(255,255,255,.07)');
    shine.addColorStop(1,    'rgba(0,0,0,.55)');
    ctx.fillStyle = shine;
    ctx.fillRect(cx - BALL_R, cy - BALL_R, BALL_R * 2, BALL_R * 2);

    ctx.restore();

    // Крепёжный колпачок
    ctx.save();
    ctx.fillStyle = '#bbb';
    ctx.beginPath();
    ctx.arc(cx, cy - BALL_R + 3, 5, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();
  }

  // ---- орбитальные блики (масштаб зависит от суммы прожекторов) ----
  function drawOrbitGlints() {
    let totalProj = 0;
    projState.forEach(s => { totalProj += s.progress; });
    if (totalProj < 0.05) return;

    const cx = ballPos.x, cy = ballPos.ballY;
    const count = 12;
    for (let i = 0; i < count; i++) {
      const a  = rot * 4 + i * ((Math.PI * 2) / count);
      const r  = BALL_R + 6 + 4 * Math.sin(rot * 5 + i * 1.1);
      const sx = cx + Math.cos(a) * r;
      const sy = cy + Math.sin(a) * r * 0.5;
      const al = totalProj * (0.3 + 0.7 * Math.abs(Math.sin(rot * 9 + i * 1.5)));
      ctx.beginPath();
      ctx.arc(sx, sy, 2.2, 0, Math.PI * 2);
      ctx.fillStyle   = DISC_COLORS[i % DISC_COLORS.length];
      ctx.globalAlpha = Math.min(1, al);
      ctx.fill();
    }
    ctx.globalAlpha = 1;
  }

  // ---- основной цикл ----
  function loop() {
    ctx.clearRect(0, 0, CW, CH);
    rot += 0.007;

    if (!ballPos) { refreshPos(); requestAnimationFrame(loop); return; }

    // Обновляем прогресс каждого прожектора (плавный выезд/заезд)
    projState.forEach((s, link) => {
      s.progress += (s.target - s.progress) * LERP_SPD;

      // Стреляем бликами когда прожектор почти полностью выехал
      if (s.progress > 0.85 && !s.glintFired) {
        s.glintFired = true;
        for (let i = 0; i < 16; i++) {
          const a = Math.random() * Math.PI * 2;
          glints.push({
            x: ballPos.x, y: ballPos.ballY,
            vx: Math.cos(a) * (Math.random() * 5 + 1.5),
            vy: Math.sin(a) * (Math.random() * 5 + 1.5) - 1.5,
            life: 1, decay: 0.022 + Math.random() * 0.025,
            color: DISC_COLORS[Math.floor(Math.random() * DISC_COLORS.length)],
            r: 1.5 + Math.random() * 2.5,
          });
        }
      }

      // Рисуем прожектор с текущим прогрессом
      drawSpotlight(link, s.progress);
    });

    // Шар на верёвке
    drawBall();

    // Орбитальные блики (перед шаром)
    drawOrbitGlints();

    // Разлетающиеся блики
    glints = glints.filter(g => g.life > 0);
    glints.forEach(g => {
      ctx.beginPath();
      ctx.arc(g.x, g.y, g.r, 0, Math.PI * 2);
      ctx.fillStyle   = g.color;
      ctx.globalAlpha = g.life;
      ctx.fill();
      ctx.globalAlpha = 1;
      g.x  += g.vx;
      g.y  += g.vy;
      g.vy += 0.09;
      g.life -= g.decay;
    });

    requestAnimationFrame(loop);
  }

  loop();
})();


// ---- Навигация: бургер-меню ----
const burger    = document.getElementById('burger');
const navLinks  = document.getElementById('nav-links');

burger.addEventListener('click', () => {
  navLinks.classList.toggle('open');
});

// Закрыть меню при клике на ссылку
navLinks.querySelectorAll('a').forEach(link => {
  link.addEventListener('click', () => navLinks.classList.remove('open'));
});


// ---- Навигация: тень при прокрутке ----
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
  navbar.classList.toggle('scrolled', window.scrollY > 20);
});


// ---- FAQ: аккордеон ----
document.querySelectorAll('.faq-question').forEach(btn => {
  btn.addEventListener('click', () => {
    const expanded = btn.getAttribute('aria-expanded') === 'true';
    const answer   = btn.nextElementSibling;

    document.querySelectorAll('.faq-question').forEach(b => {
      b.setAttribute('aria-expanded', 'false');
      b.nextElementSibling.classList.remove('open');
    });

    if (!expanded) {
      btn.setAttribute('aria-expanded', 'true');
      answer.classList.add('open');
    }
  });
});




// ---- Яндекс.Карта: проверка загрузки iframe ----
const ymapFrame   = document.getElementById('ymap-frame');
const mapFallback = document.getElementById('map-fallback');

// Подставляем реальный iframe с картой через Yandex Maps short link
// Если embed не поддерживается — показываем кнопку
if (ymapFrame) {
  mapFallback.style.display = 'none';
}


// ---- Галерея: лайтбокс ----
const lightbox = document.getElementById('lightbox');
const lightboxImg = lightbox?.querySelector('.lightbox-img');
const galleryItems = Array.from(document.querySelectorAll('.gallery-item'));
let lightboxIndex = 0;

function openLightbox(index) {
  if (!lightbox || !lightboxImg || !galleryItems.length) return;
  lightboxIndex = index;
  const img = galleryItems[lightboxIndex].querySelector('img');
  lightboxImg.src = img.src;
  lightboxImg.alt = img.alt;
  lightbox.hidden = false;
  lightbox.setAttribute('aria-hidden', 'false');
  document.body.style.overflow = 'hidden';
}

function closeLightbox() {
  if (!lightbox) return;
  lightbox.hidden = true;
  lightbox.setAttribute('aria-hidden', 'true');
  lightboxImg.src = '';
  document.body.style.overflow = '';
}

function showLightboxStep(delta) {
  if (!galleryItems.length) return;
  lightboxIndex = (lightboxIndex + delta + galleryItems.length) % galleryItems.length;
  const img = galleryItems[lightboxIndex].querySelector('img');
  lightboxImg.src = img.src;
  lightboxImg.alt = img.alt;
}

galleryItems.forEach((item, index) => {
  item.addEventListener('click', () => openLightbox(index));
});

lightbox?.querySelector('.lightbox-close')?.addEventListener('click', closeLightbox);
lightbox?.querySelector('.lightbox-prev')?.addEventListener('click', () => showLightboxStep(-1));
lightbox?.querySelector('.lightbox-next')?.addEventListener('click', () => showLightboxStep(1));

lightbox?.addEventListener('click', (e) => {
  if (e.target === lightbox) closeLightbox();
});

document.addEventListener('keydown', (e) => {
  if (lightbox?.hidden) return;
  if (e.key === 'Escape') closeLightbox();
  if (e.key === 'ArrowLeft') showLightboxStep(-1);
  if (e.key === 'ArrowRight') showLightboxStep(1);
});

// ---- Плавное появление секций при прокрутке ----
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible');
        observer.unobserve(entry.target);
      }
    });
  },
  { threshold: 0.1 }
);

document.querySelectorAll('.timeline-card, .faq-item, .gallery-item, .coordinator-card, .stat-card, .stats-two-col').forEach(el => {
  el.style.opacity = '0';
  el.style.transform = 'translateY(24px)';
  el.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
  observer.observe(el);
});

document.addEventListener('animationend', () => {}, { once: true });

// Добавляем класс visible через CSS
const style = document.createElement('style');
style.textContent = '.visible { opacity: 1 !important; transform: none !important; }';
document.head.appendChild(style);
