| <!DOCTYPE html> |
| <html lang="uk"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Повітряна тривога - Київ та область</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| @keyframes pulse { |
| 0% { transform: scale(1); opacity: 1; } |
| 50% { transform: scale(1.05); opacity: 0.8; } |
| 100% { transform: scale(1); opacity: 1; } |
| } |
| |
| @keyframes shake { |
| 0% { transform: translateX(0); } |
| 25% { transform: translateX(-5px); } |
| 50% { transform: translateX(5px); } |
| 75% { transform: translateX(-5px); } |
| 100% { transform: translateX(0); } |
| } |
| |
| .alert-active { |
| animation: pulse 1.5s infinite, shake 0.5s infinite; |
| } |
| |
| .ukraine-gradient { |
| background: linear-gradient(135deg, #005BBB 50%, #FFD500 50%); |
| } |
| |
| .countdown-digit { |
| background: rgba(0, 0, 0, 0.7); |
| color: white; |
| border-radius: 5px; |
| padding: 0.5rem; |
| min-width: 2rem; |
| display: inline-block; |
| text-align: center; |
| } |
| </style> |
| </head> |
| <body class="font-sans bg-gray-100"> |
| <div class="container mx-auto max-w-md p-4"> |
| <div class="bg-white rounded-xl shadow-xl overflow-hidden"> |
| |
| <div class="ukraine-gradient text-white p-4 flex items-center justify-between"> |
| <div class="flex items-center"> |
| <i class="fas fa-shield-alt text-2xl mr-3"></i> |
| <div> |
| <h1 class="text-xl font-bold">Повітряна тривога</h1> |
| <p class="text-sm opacity-90">Київ та Київська область</p> |
| </div> |
| </div> |
| <div class="text-right"> |
| <div class="text-xs opacity-90" id="current-time">--:--:--</div> |
| <div class="text-xs opacity-90" id="current-date">-- --- ----</div> |
| </div> |
| </div> |
| |
| |
| <div class="p-6 text-center" id="alert-status-container"> |
| <div class="rounded-full bg-blue-100 text-blue-800 p-4 mx-auto w-32 h-32 flex items-center justify-center mb-4" id="alert-status-icon"> |
| <i class="fas fa-check-circle text-5xl"></i> |
| </div> |
| <h2 class="text-2xl font-bold mb-2" id="alert-status-text">Тривоги немає</h2> |
| <p class="text-gray-600 mb-4" id="alert-status-description">Станом на <span id="last-update">--:--</span></p> |
| |
| <div class="hidden" id="countdown-container"> |
| <p class="text-sm text-gray-600 mb-2">Тривога триває:</p> |
| <div class="flex justify-center space-x-1"> |
| <span class="countdown-digit" id="countdown-hours">00</span> |
| <span>:</span> |
| <span class="countdown-digit" id="countdown-minutes">00</span> |
| <span>:</span> |
| <span class="countdown-digit" id="countdown-seconds">00</span> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="border-t border-gray-200 p-4"> |
| <h3 class="font-semibold text-lg mb-3 flex items-center"> |
| <i class="fas fa-map-marked-alt mr-2 text-blue-600"></i> |
| Статус по районах |
| </h3> |
| |
| <div class="grid grid-cols-2 gap-2"> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Київ</span> |
| </div> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Бровари</span> |
| </div> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Ірпінь</span> |
| </div> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Буча</span> |
| </div> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Вишгород</span> |
| </div> |
| <div class="bg-green-100 text-green-800 p-2 rounded-lg flex items-center"> |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>Бориспіль</span> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="border-t border-gray-200 p-4"> |
| <h3 class="font-semibold text-lg mb-3 flex items-center"> |
| <i class="fas fa-info-circle mr-2 text-blue-600"></i> |
| Що робити під час тривоги? |
| </h3> |
| |
| <div class="space-y-3"> |
| <div class="flex items-start"> |
| <div class="bg-blue-100 text-blue-800 rounded-full w-6 h-6 flex items-center justify-center mr-2 flex-shrink-0"> |
| <i class="fas fa-running text-xs"></i> |
| </div> |
| <p>Швидко перемістіться до найближчого укриття</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-blue-100 text-blue-800 rounded-full w-6 h-6 flex items-center justify-center mr-2 flex-shrink-0"> |
| <i class="fas fa-mobile-alt text-xs"></i> |
| </div> |
| <p>Слідкуйте за офіційними джерелами інформації</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-blue-100 text-blue-800 rounded-full w-6 h-6 flex items-center justify-center mr-2 flex-shrink-0"> |
| <i class="fas fa-first-aid text-xs"></i> |
| </div> |
| <p>Майте при собі аптечку та запас води</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="border-t border-gray-200 bg-gray-50 p-3 text-center text-xs text-gray-600"> |
| <p>Дані оновлюються автоматично</p> |
| <p class="mt-1">© 2023 Україна. Героям слава! <i class="fas fa-heart text-red-500"></i></p> |
| </div> |
| </div> |
| |
| |
| <div class="mt-4 flex justify-center space-x-4"> |
| <button onclick="triggerAlert(true)" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg"> |
| Симулювати тривогу |
| </button> |
| <button onclick="triggerAlert(false)" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg"> |
| Відмінити тривогу |
| </button> |
| </div> |
| </div> |
|
|
| <script> |
| |
| function updateDateTime() { |
| const now = new Date(); |
| const timeElement = document.getElementById('current-time'); |
| const dateElement = document.getElementById('current-date'); |
| const lastUpdateElement = document.getElementById('last-update'); |
| |
| const hours = String(now.getHours()).padStart(2, '0'); |
| const minutes = String(now.getMinutes()).padStart(2, '0'); |
| const seconds = String(now.getSeconds()).padStart(2, '0'); |
| |
| const days = ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'Пятниця', 'Субота']; |
| const months = ['січня', 'лютого', 'березня', 'квітня', 'травня', 'червня', 'липня', 'серпня', 'вересня', 'жовтня', 'листопада', 'грудня']; |
| |
| timeElement.textContent = `${hours}:${minutes}:${seconds}`; |
| dateElement.textContent = `${days[now.getDay()]}, ${now.getDate()} ${months[now.getMonth()]} ${now.getFullYear()}`; |
| lastUpdateElement.textContent = `${hours}:${minutes}`; |
| } |
| |
| setInterval(updateDateTime, 1000); |
| updateDateTime(); |
| |
| |
| let alertStartTime = null; |
| let countdownInterval = null; |
| |
| function triggerAlert(active) { |
| const statusContainer = document.getElementById('alert-status-container'); |
| const statusIcon = document.getElementById('alert-status-icon'); |
| const statusText = document.getElementById('alert-status-text'); |
| const statusDescription = document.getElementById('alert-status-description'); |
| const countdownContainer = document.getElementById('countdown-container'); |
| const regionStatuses = document.querySelectorAll('.bg-green-100'); |
| |
| if (active) { |
| |
| statusContainer.classList.add('alert-active'); |
| statusIcon.className = 'rounded-full bg-red-100 text-red-800 p-4 mx-auto w-32 h-32 flex items-center justify-center mb-4 alert-active'; |
| statusIcon.innerHTML = '<i class="fas fa-exclamation-triangle text-5xl"></i>'; |
| statusText.textContent = 'Повітряна тривога!'; |
| statusText.className = 'text-2xl font-bold mb-2 text-red-600'; |
| statusDescription.innerHTML = 'Станом на <span id="last-update">' + document.getElementById('last-update').textContent + '</span>'; |
| |
| countdownContainer.classList.remove('hidden'); |
| |
| |
| regionStatuses.forEach(el => { |
| el.className = 'bg-red-100 text-red-800 p-2 rounded-lg flex items-center'; |
| el.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>' + el.textContent; |
| }); |
| |
| |
| alertStartTime = new Date(); |
| updateCountdown(); |
| countdownInterval = setInterval(updateCountdown, 1000); |
| |
| |
| playAlertSound(); |
| } else { |
| |
| statusContainer.classList.remove('alert-active'); |
| statusIcon.className = 'rounded-full bg-blue-100 text-blue-800 p-4 mx-auto w-32 h-32 flex items-center justify-center mb-4'; |
| statusIcon.innerHTML = '<i class="fas fa-check-circle text-5xl"></i>'; |
| statusText.textContent = 'Тривоги немає'; |
| statusText.className = 'text-2xl font-bold mb-2'; |
| statusDescription.innerHTML = 'Станом на <span id="last-update">' + document.getElementById('last-update').textContent + '</span>'; |
| |
| countdownContainer.classList.add('hidden'); |
| |
| |
| regionStatuses.forEach(el => { |
| el.className = 'bg-green-100 text-green-800 p-2 rounded-lg flex items-center'; |
| el.innerHTML = '<i class="fas fa-check-circle mr-2"></i>' + el.textContent; |
| }); |
| |
| |
| if (countdownInterval) { |
| clearInterval(countdownInterval); |
| } |
| } |
| } |
| |
| function updateCountdown() { |
| const now = new Date(); |
| const diff = Math.floor((now - alertStartTime) / 1000); |
| |
| const hours = Math.floor(diff / 3600); |
| const minutes = Math.floor((diff % 3600) / 60); |
| const seconds = diff % 60; |
| |
| document.getElementById('countdown-hours').textContent = String(hours).padStart(2, '0'); |
| document.getElementById('countdown-minutes').textContent = String(minutes).padStart(2, '0'); |
| document.getElementById('countdown-seconds').textContent = String(seconds).padStart(2, '0'); |
| } |
| |
| function playAlertSound() { |
| |
| const context = new (window.AudioContext || window.webkitAudioContext)(); |
| const oscillator = context.createOscillator(); |
| const gain = context.createGain(); |
| |
| oscillator.type = 'sine'; |
| oscillator.frequency.value = 800; |
| gain.gain.value = 0.1; |
| |
| oscillator.connect(gain); |
| gain.connect(context.destination); |
| |
| oscillator.start(); |
| setTimeout(() => { |
| oscillator.stop(); |
| }, 1000); |
| } |
| |
| |
| setInterval(() => { |
| if (Math.random() > 0.95) { |
| triggerAlert(true); |
| setTimeout(() => { |
| triggerAlert(false); |
| }, 30000 + Math.random() * 120000); |
| } |
| }, 60000); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Krylov/alert" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |