Offline page 2

HTML Code Showcase

Offline Webpage

HTML Code

<!DOCTYPE html>
<html lang="hi">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, user-scalable=no"
    />
    <title>आप ऑफ़लाइन हैं</title>

    <!-- Google Fonts -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Noto+Sans+Devanagari:wght@400;500&display=swap"
      rel="stylesheet"
    />

    <style>
      :root {
        --primary-color: #6f0ff9;
        --primary-light: #8b49ff;
        --primary-lighter: #f8f4ff;
        --primary-border: #eae0fe;
        --background-color: #f0f2f5;
        --white-color: #ffffff;
        --text-dark: #333333;
        --text-light: #555555;
        --text-subtle: #888888;

        --font-primary: "Poppins", sans-serif;
        --font-secondary: "Noto Sans Devanagari", sans-serif;

        --shadow-light: 0 4px 15px rgba(0, 0, 0, 0.05);
        --shadow-medium: 0 8px 25px rgba(0, 0, 0, 0.1);
        --shadow-strong: 0 5px 15px rgba(111, 15, 249, 0.4);

        --space-sm: 8px;
        --space-md: 16px;
        --space-lg: 24px;
        --space-xl: 32px;

        --border-radius-sm: 10px;
        --border-radius-md: 20px;

        --transition-smooth: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
      }

      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      html,
      body {
        font-family: var(--font-primary);
        color: var(--text-light);
        height: 100%;
        overflow: hidden;
        background-color: var(--background-color);
        background-image: radial-gradient(
          circle at 25% 15%,
          var(--primary-lighter) 0%,
          var(--background-color) 25%
        );
      }

      /* Particle Container */
      .particles-container {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 1;
        pointer-events: none;
      }

      .particle {
        position: absolute;
        border-radius: 50%;
        /* New particle color as requested */
        background-color: var(--primary-color);
        opacity: 0;
        /* New animation for random movement and fading */
        animation: moveAndFade 20s infinite;
      }

      /* New Keyframes for random movement and fading */
      @keyframes moveAndFade {
        0% {
          transform: translate(0, 0);
          opacity: 0;
        }
        25% {
          transform: translate(var(--x1), var(--y1));
          opacity: 0.7;
        }
        50% {
          transform: translate(var(--x2), var(--y2));
          opacity: 0;
        }
        75% {
          transform: translate(var(--x3), var(--y3));
          opacity: 0.5;
        }
        100% {
          transform: translate(var(--x4), var(--y4));
          opacity: 0;
        }
      }

      /* Main Container */
      .container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 100%;
        padding: var(--space-md);
        text-align: center;
        position: relative;
        z-index: 2;
      }

      .offline-card {
        background-color: var(--white-color);
        border-radius: var(--border-radius-md);
        padding: var(--space-xl);
        width: 100%;
        max-width: 420px;
        box-shadow: var(--shadow-medium);
        border: 1px solid var(--primary-border);
        transform: scale(0.95);
        opacity: 0;
        animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.2s
          forwards;
      }

      @keyframes popIn {
        to {
          opacity: 1;
          transform: scale(1);
        }
      }

      .icon-container {
        margin-bottom: var(--space-lg);
      }

      .icon-pulse {
        width: 100px;
        height: 100px;
        border-radius: 50%;
        background-color: var(--primary-lighter);
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0 auto;
        position: relative;
      }

      .icon-pulse::before,
      .icon-pulse::after {
        content: "";
        position: absolute;
        border: 1px solid var(--primary-light);
        width: 100%;
        height: 100%;
        border-radius: 50%;
        animation: pulse 3s ease-out infinite;
        opacity: 0;
      }

      .icon-pulse::after {
        animation-delay: 1.5s;
      }

      @keyframes pulse {
        0% {
          transform: scale(0.9);
          opacity: 0;
        }
        50% {
          opacity: 0.6;
        }
        100% {
          transform: scale(1.5);
          opacity: 0;
        }
      }

      .offline-icon {
        width: 50px;
        height: 50px;
        stroke: var(--primary-color);
      }

      .title {
        font-size: 2rem;
        font-weight: 600;
        margin-bottom: var(--space-sm);
        color: var(--text-dark);
      }

      .message {
        font-size: 1rem;
        line-height: 1.6;
        margin-bottom: var(--space-lg);
        color: var(--text-light);
        font-family: var(--font-secondary);
      }

      .retry-button {
        background-color: var(--primary-color);
        color: var(--white-color);
        border: none;
        border-radius: var(--border-radius-sm);
        padding: 12px var(--space-lg);
        font-size: 1rem;
        font-weight: 500;
        cursor: pointer;
        transition: var(--transition-smooth);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-sm);
        box-shadow: var(--shadow-light);
      }

      .retry-button:hover {
        background-color: var(--primary-light);
        transform: translateY(-3px);
        box-shadow: var(--shadow-strong);
      }

      .retry-button:active {
        transform: translateY(0);
        box-shadow: var(--shadow-light);
      }

      .retry-button.loading {
        pointer-events: none;
        background-color: var(--text-subtle);
      }

      .spinner {
        width: 18px;
        height: 18px;
        border: 2px solid transparent;
        border-top-color: var(--white-color);
        border-radius: 50%;
        animation: spin 0.8s linear infinite;
        display: none;
      }

      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }

      /* == FIX: Card was disappearing on small screens == */
      @media (max-width: 480px) {
        .offline-card {
          padding: var(--space-lg) var(--space-md);
          /* The following lines were removed to keep the card visible */
          /* border: none; */
          /* box-shadow: none; */
          /* background: transparent; */
        }
        .title {
          font-size: 1.5rem;
        }
        .message {
          font-size: 0.9rem;
        }
        .icon-pulse {
          width: 80px;
          height: 80px;
        }
        .offline-icon {
          width: 40px;
          height: 40px;
        }
      }
    </style>
  </head>
  <body>
    <div class="particles-container" id="particles-container"></div>
    <div class="container">
      <div class="offline-card">
        <div class="icon-container">
          <div class="icon-pulse">
            <svg
              class="offline-icon"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"></path>
              <line x1="1" y1="1" x2="23" y2="23"></line>
            </svg>
          </div>
        </div>

        <h1 class="title" id="title">आप ऑफ़लाइन हैं</h1>
        <p class="message" id="message">
          कृपया अपना इंटरनेट कनेक्शन जांचें और ऑनलाइन होने पर फिर से प्रयास
          करें।
        </p>

        <button id="retry-button" class="retry-button">
          <span class="spinner"></span>
          <span id="button-text">फिर से प्रयास करें</span>
        </button>
      </div>
    </div>

    <script>
      const retryButton = document.getElementById("retry-button");
      const buttonText = document.getElementById("button-text");
      const spinner = document.querySelector(".spinner");
      const title = document.getElementById("title");
      const message = document.getElementById("message");
      const particlesContainer = document.getElementById("particles-container");

      let wasOnline = navigator.onLine;

      const translations = {
        en: {
          title: "You're Offline",
          message:
            "Please check your internet connection and try again when you're back online.",
          retry: "Retry",
          checking: "Checking...",
        },
        hi: {
          title: "आप ऑफ़लाइन हैं",
          message:
            "कृपया अपना इंटरनेट कनेक्शन जांचें और ऑनलाइन होने पर फिर से प्रयास करें।",
          retry: "फिर से प्रयास करें",
          checking: "जाँच हो रही है...",
        },
      };

      function setLanguage() {
        const userLang = navigator.language.toLowerCase().substring(0, 2);
        const lang = ["hi"].includes(userLang) ? userLang : "en";
        document.documentElement.lang = lang;
        title.textContent = translations[lang].title;
        message.textContent = translations[lang].message;
        buttonText.textContent = translations[lang].retry;
      }

      // --- New and Improved Particle Background Effect ---
      function createParticles() {
        // Increase particle count for "dheer saare" effect
        const particleCount = Math.floor(window.innerWidth / 15);
        particlesContainer.innerHTML = ""; // Clear old particles

        for (let i = 0; i < particleCount; i++) {
          const particle = document.createElement("div");
          particle.classList.add("particle");

          const size = Math.random() * 5 + 2; // Size: 2px to 7px
          particle.style.width = `${size}px`;
          particle.style.height = `${size}px`;

          // Start position anywhere on the screen
          particle.style.top = `${Math.random() * 100}vh`;
          particle.style.left = `${Math.random() * 100}vw`;

          // Random destinations for the keyframe animation
          const randomRange = 150;
          particle.style.setProperty(
            "--x1",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--y1",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--x2",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--y2",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--x3",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--y3",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--x4",
            `${Math.random() * randomRange - randomRange / 2}px`
          );
          particle.style.setProperty(
            "--y4",
            `${Math.random() * randomRange - randomRange / 2}px`
          );

          // Animation properties for variety
          const duration = Math.random() * 15 + 10; // Duration: 10s to 25s
          const delay = Math.random() * 10; // Delay: 0s to 10s

          particle.style.animationDuration = `${duration}s`;
          particle.style.animationDelay = `${delay}s`;

          particlesContainer.appendChild(particle);
        }
      }

      function updateOnlineStatus() {
        const isOnline = navigator.onLine;
        if (isOnline && !wasOnline) {
          document.body.style.transition = "opacity 0.5s ease-in-out";
          document.body.style.opacity = "0";
          setTimeout(() => {
            location.reload();
          }, 500);
        }
        wasOnline = isOnline;
      }

      function handleRetry() {
        retryButton.classList.add("loading");
        spinner.style.display = "inline-block";
        const userLang = document.documentElement.lang;
        buttonText.textContent = translations[userLang].checking;

        setTimeout(() => {
          if (navigator.onLine) {
            location.reload();
          } else {
            retryButton.classList.remove("loading");
            spinner.style.display = "none";
            buttonText.textContent = translations[userLang].retry;

            retryButton.animate(
              [
                { transform: "translateX(-6px)" },
                { transform: "translateX(6px)" },
                { transform: "translateX(-6px)" },
                { transform: "translateX(0)" },
              ],
              { duration: 400, easing: "ease-in-out" }
            );
          }
        }, 1500);
      }

      function init() {
        setLanguage();
        createParticles();

        window.addEventListener("online", updateOnlineStatus);
        window.addEventListener("offline", updateOnlineStatus);
        retryButton.addEventListener("click", handleRetry);
        // Regenerate particles on resize to fit the new screen size
        window.addEventListener("resize", createParticles);
      }

      window.addEventListener("load", init);
    </script>
  </body>
</html>
            

Comments

Popular Posts

Offline Page

15 August Code

Portfolio Website