Перед закрывающим тегом </body> добавляем такой элемент:

<div class="snowflakes-container" id="snowflakes"></div>

Добавляем следующие стили:

.snowflake {
  position: fixed;
  top: -20px;
  z-index: 9999;
  user-select: none;
  pointer-events: none;
  color: #fff;
  font-size: 1.2em;
  opacity: 0.8;
  text-shadow: 0 0 5px rgba(255,255,255,0.7);
  animation: fall linear infinite;
}

@keyframes fall {
  to {
    transform: translateY(105vh) rotate(360deg);
  }
}

Ну и наконец такой скрипт:

document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('snowflakes');
  const snowflakeChars = ['', '', '', '', ''];
  const count = window.innerWidth < 768 ? 15 : 30; // меньше на мобильных

  for (let i = 0; i < count; i++) {
    const snow = document.createElement('div');
    snow.classList.add('snowflake');
    snow.innerHTML = snowflakeChars[Math.floor(Math.random() * snowflakeChars.length)];
    
    // Случайное положение по X
    snow.style.left = Math.random() * 100 + 'vw';
    
    // Случайный размер
    const size = 0.6 + Math.random() * 0.8;
    snow.style.fontSize = size + 'em';
    
    // Случайная прозрачность
    snow.style.opacity = 0.4 + Math.random() * 0.6;
    
    // Случайная длительность анимации (5–15 сек)
    const duration = 5 + Math.random() * 10;
    snow.style.animationDuration = duration + 's';
    
    // Случайная задержка (для "неравномерного" старта)
    snow.style.animationDelay = Math.random() * 5 + 's';
    
    container.appendChild(snow);
  }
});

Этот код создаёт лёгкие снежинки, падающие с разной скоростью и прозрачностью. Он не требует подключения сторонних библиотек и работает «из коробки». Падающие снежинки — это простой, но эффектный способ сделать ваш сайт по-новогоднему уютным.