| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Hodensack | Where Rules Go To Die</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> |
| @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap'); |
| |
| .pixel-font { |
| font-family: 'Press Start 2P', cursive; |
| } |
| |
| .glitch { |
| position: relative; |
| } |
| |
| .glitch::before, .glitch::after { |
| content: attr(data-text); |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| } |
| |
| .glitch::before { |
| left: 2px; |
| text-shadow: -2px 0 red; |
| animation: glitch-anim 2s infinite linear alternate-reverse; |
| } |
| |
| .glitch::after { |
| left: -2px; |
| text-shadow: -2px 0 blue; |
| animation: glitch-anim 2s infinite linear alternate-reverse; |
| } |
| |
| @keyframes glitch-anim { |
| 0% { clip: rect(32px, 9999px, 28px, 0) } |
| 10% { clip: rect(13px, 9999px, 37px, 0) } |
| 20% { clip: rect(45px, 9999px, 33px, 0) } |
| 30% { clip: rect(31px, 9999px, 94px, 0) } |
| 40% { clip: rect(88px, 9999px, 98px, 0) } |
| 50% { clip: rect(9px, 9999px, 98px, 0) } |
| 60% { clip: rect(37px, 9999px, 17px, 0) } |
| 70% { clip: rect(77px, 9999px, 34px, 0) } |
| 80% { clip: rect(55px, 9999px, 49px, 0) } |
| 90% { clip: rect(10px, 9999px, 2px, 0) } |
| 100% { clip: rect(35px, 9999px, 53px, 0) } |
| } |
| |
| .server-rules li { |
| margin-bottom: 1rem; |
| position: relative; |
| padding-left: 2.5rem; |
| } |
| |
| .server-rules li::before { |
| content: ""; |
| position: absolute; |
| left: 0; |
| top: 0.25rem; |
| font-size: 1.5rem; |
| width: 2rem; |
| text-align: center; |
| } |
| |
| .blood-splatter { |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M30,15 Q40,5 50,15 Q60,5 70,15 Q80,30 70,50 Q60,70 50,85 Q40,70 30,50 Q20,30 30,15" fill="%23ff0000" opacity="0.3"/></svg>'); |
| background-size: 50px 50px; |
| background-repeat: repeat; |
| } |
| |
| .creeper-bg { |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><rect width="4" height="4" x="0" y="0" fill="%23404040"/><rect width="4" height="4" x="8" y="0" fill="%23404040"/><rect width="4" height="4" x="16" y="0" fill="%23404040"/><rect width="4" height="4" x="0" y="8" fill="%23404040"/><rect width="4" height="4" x="8" y="8" fill="%2300ff00"/><rect width="4" height="4" x="16" y="8" fill="%23404040"/><rect width="4" height="4" x="0" y="16" fill="%23404040"/><rect width="4" height="4" x="16" y="16" fill="%23404040"/></svg>'); |
| } |
| |
| |
| .form-message { |
| display: none; |
| padding: 1rem; |
| margin: 1rem 0; |
| border-radius: 4px; |
| text-align: center; |
| } |
| |
| .form-success { |
| background-color: #4CAF50; |
| color: white; |
| } |
| |
| .form-error { |
| background-color: #f44336; |
| color: white; |
| } |
| |
| |
| .player-list { |
| max-height: 200px; |
| overflow-y: auto; |
| scrollbar-width: thin; |
| scrollbar-color: #4CAF50 #2d3748; |
| } |
| |
| .player-list::-webkit-scrollbar { |
| width: 6px; |
| } |
| |
| .player-list::-webkit-scrollbar-track { |
| background: #2d3748; |
| } |
| |
| .player-list::-webkit-scrollbar-thumb { |
| background-color: #4CAF50; |
| border-radius: 6px; |
| } |
| |
| |
| .ping-indicator { |
| width: 10px; |
| height: 10px; |
| border-radius: 50%; |
| display: inline-block; |
| margin-right: 5px; |
| } |
| |
| .ping-excellent { |
| background-color: #00ff00; |
| box-shadow: 0 0 5px #00ff00; |
| } |
| |
| .ping-good { |
| background-color: #aaff00; |
| box-shadow: 0 0 5px #aaff00; |
| } |
| |
| .ping-okay { |
| background-color: #ffff00; |
| box-shadow: 0 0 5px #ffff00; |
| } |
| |
| .ping-bad { |
| background-color: #ffaa00; |
| box-shadow: 0 0 5px #ffaa00; |
| } |
| |
| .ping-terrible { |
| background-color: #ff0000; |
| box-shadow: 0 0 5px #ff0000; |
| } |
| |
| |
| @keyframes spin { |
| 0% { transform: rotate(0deg); } |
| 100% { transform: rotate(360deg); } |
| } |
| |
| .refresh-spin { |
| animation: spin 1s linear infinite; |
| } |
| |
| |
| .rule-1::before { content: "\f023"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #4CAF50; } |
| .rule-2::before { content: "\f187"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #FF9800; } |
| .rule-3::before { content: "\f086"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #9C27B0; } |
| .rule-4::before { content: "\f0e0"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #2196F3; } |
| .rule-5::before { content: "\f6e9"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #F44336; } |
| .rule-6::before { content: "\f188"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #607D8B; } |
| .rule-7::before { content: "\f1b2"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #795548; } |
| .rule-8::before { content: "\f0c2"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #00BCD4; } |
| .rule-9::before { content: "\f0eb"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #FFEB3B; } |
| .rule-10::before { content: "\f0a1"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: #E91E63; } |
| </style> |
| </head> |
| <body class="bg-black text-green-400 pixel-font creeper-bg"> |
| |
| <div class="bg-red-900 text-yellow-300 text-center py-2 px-4 text-xs"> |
| ⚠ WARNING: This server contains dark humor, offensive jokes, and questionable life choices. Enter at your own risk. |
| </div> |
|
|
| |
| <header class="container mx-auto px-4 py-8 text-center"> |
| <h1 class="glitch text-4xl md:text-6xl mb-4" data-text="HODENSACK.MC">HODENSACK</h1> |
| <p class="text-red-500 text-sm md:text-base">"We're not racist... we hate everyone equally"</p> |
| </header> |
|
|
| |
| <div class="container mx-auto px-4 mb-8"> |
| <div class="bg-gray-900 border-2 border-green-600 p-4 max-w-md mx-auto text-center"> |
| <div class="flex justify-between items-center mb-2"> |
| <div class="flex items-center"> |
| <div id="status-indicator" class="w-3 h-3 rounded-full bg-gray-500 mr-2"></div> |
| <span id="status-text">CHECKING SERVER...</span> |
| </div> |
| <button id="refresh-status" class="text-green-400 hover:text-yellow-400 text-sm"> |
| <i id="refresh-icon" class="fas fa-sync-alt"></i> REFRESH |
| </button> |
| </div> |
| <div id="server-details"> |
| <p class="text-xs">IP: <span id="server-ip">hoden-sack.g-portal.game</span></p> |
| <p class="text-xs">Version: <span id="server">1.21.5 (Fabric)</span></p> |
| <p class="text-xs">Players: <span id="player-count">0</span>/<span id="max-players">0</span></p> |
| <div id="player-list-container" class="hidden mt-2"> |
| <p class="text-xs mb-1">Online Players:</p> |
| <div id="player-list" class="player-list text-xs text-left pl-4"></div> |
| </div> |
| <p class="text-xs mt-1">Ping: <span id="server-ping">0</span>ms</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="container mx-auto px-4 mb-12"> |
| <div class="border-4 border-red-700 bg-black p-1 relative"> |
| <div class="aspect-w-16 aspect-h-9 bg-gray-800 flex items-center justify-center"> |
| <div class="text-center"> |
| <i class="fas fa-skull-crossbones text-6xl text-red-600 mb-4"></i> |
| <p class="text-xl">"Trailer coming never"</p> |
| </div> |
| </div> |
| <div class="absolute -bottom-3 -right-3 bg-yellow-400 text-black px-2 py-1 text-xs"> |
| FAKE TRAILER |
| </div> |
| </div> |
| </div> |
|
|
| |
| <section class="container mx-auto px-4 mb-12"> |
| <h2 class="text-2xl md:text-3xl text-center mb-6 glitch" data-text="WHY JOIN?">WHY JOIN?</h2> |
| |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> |
| <div class="bg-gray-900 border border-green-700 p-4"> |
| <h3 class="text-xl text-red-500 mb-2">🚫 RULES</h3> |
| <p class="text-xs">We have rules, so follow them or get your ass banned</p> |
| </div> |
| |
| <div class="bg-gray-900 border border-green-700 p-4"> |
| <h3 class="text-xl text-red-500 mb-2">💀 DARK HUMOR</h3> |
| <p class="text-xs">Our Discord is 70% offensive memes, 20% Minecraft coordinates, and 10% someone crying because their mom got gooned on</p> |
| </div> |
| |
| <div class="bg-gray-900 border border-green-700 p-4"> |
| <h3 class="text-xl text-red-500 mb-2">🧨 CHAOS GUARANTEED</h3> |
| <p class="text-xs">We kick people like Noé because they yappidy yapp yapp way too much. "That's offensive" <br/>- Shut up</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="container mx-auto px-4 mb-12 blood-splatter"> |
| <div class="bg-gray-900 border-2 border-red-700 p-6"> |
| <h2 class="text-2xl md:text-3xl text-center mb-6 glitch" data-text="SERVER RULES">SERVER RULES</h2> |
| |
| <p class="text-center mb-6 text-sm">Welcome to Hodensack! To ensure fair gameplay, please follow these rules. Violations may result in warnings or bans.</p> |
| |
| <ul class="server-rules text-xs space-y-2"> |
| <li class="rule-1"><strong>No Griefing:</strong> Do not destroy other players' buildings, structures, or landscapes. Even single blocks count.</li> |
| <li class="rule-2"><strong>No Theft:</strong> Don't take items from others' chests, furnaces, or farms - even if they're unsecured.</li> |
| <li class="rule-3"><strong>Respectful Communication:</strong> No trolling, spamming, or offensive language in chat.</li> |
| <li class="rule-4"><strong>No Harassment:</strong> No provoking, trapping, or killing without consent - not even with Redstone contraptions.</li> |
| <li class="rule-5"><strong>PvP Rules:</strong> PvP is only allowed when both parties agree. No forced PvP.</li> |
| <li class="rule-6"><strong>Banned Mods/Hacks:</strong> X-Ray, Fly, Kill-Aura etc. are prohibited. Allowed: OptiFine, Shaders, MiniMap (without radar). Generally, any mod that doesn't provide an unfair advantage.</li> |
| <li class="rule-7"><strong>Building Areas:</strong> Only build on unclaimed land. Respect others' claims and boundaries.</li> |
| <li class="rule-8"><strong>AFK Farms & Lag:</strong> No excessive Redstone contraptions. AFK farms are only allowed if they don't cause server lag.</li> |
| <li class="rule-9"><strong>Staff & Appeals:</strong> Follow staff instructions. If a violation isn't noticed, it can be reported with evidence (e.g. screenshot) for review. Harsh penalties may apply.</li> |
| <li class="rule-10"><strong>Fair Play:</strong> Don't exploit rule loopholes. Play with common sense and good sportsmanship.</li> |
| </ul> |
| |
| <div class="mt-6 text-center text-xs"> |
| <p>By joining this server, you confirm that you have read and agree to these rules.</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="container mx-auto px-4 mb-12"> |
| <h2 class="text-2xl md:text-3xl text-center mb-6 glitch" data-text="PLAYER QUOTES">PLAYER QUOTES</h2> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
| <div class="bg-gray-900 border border-yellow-500 p-4"> |
| <p class="italic mb-2">"I made that to have fun with friends. But I have found out most of them are Hurensöhne"</p> |
| <p class="text-right text-xs text-red-400">- Sexendreks (admin)</p> |
| </div> |
| |
| <div class="bg-gray-900 border border-yellow-500 p-4"> |
| <p class="italic mb-2">"This server made me question my life choices... then I built a black dick statue."</p> |
| <p class="text-right text-xs text-red-400">- KukukIsGreat (currently griefed)</p> |
| </div> |
| |
| <div class="bg-gray-900 border border-yellow-500 p-4"> |
| <p class="italic mb-2">"10/10 would get pegged again."</p> |
| <p class="text-right text-xs text-red-400">- MinecraftSiftler (our most horny member)</p> |
| </div> |
| |
| <div class="bg-gray-900 border border-yellow-500 p-4"> |
| <p class="italic mb-2">"The toxicity here is more refined than my redstone skills."</p> |
| <p class="text-right text-xs text-red-400">- Herobrine'sWaifu (spams p0rn sounds)</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <section class="container mx-auto px-4 mb-12"> |
| <div class="bg-gray-900 border-2 border-green-600 p-6 max-w-2xl mx-auto text-center"> |
| <h2 class="text-2xl md:text-3xl mb-4 glitch" data-text="WANNA JOIN?">WANNA JOIN?</h2> |
| |
| <p class="mb-6 text-sm">Drop your Minecraft username below and we might whitelist you if we're drunk enough.</p> |
| |
| |
| <div id="success-message" class="form-message form-success"> |
| Application submitted! We'll review it when we're sober. |
| </div> |
| |
| <div id="error-message" class="form-message form-error"> |
| Application submitted! We'll review it when we're sober. |
| </div> |
| |
| |
| <form id="application-form" class="max-w-md mx-auto" action="https://formsubmit.co/4778a8b5f9263a130e4879ac2f78220f" method="POST"> |
| |
| <input type="hidden" name="_subject" value="New Hodensack MC Application"> |
| <input type="hidden" name="_next" value="https://yourwebsite.com/thank-you.html"> |
| <input type="hidden" name="_captcha" value="false"> |
| <input type="hidden" name="_template" value="table"> |
| |
| <div class="mb-4"> |
| <input type="text" name="username" placeholder="Minecraft Username" class="w-full px-4 py-2 bg-black border border-green-600 text-green-400" required> |
| </div> |
| <div class="mb-4"> |
| <input type="text" name="worst_quality" placeholder="Your worst quality" class="w-full px-4 py-2 bg-black border border-green-600 text-green-400" required> |
| </div> |
| <div class="mb-4"> |
| <textarea name="why_join" placeholder="Why should we let you in? (Be funny or gtfo)" class="w-full px-4 py-2 bg-black border border-green-600 text-green-400 h-24" required></textarea> |
| </div> |
| <button type="submit" class="bg-red-700 hover:bg-red-600 text-yellow-300 px-6 py-2 border border-yellow-500"> |
| SUBMIT APPLICATION |
| </button> |
| </form> |
| |
| <div class="mt-6 text-xs"> |
| <p>Note: By applying you consent to being roasted mercilessly in our Discord.</p> |
| </div> |
| </div> |
| </section> |
|
|
| |
| <footer class="container mx-auto px-4 py-8 text-center text-xs"> |
| <div class="border-t border-green-800 pt-6"> |
| <p>Hodensack MC is not affiliated with Mojang or Microsoft. Probably for the best.</p> |
| <p class="mt-2">© 2025 Hodensack | "We're going to hell anyway"</p> |
| <div class="mt-4 flex justify-center space-x-4"> |
| <a href="#" class="text-green-400 hover:text-yellow-400"><i class="fab fa-discord"></i></a> |
| <a href="#" class="text-green-400 hover:text-yellow-400"><i class="fab fa-twitter"></i></a> |
| <a href="#" class="text-green-400 hover:text-yellow-400"><i class="fab fa-youtube"></i></a> |
| </div> |
| </div> |
| </footer> |
|
|
| |
| <div class="fixed bottom-4 right-4"> |
| <button id="nuke-button" class="bg-red-700 text-yellow-300 px-3 py-1 text-xs border border-yellow-500"> |
| <i class="fas fa-bomb mr-1"></i> EMERGENCY MAP RESET |
| </button> |
| </div> |
|
|
| <script> |
| |
| const serverIP = 'hoden-sack.g-portal.game'; |
| const statusIndicator = document.getElementById('status-indicator'); |
| const statusText = document.getElementById('status-text'); |
| const serverVersion = document.getElementById('server-version'); |
| const playerCount = document.getElementById('player-count'); |
| const maxPlayers = document.getElementById('max-players'); |
| const playerListContainer = document.getElementById('player-list-container'); |
| const playerList = document.getElementById('player-list'); |
| const serverPing = document.getElementById('server-ping'); |
| const refreshButton = document.getElementById('refresh-status'); |
| const refreshIcon = document.getElementById('refresh-icon'); |
| |
| |
| async function checkServerStatus() { |
| try { |
| |
| statusIndicator.className = 'w-3 h-3 rounded-full bg-yellow-500 mr-2 animate-pulse'; |
| statusText.textContent = 'CHECKING SERVER...'; |
| refreshIcon.className = 'fas fa-sync-alt refresh-spin'; |
| |
| |
| const response = await fetch(`https://api.mcstatus.io/v2/status/java/${serverIP}`); |
| |
| if (!response.ok) { |
| throw new Error('Server offline or not reachable'); |
| } |
| |
| const data = await response.json(); |
| |
| |
| if (data.online) { |
| statusIndicator.className = 'w-3 h-3 rounded-full bg-green-500 mr-2'; |
| statusText.textContent = 'SERVER STATUS: ONLINE'; |
| serverVersion.textContent = data.version.name || 'Unknown'; |
| playerCount.textContent = data.players.online; |
| maxPlayers.textContent = data.players.max; |
| serverPing.textContent = data.round_trip || '?'; |
| |
| |
| updatePingIndicator(data.round_trip); |
| |
| |
| if (data.players.list && data.players.list.length > 0) { |
| playerList.innerHTML = ''; |
| data.players.list.forEach(player => { |
| const playerElement = document.createElement('div'); |
| playerElement.className = 'py-1 flex items-center'; |
| playerElement.innerHTML = ` |
| <img src="https://mc-heads.net/avatar/${player.name_clean}/16" class="mr-2" alt="${player.name_clean}"> |
| ${player.name_clean} |
| `; |
| playerList.appendChild(playerElement); |
| }); |
| playerListContainer.classList.remove('hidden'); |
| } else { |
| playerListContainer.classList.add('hidden'); |
| } |
| } else { |
| throw new Error('Server offline'); |
| } |
| } catch (error) { |
| console.error('Error checking server status:', error); |
| statusIndicator.className = 'w-3 h-3 rounded-full bg-red-500 mr-2'; |
| statusText.textContent = 'SERVER STATUS: OFFLINE'; |
| serverVersion.textContent = 'Unknown'; |
| playerCount.textContent = '0'; |
| maxPlayers.textContent = '0'; |
| serverPing.textContent = '∞'; |
| playerListContainer.classList.add('hidden'); |
| } finally { |
| refreshIcon.className = 'fas fa-sync-alt'; |
| } |
| } |
| |
| |
| function updatePingIndicator(ping) { |
| if (!ping) return; |
| |
| const pingElement = document.getElementById('server-ping'); |
| |
| if (ping < 50) { |
| pingElement.className = 'ping-excellent'; |
| } else if (ping < 100) { |
| pingElement.className = 'ping-good'; |
| } else if (ping < 200) { |
| pingElement.className = 'ping-okay'; |
| } else if (ping < 300) { |
| pingElement.className = 'ping-bad'; |
| } else { |
| pingElement.className = 'ping-terrible'; |
| } |
| } |
| |
| |
| refreshButton.addEventListener('click', checkServerStatus); |
| |
| |
| document.addEventListener('DOMContentLoaded', checkServerStatus); |
| |
| |
| setInterval(checkServerStatus, 30000); |
| |
| |
| const nukeButton = document.getElementById('nuke-button'); |
| |
| nukeButton.addEventListener('click', () => { |
| |
| document.body.style.overflow = 'hidden'; |
| const explosion = document.createElement('div'); |
| explosion.className = 'fixed inset-0 bg-yellow-500 flex items-center justify-center z-50'; |
| explosion.innerHTML = ` |
| <div class="text-center"> |
| <i class="fas fa-bomb text-6xl mb-4"></i> |
| <p class="text-2xl font-bold mb-2">MAP RESET INITIATED</p> |
| <p class="text-sm">Say goodbye to your builds, nerd.</p> |
| </div> |
| `; |
| document.body.appendChild(explosion); |
| |
| |
| document.body.style.animation = 'shake 0.5s'; |
| |
| |
| setTimeout(() => { |
| explosion.remove(); |
| document.body.style.overflow = ''; |
| document.body.style.animation = ''; |
| |
| |
| alert('Just kidding... or am I? Check your builds.'); |
| }, 3000); |
| }); |
| |
| |
| const style = document.createElement('style'); |
| style.innerHTML = ` |
| @keyframes shake { |
| 0% { transform: translate(1px, 1px) rotate(0deg); } |
| 10% { transform: translate(-1px, -2px) rotate(-1deg); } |
| 20% { transform: translate(-3px, 0px) rotate(1deg); } |
| 30% { transform: translate(3px, 2px) rotate(0deg); } |
| 40% { transform: translate(1px, -1px) rotate(1deg); } |
| 50% { transform: translate(-1px, 2px) rotate(-1deg); } |
| 60% { transform: translate(-3px, 1px) rotate(0deg); } |
| 70% { transform: translate(3px, 1px) rotate(-1deg); } |
| 80% { transform: translate(-1px, -1px) rotate(1deg); } |
| 90% { transform: translate(1px, 2px) rotate(0deg); } |
| 100% { transform: translate(1px, -2px) rotate(-1deg); } |
| } |
| `; |
| document.head.appendChild(style); |
| |
| |
| const glitchElements = document.querySelectorAll('.glitch'); |
| glitchElements.forEach(el => { |
| el.addEventListener('mouseenter', () => { |
| el.style.animation = 'none'; |
| if (el.nextElementSibling && el.nextElementSibling.classList.contains('glitch')) { |
| el.nextElementSibling.style.animation = 'none'; |
| } |
| }); |
| |
| el.addEventListener('mouseleave', () => { |
| el.style.animation = ''; |
| if (el.nextElementSibling && el.nextElementSibling.classList.contains('glitch')) { |
| el.nextElementSibling.style.animation = ''; |
| } |
| }); |
| }); |
| |
| |
| const form = document.getElementById('application-form'); |
| const successMessage = document.getElementById('success-message'); |
| const errorMessage = document.getElementById('error-message'); |
| |
| if (form) { |
| form.addEventListener('submit', async (e) => { |
| e.preventDefault(); |
| |
| |
| const submitButton = form.querySelector('button[type="submit"]'); |
| const originalButtonText = submitButton.innerHTML; |
| submitButton.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> SENDING...'; |
| submitButton.disabled = true; |
| |
| try { |
| const formData = new FormData(form); |
| const response = await fetch(form.action, { |
| method: 'POST', |
| body: formData, |
| headers: { |
| 'Accept': 'application/json' |
| } |
| }); |
| |
| if (response.ok) { |
| |
| successMessage.style.display = 'block'; |
| errorMessage.style.display = 'none'; |
| form.reset(); |
| |
| |
| setTimeout(() => { |
| successMessage.style.display = 'none'; |
| }, 5000); |
| } else { |
| throw new Error('Form submission failed'); |
| } |
| } catch (error) { |
| |
| errorMessage.style.display = 'block'; |
| successMessage.style.display = 'none'; |
| |
| |
| setTimeout(() => { |
| errorMessage.style.display = 'none'; |
| }, 5000); |
| } finally { |
| |
| submitButton.innerHTML = originalButtonText; |
| submitButton.disabled = false; |
| } |
| }); |
| } |
| </script> |
| </body> |
| </html> |