Review the whole codes given throughly and then Fix it all thoroughly. Make it work properly. Send the fully working full code. <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Light Novel Library</title>

  <!-- Preconnect for performance -->
  <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  
  <!-- Load Fonts with swap to ensure text visibility -->
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">

  <!-- External Libraries -->
  
  <script src="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js" ></script>
  
  <!-- AOS CSS -->
  <link href="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.css" rel="stylesheet">

  <!-- Stylesheet -->
  <style>
    /* Root Variables */
    :root {
      --primary-color: #ffffff;
      --secondary-color: #000000;
      --background-color: #121212;
      --card-background: #1e1e1e;
      --text-primary: #ffffff;
      --text-secondary: #bbbbbb;
      --border-color: #333333;
      --shadow-sm: 0 1px 3px rgba(255,255,255,0.1);
      --shadow-md: 0 4px 6px rgba(255,255,255,0.1);
      --shadow-lg: 0 10px 15px rgba(255,255,255,0.1);
      --radius-sm: 0.375rem;
      --radius-md: 0.5rem;
      --radius-lg: 1rem;
      --transition-duration: 0.3s;
      --max-width: 1280px;
      --header-height: 80px;
      --toast-background: rgba(0, 0, 0, 0.8);
      --toast-color: #ffffff;
      --font-family: 'Inter', sans-serif;
    }

    /* Light Theme Variables */
    [data-theme="light"] {
      --primary-color: #000000;
      --secondary-color: #ffffff;
      --background-color: #f0f4f8;
      --card-background: #ffffff;
      --text-primary: #1f2937;
      --text-secondary: #6b7280;
      --border-color: #dddddd;
      --shadow-sm: 0 1px 3px rgba(0,0,0,0.12);
      --shadow-md: 0 4px 6px rgba(0,0,0,0.1);
      --shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
      --toast-background: rgba(255, 255, 255, 0.9);
      --toast-color: #000000;
    }

    /* Reset and Base Styles */
    *, ::before, ::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      font-family: var(--font-family);
      background-color: var(--background-color);
      color: var(--text-primary);
      line-height: 1.6;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
    }

    /* Header Styles */
    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 1rem 2rem;
      background-color: var(--card-background);
      box-shadow: var(--shadow-sm);
      border-radius: var(--radius-md);
      position: sticky;
      top: 0;
      z-index: 1000;
      transition: background-color var(--transition-duration) ease;
    }

    .header__title {
      font-size: 1.75rem;
      font-weight: 700;
      color: var(--text-primary);
    }

    /* Toggle Switch Styles */
    .toggle-switch {
      position: relative;
      display: inline-block;
      width: 60px;
      height: 34px;
    }

    .toggle-switch input {
      opacity: 0;
      width: 0;
      height: 0;
    }

    .slider {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: var(--border-color);
      transition: background-color var(--transition-duration) ease;
      border-radius: 34px;
    }

    .slider::before {
      position: absolute;
      content: "";
      height: 26px;
      width: 26px;
      left: 4px;
      bottom: 4px;
      background-color: var(--secondary-color);
      transition: transform var(--transition-duration) ease, background-color var(--transition-duration) ease;
      border-radius: 50%;
    }

    input:checked + .slider {
      background-color: var(--primary-color);
    }

    input:checked + .slider::before {
      transform: translateX(26px);
      background-color: var(--secondary-color);
    }

    /* Main Content Styles */
    .main {
      flex: 1;
      max-width: var(--max-width);
      margin: 2rem auto;
      padding: 0 1.5rem;
      width: 100%;
    }

    /* Search and Refresh Styles */
    .search-container {
      display: flex;
      flex-wrap: wrap;
      gap: 1rem;
      align-items: center;
      margin-bottom: 2rem;
    }

    .search-input {
      flex: 1;
      min-width: 250px;
      padding: 0.75rem 1.5rem;
      font-size: 1rem;
      border: 2px solid var(--border-color);
      border-radius: var(--radius-md);
      outline: none;
      transition: border-color var(--transition-duration) ease, background-color var(--transition-duration) ease, color var(--transition-duration) ease;
      background-color: var(--card-background);
      color: var(--text-primary);
    }

    .search-input::placeholder {
      color: var(--text-secondary);
    }

    .search-input:focus {
      border-color: var(--primary-color);
    }

    .refresh-button {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.75rem 1.5rem;
      font-size: 1rem;
      border: 2px solid var(--border-color);
      border-radius: var(--radius-md);
      background-color: var(--secondary-color);
      color: var(--primary-color);
      cursor: pointer;
      transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease, border-color var(--transition-duration) ease, transform 0.2s ease;
      min-width: 150px;
    }

    .refresh-button:hover {
      background-color: var(--primary-color);
      color: var(--secondary-color);
      border-color: var(--primary-color);
      transform: translateY(-2px);
    }

    .refresh-button:active {
      transform: translateY(0);
    }

    .refresh-button svg {
      width: 20px;
      height: 20px;
      fill: currentColor;
      transition: transform 0.3s ease;
    }

    .refresh-button:hover svg {
      transform: rotate(360deg);
    }

    .refresh-button:disabled {
      opacity: 0.6;
      cursor: not-allowed;
      transform: none;
    }

    /* Grid Styles */
    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
      gap: 2rem;
    }

    /* Card Styles */
    .card {
      background: var(--card-background);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-md);
      overflow: hidden;
      box-shadow: var(--shadow-sm);
      transition: transform var(--transition-duration) ease, box-shadow var(--transition-duration) ease, border-color var(--transition-duration) ease;
      cursor: pointer;
      display: flex;
      flex-direction: column;
      height: 100%;
      opacity: 0;
      transform: translateY(20px);
      animation: fadeInCard 0.5s forwards;
    }

    .card:hover {
      transform: translateY(-5px);
      box-shadow: var(--shadow-lg);
      border-color: var(--primary-color);
    }

    @keyframes fadeInCard {
      to { opacity: 1; transform: translateY(0); }
    }

    .card__image-container {
      position: relative;
      width: 100%;
      padding-top: 140%;
      background: #2a2a2a;
      overflow: hidden;
    }

    .card__image {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.3s ease;
    }

    .card:hover .card__image {
      transform: scale(1.05);
    }

    .card__content {
      padding: 1rem;
      flex-grow: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }

    .card__title {
      font-size: 1.1rem;
      font-weight: 600;
      color: var(--text-primary);
      text-align: center;
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      transition: color var(--transition-duration) ease;
    }

    .card:hover .card__title {
      color: var(--secondary-color);
    }

    /* Loader Styles */
    .loader {
      display: none;
      justify-content: center;
      align-items: center;
      height: 200px;
      color: var(--text-secondary);
    }

    .loader.visible {
      display: flex;
    }

    .loader__spinner {
      width: 50px;
      height: 50px;
      border: 5px solid #444444;
      border-top: 5px solid var(--primary-color);
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }

    /* Spinner Animation */
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }

    /* Error Message Styles */
    .error-message {
      text-align: center;
      color: #ff8080;
      padding: 1rem;
      background: var(--border-color);
      border-radius: var(--radius-sm);
      margin: 1rem 0;
      opacity: 1;
      transition: opacity 0.5s ease-out;
    }

    .error-message.fade-out {
      opacity: 0;
    }

    /* Modal Styles */
    .modal {
      display: none;
      position: fixed;
      z-index: 2000;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      overflow: auto;
      background-color: rgba(0,0,0,0.85);
      justify-content: center;
      align-items: center;
      padding: 1rem;
      transition: opacity 0.3s ease;
    }

    .modal.show {
      display: flex;
      opacity: 1;
    }

    .modal-content {
      background-color: var(--card-background);
      padding: 2rem;
      border-radius: var(--radius-lg);
      max-width: 700px;
      width: 100%;
      position: relative;
      box-shadow: var(--shadow-lg);
      animation: fadeInModal 0.3s ease;
      color: var(--text-primary);
    }

    @keyframes fadeInModal {
      from { opacity: 0; transform: translateY(-20px); }
      to { opacity: 1; transform: translateY(0); }
    }

    .close {
      position: absolute;
      top: 1rem;
      right: 1.5rem;
      color: var(--text-secondary);
      font-size: 2rem;
      font-weight: bold;
      cursor: pointer;
      transition: color var(--transition-duration) ease;
      background: none;
      border: none;
      font-family: inherit;
    }

    .close:hover,
    .close:focus {
      color: var(--primary-color);
      outline: none;
    }

    .modal__title {
      font-size: 1.75rem;
      font-weight: 700;
      margin-bottom: 1rem;
      color: var(--text-primary);
      text-align: center;
    }

    .modal__link {
      display: inline-block;
      padding: 0.75rem 1.5rem;
      background-color: var(--primary-color);
      color: var(--secondary-color);
      text-decoration: none;
      border-radius: var(--radius-md);
      font-weight: 600;
      transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
      text-align: center;
      width: 100%;
    }

    .modal__link:hover {
      background-color: var(--secondary-color);
      color: var(--primary-color);
    }

    /* Sentinel Element for Infinite Scroll */
    .sentinel {
      height: 1px;
    }

    /* Progress Bar Styles */
    .progress-container {
      width: 100%;
      background-color: #333333;
      border-radius: var(--radius-md);
      margin: 1rem 0;
      display: none;
    }

    .progress-bar {
      height: 10px;
      width: 0%;
      background-color: var(--primary-color);
      border-radius: var(--radius-md);
      transition: width 0.3s ease;
    }

    .progress-text {
      text-align: center;
      margin-top: 0.5rem;
      font-size: 0.9rem;
      color: var(--text-primary);
      display: none;
    }

    /* Toast Styles */
    .toast-container {
      position: fixed;
      bottom: 20px;
      right: 20px;
      z-index: 3000;
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }

    .toast {
      background-color: var(--toast-background);
      color: var(--toast-color);
      padding: 1rem 1.5rem;
      border-radius: var(--radius-sm);
      box-shadow: var(--shadow-lg);
      display: flex;
      align-items: center;
      gap: 0.5rem;
      animation: slideIn 0.5s forwards;
      opacity: 0;
      transition: opacity 0.3s ease;
    }

    .toast.show {
      opacity: 1;
    }

    @keyframes slideIn {
      from {
        transform: translateX(100%);
        opacity: 0;
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }

    .toast.success {
      background-color: #28a745;
      color: #ffffff;
    }

    .toast.error {
      background-color: #dc3545;
      color: #ffffff;
    }

    .toast svg {
      width: 20px;
      height: 20px;
      fill: currentColor;
    }

    /* Responsive Styles */
    @media (max-width: 1024px) {
      .header__title {
        font-size: 1.5rem;
      }
    }

    @media (max-width: 768px) {
      .grid {
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        gap: 1.5rem;
      }

      .card__title {
        font-size: 1rem;
      }

      .refresh-button {
        width: 100%;
        justify-content: center;
      }
    }

    @media (max-width: 480px) {
      .grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 1rem;
      }

      .header {
        flex-direction: column;
        align-items: flex-start;
      }

      .toggle-switch {
        margin-top: 1rem;
      }
    }

    /* Menu Button and Menu Styles */
    .menu-button {
      position: fixed;
      top: 1rem;
      left: 1rem;
      z-index: 1001;
      background-color: var(--card-background);
      color: var(--text-primary);
      border: none;
      padding: 0.75rem;
      border-radius: var(--radius-sm);
      cursor: pointer;
      transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .menu-button:hover {
      background-color: var(--primary-color);
      color: var(--secondary-color);
    }

    .menu-button svg {
      width: 24px;
      height: 24px;
      fill: currentColor;
    }

    .menu {
      position: fixed;
      top: 0;
      left: 0;
      width: 50%;
      height: 100%;
      background-color: var(--card-background);
      box-shadow: var(--shadow-lg);
      transform: translateX(-100%);
      transition: transform var(--transition-duration) ease;
      z-index: 1000;
      display: flex;
      flex-direction: column;
      padding: 2rem;
    }

    .menu.open {
      transform: translateX(0);
    }

    .menu__item {
      padding: 1rem 0;
      color: var(--text-primary);
      text-decoration: none;
      font-size: 1.2rem;
      transition: color var(--transition-duration) ease;
    }

    .menu__item:hover {
      color: var(--primary-color);
    }

    /* Settings Panel Styles */
    .settings-panel {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.85);
      justify-content: center;
      align-items: center;
      z-index: 1001;
      opacity: 0;
      transition: opacity 0.3s ease;
    }

    .settings-panel.open {
      display: flex;
      opacity: 1;
    }

    .settings-panel__content {
      background-color: var(--card-background);
      padding: 2rem;
      border-radius: var(--radius-lg);
      max-width: 500px;
      width: 100%;
      position: relative;
      box-shadow: var(--shadow-lg);
      animation: fadeInModal 0.3s ease;
      color: var(--text-primary);
    }

    .settings-panel__close {
      position: absolute;
      top: 1rem;
      right: 1.5rem;
      color: var(--text-secondary);
      font-size: 2rem;
      font-weight: bold;
      cursor: pointer;
      transition: color var(--transition-duration) ease;
      background: none;
      border: none;
      font-family: inherit;
    }

    .settings-panel__close:hover,
    .settings-panel__close:focus {
      color: var(--primary-color);
      outline: none;
    }

    .settings-panel__title {
      font-size: 1.75rem;
      font-weight: 700;
      margin-bottom: 1rem;
      color: var(--text-primary);
      text-align: center;
    }

    .settings-panel__toggle {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 1rem;
    }

    .settings-panel__toggle label {
      font-size: 1.2rem;
      color: var(--text-primary);
    }

    .settings-panel__refresh {
      display: flex;
      justify-content: center;
      margin-top: 1rem;
    }
  </style>
</head>
<body>
  <!-- Header with Title -->
  <header class="header">
    <div class="header__title">Light Novel Library Collection</div>
  </header>

  <!-- Menu Button -->
  <button class="menu-button" id="menu-button" aria-label="Open Menu">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
    </svg>
  </button>

  <!-- Menu -->
  <nav class="menu" id="menu">
    <a href="#" class="menu__item" data-target="home">Home</a>
    <a href="#" class="menu__item" data-target="ln-pdfs">LN PDFs</a>
    <a href="#" class="menu__item" data-target="ln-epubs">LN EPUBs</a>
    <a href="#" class="menu__item" data-target="release-dates">Release Dates</a>
    <a href="#" class="menu__item" data-target="webnovels">Web Novels</a>
    <a href="#" class="menu__item" data-target="manga">Manga</a>
    <a href="#" class="menu__item" data-target="settings">Settings</a>
  </nav>

  <!-- Settings Panel -->
  <div class="settings-panel" id="settings-panel">
    <div class="settings-panel__content">
      <button class="settings-panel__close" aria-label="Close Settings">&times;</button>
      <h2 class="settings-panel__title">Settings</h2>
      <div class="settings-panel__toggle">
        <label for="theme-toggle">Dark Mode</label>
        <label class="toggle-switch">
          <input type="checkbox" id="theme-toggle" aria-label="Toggle Dark Mode">
          <span class="slider"></span>
        </label>
      </div>
      <div class="settings-panel__refresh">
        <button id="refresh-button" class="refresh-button" aria-label="Refresh Data">
          <!-- Refresh Icon SVG -->
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M17.65 6.35a7.95 7.95 0 00-11.3 0l-1.41-1.42a10 10 0 0114.14 0c.39.39.39 1.02 0 1.41l-1.42 1.42zM6.35 17.65a7.95 7.95 0 0011.3 0l1.41 1.42a10 10 0 01-14.14 0c-.39-.39-.39-1.02 0-1.41l1.42-1.42z"/>
          </svg>
          Refresh Data
        </button>
      </div>
    </div>
  </div>

  <!-- Main Content -->
  <main class="main" role="main">
    <!-- Search Bar -->
    <div class="search-container">
      <input type="text" id="search-input" class="search-input" placeholder="Search light novels..." aria-label="Search light novels">
    </div>

    <!-- Progress Bar -->
    <div class="progress-container" id="progress-container">
      <div class="progress-bar" id="progress-bar"></div>
    </div>
    <div class="progress-text" id="progress-text">0%</div>

    <!-- Content Grid -->
    <div id="content" class="grid" aria-live="polite">
      <!-- Initial Loader -->
      <div class="loader" id="loader" role="status" aria-label="Loading novels">
        <div class="loader__spinner"></div>
      </div>
    </div>

    <!-- Sentinel Element for Infinite Scroll -->
    <div class="sentinel" id="sentinel"></div>
  </main>

  <!-- Modal -->
  <div id="modal" class="modal" aria-hidden="true" role="dialog" aria-labelledby="modal-title">
    <div class="modal-content">
      <button class="close" aria-label="Close modal">&times;</button>
      <h2 id="modal-title" class="modal__title"></h2>
      <a id="modal-link" class="modal__link" href="#" target="_blank" rel="noopener noreferrer">Read PDF</a>
    </div>
  </div>

  <!-- Toast Notifications -->
  <div class="toast-container" id="toast-container"></div>

  <!-- JavaScript -->
  <!-- JavaScript -->
<script>
  'use strict';
  (async function() {

    /**
     * IndexedDB Utilities
     */
    let db;
    const DB_VERSION = 2; // Updated database version

    const openDatabase = () => {
      return new Promise((resolve, reject) => {
        const request = indexedDB.open('MonochromeNovelsDB', DB_VERSION);

        request.onupgradeneeded = function(event) {
          const db = event.target.result;
          if (event.oldVersion < 1) {
            // Initial creation of object stores
            const novelsStore = db.createObjectStore('novels', { keyPath: 'id', autoIncrement: true });
            novelsStore.createIndex('name', 'name', { unique: true });
            novelsStore.createIndex('nameLower', 'nameLower', { unique: false });
            novelsStore.createIndex('coverUrl', 'coverUrl', { unique: true });
            novelsStore.createIndex('pdfUrl', 'pdfUrl', { unique: true });
            novelsStore.createIndex('timestamp', 'timestamp', { unique: false });

            const settingsStore = db.createObjectStore('settings', { keyPath: 'key' });

          } else if (event.oldVersion < 2) {
            // Upgrade logic for version 2
            const transaction = event.target.transaction;
            const novelsStore = transaction.objectStore('novels');
            // Add a new index or make changes as needed
            if (!novelsStore.indexNames.contains('nameLower')) {
              novelsStore.createIndex('nameLower', 'nameLower', { unique: false });
            }
          }
          // Future upgrades can be handled here
        };

        request.onsuccess = function(event) {
          db = event.target.result;
          resolve(db);
        };

        request.onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    // Other IndexedDB methods remain similar, with added error handling
    const countNovels = () => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readonly');
        const store = transaction.objectStore('novels');
        const countRequest = store.count();
        countRequest.onsuccess = function() {
          resolve(countRequest.result);
        };
        countRequest.onerror = function() {
          reject(countRequest.error);
        };
      });
    };

    const getAllNovels = () => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readonly');
        const store = transaction.objectStore('novels');
        const getAllRequest = store.getAll();
        getAllRequest.onsuccess = function() {
          resolve(getAllRequest.result);
        };
        getAllRequest.onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    const getNovels = (offset, limit) => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readonly');
        const store = transaction.objectStore('novels');
        const index = store.index('name');

        const result = [];
        let advanced = false;
        index.openCursor().onsuccess = function(event) {
          const cursor = event.target.result;
          if (cursor) {
            if (!advanced && offset > 0) {
              advanced = true;
              cursor.advance(offset);
              return;
            }
            result.push(cursor.value);
            if (result.length < limit) {
              cursor.continue();
            } else {
              resolve(result);
            }
          } else {
            resolve(result);
          }
        };
        index.openCursor().onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    const getNovelsByNameIncludes = (searchTerm, offset, limit) => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readonly');
        const store = transaction.objectStore('novels');
        const index = store.index('nameLower');

        const lowerSearchTerm = searchTerm.toLowerCase();
        const result = [];
        index.openCursor().onsuccess = function(event) {
          const cursor = event.target.result;
          if (cursor) {
            if (cursor.value.nameLower.includes(lowerSearchTerm)) {
              if (offset > 0) {
                offset--;
              } else {
                result.push(cursor.value);
              }
            }
            if (result.length < limit) {
              cursor.continue();
            } else {
              resolve(result);
            }
          } else {
            resolve(result);
          }
        };
        index.openCursor().onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    const bulkAddNovels = (novels) => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readwrite');
        const store = transaction.objectStore('novels');

        const promises = novels.map((novel) => {
          return new Promise((res, rej) => {
            const request = store.put(novel);
            request.onsuccess = function() {
              res();
            };
            request.onerror = function(event) {
              console.error('Failed to add novel:', novel.name, event.target.error);
              res(); // Resolve even on error to continue
            };
          });
        });

        Promise.allSettled(promises).then(() => {
          resolve();
        }).catch((error) => {
          reject(error);
        });
      });
    };

    const clearNovels = () => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readwrite');
        const store = transaction.objectStore('novels');
        const clearRequest = store.clear();
        clearRequest.onsuccess = function() {
          resolve();
        };
        clearRequest.onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    const getSetting = (key) => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('settings', 'readonly');
        const store = transaction.objectStore('settings');
        const getRequest = store.get(key);
        getRequest.onsuccess = function() {
          resolve(getRequest.result ? getRequest.result.value : null);
        };
        getRequest.onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    const putSetting = (key, value) => {
      return new Promise((resolve, reject) => {
        const transaction = db.transaction('settings', 'readwrite');
        const store = transaction.objectStore('settings');
        const putRequest = store.put({ key: key, value: value });
        putRequest.onsuccess = function() {
          resolve();
        };
        putRequest.onerror = function(event) {
          reject(event.target.error);
        };
      });
    };

    /**
     * Constants and Variables
     */
    const PAGE_SIZE = 20; // Number of novels to load per page
    let currentPage = 0; // Current page index
    let isLoading = false; // Flag to prevent multiple simultaneous loads
    let hasMore = true; // Flag to determine if more novels are available
    let currentSearchTerm = ''; // Current search term

    const PLACEHOLDER_IMAGE = 'https://via.placeholder.com/500x700?text=No+Image'; // Placeholder for missing images

    /**
     * Debounce Function to Limit Function Execution Rate
     * @param {Function} func
     * @param {number} delay
     * @returns {Function}
     */
    const debounce = (func, delay) => {
      let debounceTimer;
      return function(...args) {
        const context = this;
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => func.apply(context, args), delay);
      }
    };

    /**
     * Utility: Delay Function
     * @param {number} ms
     * @returns {Promise}
     */
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

    /**
     * Utility: Retry Operation with Exponential Backoff (3 Attempts)
     * @param {Function} operation
     * @param {number} attempts
     * @param {number} delayDuration
     * @returns {Promise}
     */
    const retryOperation = async (operation, attempts = 3, delayDuration = 1500) => {
      for (let i = 0; i < attempts; i++) {
        try {
          return await operation();
        } catch (error) {
          if (i === attempts - 1) throw error;
          await delay(delayDuration * Math.pow(2, i)); // Exponential backoff
        }
      }
    };

    /**
     * Initialize Intersection Observer for Infinite Scroll using Sentinel Element
     */
    const setupSentinelObserver = () => {
      const sentinel = document.getElementById('sentinel');
      if (!('IntersectionObserver' in window)) {
        // Fallback if IntersectionObserver is not supported
        window.addEventListener('scroll', onScrollLoadNextPage);
        return;
      }

      const sentinelObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting && hasMore && !isLoading) {
            loadNextPageWrapper();
          }
        });
      }, {
        rootMargin: '100px',
        threshold: 0
      });
      sentinelObserver.observe(sentinel);
    };

    // Fallback function for scroll event
    let scrollTimeout;
    const onScrollLoadNextPage = () => {
      if (scrollTimeout) {
        clearTimeout(scrollTimeout);
      }
      scrollTimeout = setTimeout(() => {
        if (window.scrollY + window.innerHeight >= document.body.scrollHeight - 100 && hasMore && !isLoading) {
          loadNextPageWrapper();
        }
      }, 200);
    };

    /**
     * Load Next Page Wrapper to prevent concurrent invocations
     */
    let loadNextPageQueue = Promise.resolve();
    const loadNextPageWrapper = () => {
      loadNextPageQueue = loadNextPageQueue.then(() => loadNextPage());
    };

    /**
     * Load Next Page of Novels from IndexedDB
     */
    const loadNextPage = async () => {
      if (isLoading) return; // Prevent multiple simultaneous loads
      isLoading = true;
      showLoader();

      try {
        let novels;

        if (currentSearchTerm === '') {
          novels = await getNovels(currentPage * PAGE_SIZE, PAGE_SIZE);
        } else {
          novels = await getNovelsByNameIncludes(currentSearchTerm, currentPage * PAGE_SIZE, PAGE_SIZE);
        }

        if (novels.length < PAGE_SIZE) {
          hasMore = false; // No more novels to load
        }

        if (novels.length > 0) {
          appendNovelsToDisplay(novels);
          currentPage++;
        } else {
          if (currentPage === 0) {
            showTemporaryError('No novels found for the given search term.', 5000);
          }
        }

        // Edge case: Load more if content doesn't fill viewport
        if (document.body.scrollHeight <= window.innerHeight && hasMore && !isLoading) {
          loadNextPageWrapper();
        }

      } catch (error) {
        console.error('Error loading novels:', error);
        showTemporaryError('An error occurred while loading novels.', 5000);
      } finally {
        hideLoader();
        isLoading = false;
      }
    };

    /**
     * Show Loader
     */
    const showLoader = () => {
      document.getElementById('loader').classList.add('visible');
    };

    /**
     * Hide Loader
     */
    const hideLoader = () => {
      document.getElementById('loader').classList.remove('visible');
    };

    /**
     * Display Error Message Temporarily
     * @param {string} message
     * @param {number} duration - Duration in milliseconds
     */
    const showTemporaryError = (message, duration = 5000) => {
      const content = document.getElementById('content');
      // Remove existing error messages
      const existingErrors = content.querySelectorAll('.error-message');
      existingErrors.forEach(error => error.remove());

      const errorDiv = document.createElement('div');
      errorDiv.className = 'error-message';
      errorDiv.setAttribute('role', 'alert');
      errorDiv.textContent = message;

      content.prepend(errorDiv);

      // Fade out after specified duration
      setTimeout(() => {
        errorDiv.classList.add('fade-out');
        // Remove from DOM after fade-out transition
        setTimeout(() => {
          errorDiv.remove();
        }, 500);
      }, duration);
    };

    /**
     * Append Novels to Display
     * @param {Array} novels
     */
    const appendNovelsToDisplay = novels => {
      const content = document.getElementById('content');
      const fragment = document.createDocumentFragment();

      novels.forEach(novel => {
        const card = createNovelCard(novel);
        fragment.appendChild(card);
      });

      content.appendChild(fragment);
      if (window.AOS) {
        AOS.refresh(); // Refresh AOS to apply animations to new elements
      }

      // Lazy load images
      lazyLoadImages();
    };

    /**
     * Create Novel Card Element
     * @param {Object} novel
     * @returns {HTMLElement}
     */
    const createNovelCard = (novel) => {
      const card = document.createElement('div');
      card.className = 'card';
      card.setAttribute('tabindex', '0');
      card.setAttribute('role', 'button');
      card.setAttribute('aria-labelledby', `novel-title-${encodeURIComponent(novel.name)}`);
      card.setAttribute('data-aos', 'fade-up');

      const imageContainer = document.createElement('div');
      imageContainer.className = 'card__image-container';

      const image = document.createElement('img');
      image.className = 'card__image';
      image.dataset.src = novel.coverUrl || PLACEHOLDER_IMAGE;
      image.alt = `Cover of ${novel.name}`;
      image.loading = 'lazy';
      image.onerror = function() {
        this.src = PLACEHOLDER_IMAGE;
      };

      imageContainer.appendChild(image);
      card.appendChild(imageContainer);

      const content = document.createElement('div');
      content.className = 'card__content';

      const title = document.createElement('h2');
      title.id = `novel-title-${encodeURIComponent(novel.name)}`;
      title.className = 'card__title';
      title.textContent = novel.name;

      content.appendChild(title);
      card.appendChild(content);

      // Event Listener to Open Modal
      const openModalEvent = (e) => {
        if (e.type === 'click' || (e.type === 'keypress' && (e.key === 'Enter' || e.key === ' '))) {
          e.preventDefault();
          showModal(novel);
        }
      };

      card.addEventListener('click', openModalEvent);
      card.addEventListener('keypress', openModalEvent);

      return card;
    };

    /**
     * Lazy Load Images using Intersection Observer
     */
    const lazyLoadImages = () => {
      const images = document.querySelectorAll('img[data-src]');
      const config = {
        rootMargin: '50px 0px',
        threshold: 0.01
      };

      let observer;
      if ('IntersectionObserver' in window) {
        observer = new IntersectionObserver((entries, self) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              preloadImage(entry.target);
              self.unobserve(entry.target);
            }
          });
        }, config);

        images.forEach(image => {
          observer.observe(image);
        });
      } else {
        // Fallback for browsers without IntersectionObserver support
        images.forEach(image => {
          preloadImage(image);
        });
      }
    };

    const preloadImage = (img) => {
      img.src = img.dataset.src;
      img.onload = () => {
        img.removeAttribute('data-src');
      };
    };

    /**
     * Utility: Escape HTML to Prevent XSS
     * @param {string} str
     * @returns {string}
     */
    const escapeHTML = (str) => {
      if (!str) return '';
      return str.replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
    };

    /**
     * Modal Functionality
     */
    const modal = document.getElementById('modal');
    const modalTitle = document.getElementById('modal-title');
    const modalLink = document.getElementById('modal-link');
    const closeBtn = document.querySelector('.close');

    /**
     * Show Modal with Novel Details
     * @param {Object} novel
     */
    const showModal = (novel) => {
      modalTitle.textContent = novel.name;
      modalLink.setAttribute('href', novel.pdfUrl);
      modal.classList.add('show');
      modal.setAttribute('aria-hidden', 'false');
      document.body.style.overflow = 'hidden'; // Prevent background scrolling
      closeBtn.focus(); // Focus on close button for accessibility

      // Trap focus inside modal
      document.addEventListener('focus', trapFocus, true);
    };

    /**
     * Close Modal
     */
    const closeModal = () => {
      modal.classList.remove('show');
      modal.setAttribute('aria-hidden', 'true');
      document.body.style.overflow = 'auto';

      // Remove focus trap
      document.removeEventListener('focus', trapFocus, true);
    };

    const trapFocus = (event) => {
      if (!modal.contains(event.target)) {
        event.stopPropagation();
        closeBtn.focus();
      }
    };

    closeBtn.addEventListener('click', closeModal);

    window.addEventListener('click', (event) => {
      if (event.target === modal) {
        closeModal();
      }
    });

    window.addEventListener('keydown', (event) => {
      if (event.key === 'Escape' && modal.classList.contains('show')) {
        closeModal();
      }
    });

    /**
     * Search Functionality
     */
    const searchInput = document.getElementById('search-input');

    const handleSearch = debounce(async () => {
      currentSearchTerm = searchInput.value.trim();
      currentPage = 0;
      hasMore = true;

      const content = document.getElementById('content');
      content.innerHTML = ''; // Clear existing content

      // Reload the first page with the new search term
      await loadNextPage();
    }, 300); // 300ms debounce delay

    searchInput.addEventListener('input', handleSearch);

    /**
     * Refresh Data Functionality
     */
    const refreshButton = document.getElementById('refresh-button');
    refreshButton.addEventListener('click', async () => {
      // Replace confirm dialog with custom modal
      showConfirmationModal('Are you sure you want to refresh the data? This may take a few moments.', async () => {
        isLoading = true;
        showLoader();
        hasMore = true;
        currentPage = 0;
        refreshButton.disabled = true;

        try {
          // Clear existing data
          await clearNovels();

          // Fetch and parse fresh data
          await fetchAndStoreNovels();

          // Reload the first page of novels
          document.getElementById('content').innerHTML = ''; // Clear existing content

          await loadNextPage();

          // Show success toast
          showToast('Data refreshed successfully!', 'success');
        } catch (error) {
          console.error('Error refreshing data:', error);
          showTemporaryError('Failed to refresh data. Please try again later.', 5000);
          // Show error toast
          showToast('Failed to refresh data.', 'error');
        } finally {
          hideLoader();
          isLoading = false;
          refreshButton.disabled = false;
        }
      });
    });

    /**
     * Show Confirmation Modal
     * @param {string} message
     * @param {Function} onConfirm
     */
    const showConfirmationModal = (message, onConfirm) => {
      const confirmationModal = document.createElement('div');
      confirmationModal.className = 'modal';
      confirmationModal.setAttribute('role', 'dialog');
      confirmationModal.setAttribute('aria-modal', 'true');

      const modalContent = document.createElement('div');
      modalContent.className = 'modal-content';

      const modalMessage = document.createElement('p');
      modalMessage.textContent = message;

      const modalButtons = document.createElement('div');
      modalButtons.className = 'modal-buttons';

      const confirmButton = document.createElement('button');
      confirmButton.textContent = 'Confirm';
      confirmButton.className = 'button confirm-button';

      const cancelButton = document.createElement('button');
      cancelButton.textContent = 'Cancel';
      cancelButton.className = 'button cancel-button';

      modalButtons.appendChild(confirmButton);
      modalButtons.appendChild(cancelButton);

      modalContent.appendChild(modalMessage);
      modalContent.appendChild(modalButtons);
      confirmationModal.appendChild(modalContent);
      document.body.appendChild(confirmationModal);
      document.body.style.overflow = 'hidden';

      confirmButton.focus();

      const closeConfirmationModal = () => {
        confirmationModal.remove();
        document.body.style.overflow = 'auto';
      };

      confirmButton.addEventListener('click', () => {
        closeConfirmationModal();
        onConfirm();
      });

      cancelButton.addEventListener('click', closeConfirmationModal);

      window.addEventListener('keydown', (event) => {
        if (event.key === 'Escape') {
          closeConfirmationModal();
        }
      });

      window.addEventListener('click', (event) => {
        if (event.target === confirmationModal) {
          closeConfirmationModal();
        }
      });
    };

    /**
     * Initialize Application
     */
    const initializeApp = async () => {
      try {
        // Open the database
        await openDatabase();

        // Check if any novels are already stored in IndexedDB
        const count = await countNovels();
        if (count === 0) {
          // If not, fetch from the target website
          await fetchAndStoreNovels();
        } else {
          // Validate existing data
          const novels = await getAllNovels();
          if (!validateNovels(novels)) {
            await clearNovels();
            await fetchAndStoreNovels();
          }
        }

        // Load the first page of novels
        await loadNextPage();

        // Edge case: Load more if content doesn't fill viewport
        if (document.body.scrollHeight <= window.innerHeight && hasMore && !isLoading) {
          loadNextPageWrapper();
        }
      } catch (error) {
        console.error('Error initializing application:', error);
        showTemporaryError('Failed to load novels. Please try refreshing the page.', 5000);
        // Show error toast
        showToast('Failed to load novels.', 'error');
      }
    };

    /**
     * Fetch and Store Novels
     */
    const fetchAndStoreNovels = async () => {
      try {
        const html = await retryOperation(() => fetchHTML('https://jnovels.com/top-light-novels-to-read/'));
        let novels = parseHTML(html);

        if (novels.length === 0) {
          throw new Error('No novels found on the target page.');
        }

        showProgress();
        updateProgress(0);

        // Bulk upsert novels to IndexedDB
        const novelsToAdd = novels.map((novel, index) => {
          const escapedName = escapeHTML(novel.name);
          const escapedCoverUrl = escapeHTML(novel.coverUrl);
          const escapedPdfUrl = escapeHTML(novel.pdfUrl);
          return {
            id: novel.id,
            name: escapedName,
            nameLower: escapedName.toLowerCase(),
            coverUrl: escapedCoverUrl,
            pdfUrl: escapedPdfUrl,
            timestamp: Date.now()
          };
        });

        let completed = 0;
        const total = novelsToAdd.length;

        await bulkAddNovelsWithProgress(novelsToAdd, (progress) => {
          updateProgress(progress);
        });

        console.log('Novels fetched and stored successfully:', novelsToAdd.length);

        // Show success toast
        showToast('Novels fetched and stored successfully.', 'success');

      } catch (error) {
        console.error('Error fetching or storing novels:', error);
        showTemporaryError('Failed to fetch and store novels. Please try again later.', 5000);
        // Show error toast
        showToast('Failed to fetch and store novels.', 'error');
      } finally {
        hideProgress();
      }
    };

    const bulkAddNovelsWithProgress = async (novels, progressCallback) => {
      const total = novels.length;
      let completed = 0;

      return new Promise((resolve, reject) => {
        const transaction = db.transaction('novels', 'readwrite');
        const store = transaction.objectStore('novels');

        transaction.oncomplete = function() {
          resolve();
        };

        transaction.onerror = function(event) {
          reject(event.target.error);
        };

        novels.forEach((novel) => {
          const request = store.put(novel);
          request.onsuccess = function() {
            completed++;
            const progress = (completed / total) * 100;
            progressCallback(progress);
          };
          request.onerror = function(event) {
            console.error('Failed to add novel:', novel.name, event.target.error);
            completed++;
            const progress = (completed / total) * 100;
            progressCallback(progress);
          };
        });
      });
    };

    /**
     * Fetch HTML Content via CORS Proxy
     * @param {string} url
     * @returns {Promise<string>}
     */
    const fetchHTML = async (url) => {
      const proxyUrl = `https://api.codetabs.com/v1/proxy?quest=${encodeURIComponent(url)}`;
      try {
        const response = await fetch(proxyUrl, { cache: 'no-cache' });

        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const htmlContent = await response.text();

        if (!htmlContent || typeof htmlContent !== 'string') {
          throw new Error('Fetched content is invalid or empty.');
        }

        return htmlContent;
      } catch (error) {
        console.error('Error fetching HTML:', error);
        throw error; // Re-throw to be handled by caller
      }
    };

    /**
     * Parse Fetched HTML to Extract Novel Data
     * @param {string} html
     * @returns {Array<Object>}
     */
    const parseHTML = (html) => {
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, 'text/html');
      const novels = [];
      const uniqueNovels = new Set();

      // Select all h3 tags as they contain the novel names and links
      const h3Elements = doc.querySelectorAll('h3');

      h3Elements.forEach((h3Element) => {
        try {
          const aTag = h3Element.querySelector('a');
          const spanTag = h3Element.querySelector('span');

          if (!aTag || !spanTag) return; // Skip if either tag is missing

          const name = spanTag.textContent.trim();
          const pdfLink = aTag.getAttribute('href').trim();

          // The cover image is inside the following p tag
          let pElement = h3Element.nextElementSibling;
          while (pElement && pElement.tagName.toLowerCase() !== 'p') {
            pElement = pElement.nextElementSibling;
          }
          if (!pElement) return; // Skip if p tag is missing

          const imgTag = pElement.querySelector('img');
          if (!imgTag) return; // Skip if img tag is missing

          let coverUrl = imgTag.getAttribute('src') || imgTag.getAttribute('data-src');
          if (!coverUrl) return; // Skip if cover URL is missing

          // Handle different URL formats
          if (coverUrl.startsWith('//')) {
            coverUrl = `https:${coverUrl}`;
          } else if (coverUrl.startsWith('/')) {
            coverUrl = `https://jnovels.com${coverUrl}`;
          } else if (!coverUrl.startsWith('http')) {
            // Handle relative URLs without leading '/'
            coverUrl = `https://jnovels.com/${coverUrl}`;
          }

          // Validate extracted data
          if (name && pdfLink && coverUrl) {
            const novelKey = `${name}-${coverUrl}-${pdfLink}`;
            if (!uniqueNovels.has(novelKey)) {
              uniqueNovels.add(novelKey);
              novels.push({
                name,
                coverUrl,
                pdfUrl: pdfLink
              });
            }
          } else {
            console.warn('Incomplete novel data found and skipped:', { name, pdfLink, coverUrl });
          }
        } catch (error) {
          // Skip any malformed entries
          console.error('Error parsing a novel entry:', error);
        }
      });

      return novels;
    };

    /**
     * Update Progress Bar
     * @param {number} percentage
     */
    const updateProgress = (percentage) => {
      document.getElementById('progress-bar').style.width = `${percentage}%`;
      document.getElementById('progress-text').textContent = `${Math.round(percentage)}%`;
    };

    /**
     * Show Progress Bar and Text
     */
    const showProgress = () => {
      document.getElementById('progress-container').style.display = 'block';
      document.getElementById('progress-text').style.display = 'block';
    };

    /**
     * Hide Progress Bar and Text
     */
    const hideProgress = () => {
      document.getElementById('progress-container').style.display = 'none';
      document.getElementById('progress-text').style.display = 'none';
    };

    /**
     * Validate Novels
     * @param {Array<Object>} novels
     * @returns {boolean}
     */
    const validateNovels = (novels) => {
      for (const novel of novels) {
        if (!novel.name || !novel.coverUrl || !novel.pdfUrl || !novel.timestamp) {
          return false;
        }
      }
      return true;
    };

    /**
     * Toast Notification Functionality
     */
    const showToast = (message, type = 'success') => {
      const toastContainer = document.getElementById('toast-container');
      const toast = document.createElement('div');
      toast.className = `toast ${type}`;

      let iconSVG = '';

      if (type === 'success') {
        iconSVG = `
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M20.285,6.708l-11.7,11.7l-5.566-5.566c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l6.28,6.28
            c0.391,0.391,1.023,0.391,1.414,0l12.544-12.544C20.676,7.731,20.676,7.1,20.285,6.708z"/>
          </svg>
        `;
      } else if (type === 'error') {
        iconSVG = `
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M12,0C5.373,0,0,5.373,0,12s5-12,12-12S5.373,0,12,0z M16.242,16.242
            c0.391,0.391,0.391,1.023,0,1.414c-0.391,0.391-1,0.391-1.414,0L12,13.414l-2.828,2.828c-0.391,0.391-1,0.391-1.414,0
            c-0.391-0.391-0.391-1,0-1.414L10.586,12l-2.828-2.828c-0.391-0.391-0.391-1,0-1.414s1-0.391,1.414,0L12,10.586
            l2.828-2.828c0.391-0.391,1-0.391,1.414,0s0.391,1,0,1.414L13.414,12l2.828,2.828C16.633,15.219,16.633,15.851,16.242,16.242z"/>
          </svg>
        `;
      }

      toast.innerHTML = `${iconSVG} ${message}`;
      toast.classList.add('show');
      toastContainer.appendChild(toast);

      // Remove toast after 5 seconds
      setTimeout(() => {
        toast.classList.remove('show');
        setTimeout(() => {
          toast.remove();
        }, 500);
      }, 5000);
    };

    /**
     * Initialize Theme Toggle
     */
    const initializeTheme = async () => {
      const themeToggle = document.getElementById('theme-toggle');
      let currentTheme;
      try {
        currentTheme = await getSetting('theme') || 'dark';
      } catch (error) {
        console.error('Error getting theme setting:', error);
        currentTheme = 'dark';
      }

      if (currentTheme === 'light') {
        document.body.setAttribute('data-theme', 'light');
        themeToggle.checked = true;
      } else {
        document.body.setAttribute('data-theme', 'dark');
        themeToggle.checked = false;
      }

      themeToggle.addEventListener('change', async () => {
        const newTheme = themeToggle.checked ? 'light' : 'dark';
        document.body.setAttribute('data-theme', newTheme);
        try {
          await putSetting('theme', newTheme);
        } catch (error) {
          console.error('Error saving theme setting:', error);
        }
      });
    };

    /**
     * Initialize Menu Button and Menu
     */
    const initializeMenu = () => {
      const menuButton = document.getElementById('menu-button');
      const menu = document.getElementById('menu');
      const settingsPanel = document.getElementById('settings-panel');
      const settingsPanelClose = document.querySelector('.settings-panel__close');

      menuButton.addEventListener('click', () => {
        menu.classList.toggle('open');
        if (menu.classList.contains('open')) {
          document.body.style.overflow = 'hidden';
        } else {
          document.body.style.overflow = 'auto';
        }
      });

      const menuItems = menu.querySelectorAll('.menu__item');
      menuItems.forEach(menuItem => {
        menuItem.addEventListener('click', async (e) => {
          const target = e.target.getAttribute('data-target');
          if (target === 'home') {
            // Redirect to the first page where all novels are displayed
            currentSearchTerm = '';
            currentPage = 0;
            hasMore = true;
            document.getElementById('content').innerHTML = '';
            await loadNextPage();
          } else if (target === 'settings') {
            settingsPanel.classList.add('open');
            document.body.style.overflow = 'hidden';
          }
          menu.classList.remove('open');
          document.body.style.overflow = 'auto';
        });
      });

      settingsPanelClose.addEventListener('click', () => {
        settingsPanel.classList.remove('open');
        document.body.style.overflow = 'auto';
      });

      window.addEventListener('click', (event) => {
        if (event.target === settingsPanel) {
          settingsPanel.classList.remove('open');
          document.body.style.overflow = 'auto';
        }
      });

      window.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && settingsPanel.classList.contains('open')) {
          settingsPanel.classList.remove('open');
          document.body.style.overflow = 'auto';
        }
      });
    };

    /**
     * Initialize AOS and Start the Application once the DOM is fully loaded
     */
    document.addEventListener('DOMContentLoaded', () => {
      // Initialize AOS if available
      if (window.AOS) {
        AOS.init({
          duration: 800,
          easing: 'ease-in-out',
          once: true,
        });
      }

      setupSentinelObserver();
      initializeTheme();
      initializeMenu();
      initializeApp();
    });

  })();
</script>
</body>
</html>