what's the API for this

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>YouTube Unblocker + Games + Developer Mode + Console</title>

  <!-- CODEMIRROR CSS -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.min.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/theme/monokai.min.css" />

  <!-- === CORE STYLE === -->
  <style>
    /* --- General stylings --- */
    html,
    body {
      margin: 0;
      padding: 0;
      background-color: #888;
      font-family: Arial, sans-serif;
      color: black;
      overflow-x: hidden;
      transition: background-color 0.3s ease, color 0.3s ease;
      user-select: none;
      height: 100%;
    }

    body.dark-mode {
      background-color: #222;
      color: #eee;
    }

    h2 {
      color: black;
    }

    body.dark-mode h2 {
      color: white;
    }

    a {
      text-decoration: none;
      color: black;
      cursor: pointer;
      user-select: none;
      transition: background-color 0.15s ease, color 0.15s ease;
      padding: 8px 20px;
      display: block;
      border-radius: 6px;
      margin: 6px 0;
      font-weight: 700;
    }

    a:hover,
    a:focus-visible {
      background-color: #ddd;
      outline: none;
      user-select: none;
    }

    body.dark-mode a {
      color: #eee;
    }

    body.dark-mode a:hover,
    body.dark-mode a:focus-visible {
      background-color: #444;
      color: white;
    }

    button {
      cursor: pointer;
      user-select: none;
      font-weight: 700;
      font-family: Arial, sans-serif;
      font-size: 1rem;
      padding: 8px 18px;
      border-radius: 8px;
      border: none;
      background-color: #555;
      color: white;
      transition: background-color 0.3s ease;
    }

    button:hover,
    button:focus-visible {
      background-color: #777;
      outline: none;
    }

    #passwordInput,
    #youtubeURL,
    #gsearchbar,
    #secoundgsearchbar,
    select,
    input[type="number"] {
      font-weight: 600;
      font-size: 1rem;
      padding: 10px 14px;
      border-radius: 10px;
      border: 1px solid #ccc;
      outline-offset: 3px;
      outline-color: #4c9aff;
      width: 90%;
      max-width: 380px;
      margin: 10px auto;
      display: block;
      user-select: text;
    }

    #passwordInput:focus,
    #youtubeURL:focus,
    #gsearchbar:focus,
    #secoundgsearchbar:focus,
    select:focus,
    input[type="number"]:focus {
      border-color: #4c9aff;
      outline-color: #4c9aff;
      outline-style: solid;
    }


    #particles-js {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      z-index: -9999;
      background-color: #777;
      user-select: none;
    }

    /* --- Password Modal --- */
    #overlay {
      position: fixed;
      inset: 0;
      background-color: rgba(0, 0, 0, 0.85);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 99999;
      user-select: none;
    }

    #passwordModal {
      background: white;
      padding: 28px 36px;
      border-radius: 12px;
      text-align: center;
      box-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
      width: 280px;
      user-select: text;
    }

    #passwordModal h2 {
      margin-bottom: 16px;
      font-weight: 700;
      font-size: 1.4rem;
    }

    #submitPassword {
      margin-top: 16px;
      width: 100%;
      font-size: 1.1rem;
      font-weight: 700;
      background-color: #4c9aff;
      border: none;
      border-radius: 10px;
      color: white;
      padding: 12px 0;
      user-select: none;
    }

    #submitPassword:hover,
    #submitPassword:focus-visible {
      background-color: #367fdb;
      outline: none;
    }

    #errorMessage {
      color: #cc0000;
      font-weight: 700;
      margin-top: 20px;
      display: none;
      user-select: none;
    }

    #errorMessage.show {
      display: block;
    }

    /* --- NAVBAR --- */
    .settings-bar {
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100vw;
      background-color: #333;
      color: white;
      display: flex;
      align-items: center;
      justify-content: space-evenly;
      padding: 10px 0;
      user-select: none;
      z-index: 10000;
      flex-wrap: wrap;
      gap: 6px;
    }

    .settings-bar button {
      background-color: #555;
      border-radius: 10px;
      border: none;
      padding: 10px 24px;
      color: white;
      font-weight: 700;
      cursor: pointer;
      transition: background-color 0.3s;
      user-select: none;
    }

    .settings-bar button:hover,
    .settings-bar button:focus-visible {
      background-color: #777;
      outline: none;
      user-select: none;
    }

    /* --- SETTINGS PANEL --- */
    #settingsUI {
      display: none;
      position: fixed;
      bottom: 60px;
      left: 50%;
      transform: translateX(-50%);
      background-color: #444;
      color: white;
      width: 100%;
      max-width: 600px;
      border-radius: 14px 14px 0 0;
      padding: 20px 24px;
      box-shadow: 0 -3px 15px rgba(0, 0, 0, 0.4);
      user-select: none;
      z-index: 11000;
      flex-wrap: wrap;
      gap: 12px;
      font-weight: 700;
      font-size: 1rem;
      overflow-y: auto;
      max-height: 320px;
    }

    #settingsUI.active {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: space-between;
    }

    #settingsUI label {
      display: flex;
      align-items: center;
      justify-content: space-between;
      min-width: 260px;
      padding: 6px 14px;
      background-color: #555;
      border-radius: 10px;
      user-select: text;
      cursor: pointer;
      flex-grow: 1;
      margin-bottom: 8px;
      white-space: nowrap;
    }

    #settingsUI label > input[type="checkbox"],
    #settingsUI label > select,
    #settingsUI label > input[type="number"] {
      margin-left: 10px;
      cursor: pointer;
      user-select: none;
      font-weight: 700;
      font-family: Arial, sans-serif;
      background-color: white;
      color: #111;
      border: none;
      border-radius: 10px;
      padding: 6px 12px;
      max-width: 100px;
      text-align: center;
    }

    #settingsUI label > input[type="checkbox"]:focus-visible,
    #settingsUI label > select:focus-visible,
    #settingsUI label > input[type="number"]:focus-visible {
      outline: 3px solid #4c9aff;
      outline-offset: 2px;
    }

    /* === NOTIFICATIONS (TOASTS) === */
    #notification-container {
      position: fixed;
      top: 25px;
      right: 25px;
      max-width: 320px;
      z-index: 99000;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }

    .toast {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 14px 24px;
      border-radius: 12px;
      box-shadow: 0 5px 18px rgba(0, 0, 0, 0.5);
      font-weight: 600;
      font-size: 1rem;
      opacity: 0;
      cursor: pointer;
      color: white;
      animation-fill-mode: forwards;
      animation-duration: 0.35s;
      animation-timing-function: ease-out;
      user-select: none;
      transform: translateX(120%);
      /* fade in slide */
      animation-name: slideInToast;
      user-select: none;
    }

    .toast.info {
      background-color: #2980b9;
    }

    .toast.success {
      background-color: #27ae60;
    }

    .toast.warning {
      background-color: #f39c12;
      color: black;
    }

    .toast.error {
      background-color: #c0392b;
    }

    .toast:hover,
    .toast:focus-visible {
      filter: brightness(1.1);
      outline: none;
    }

    .toast .close {
      background: none;
      color: inherit;
      font-weight: 900;
      font-size: 1.4rem;
      border: none;
      cursor: pointer;
      user-select: none;
      line-height: 1;
      margin-left: 20px;
      padding-left: 12px;
    }

    /* Slide in from right */
    @keyframes slideInToast {
      to {
        opacity: 1;
        transform: translateX(0px);
      }
    }

    /* Slide out to right */
    @keyframes slideOutToast {
      to {
        opacity: 0;
        transform: translateX(120%);
      }
    }

    /* --- YouTube embed UI --- */
    #youtubeEmbedUI {
      position: fixed;
      top: 140px;
      left: 50%;
      transform: translateX(-50%);
      width: 90vw;
      max-width: 620px;
      background-color: #444;
      border-radius: 20px;
      padding: 20px 30px;
      box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
      color: white;
      z-index: 10000;
      user-select: none;
      display: none;
      flex-direction: column;
      gap: 14px;
    }

    #youtubeEmbedUI.active {
      display: flex;
    }

    #youtubeEmbedUI .top-controls {
      display: flex;
      align-items: center;
      gap: 14px;
      flex-wrap: wrap;
      user-select: text;
    }

    #youtubeEmbedUI input,
    #youtubeEmbedUI select {
      font-weight: 700;
      font-size: 1rem;
      padding: 10px 16px;
      border-radius: 15px;
      border: none;
      color: #222;
      max-width: 440px;
      width: 100%;
      user-select: text;
    }

    #youtubeEmbedUI select {
      max-width: 180px;
      cursor: pointer;
      user-select: none;
    }

    #youtubeEmbedUI button {
      background-color: #4c9aff;
      border-radius: 14px;
      padding: 12px 28px;
      font-weight: 700;
      color: white;
      border: none;
      cursor: pointer;
      transition: background-color 0.25s ease;
      user-select: none;
      flex-shrink: 0;
      white-space: nowrap;
    }

    #youtubeEmbedUI button:hover,
    #youtubeEmbedUI button:focus-visible {
      outline: none;
      background-color: #2f7de4;
    }

    #youtubeChangeButton {
      display: none;
    }

    #video-container {
      margin-top: 20px;
      width: 100%;
      background-color: black;
      border-radius: 18px;
      overflow: hidden;
      aspect-ratio: 16/9;
      box-shadow: 0 0 32px rgba(0, 0, 0, 0.7);
      user-select: none;
      position: relative;
    }

    #video-container iframe {
      width: 100%;
      height: 100%;
      border: none;
    }

    #likedVideosContainer {
      margin-top: 16px;
      background-color: #333;
      border-radius: 14px;
      padding: 14px 20px;
      max-height: 230px;
      overflow-y: auto;
      display: none;
      user-select: none;
      color: white;
    }

    #likedVideosContainer h4 {
      margin-top: 0;
      margin-bottom: 12px;
      font-weight: 700;
      user-select: text;
    }

    #likedVideosList {
      margin: 0;
      padding: 0;
      list-style: none;
      user-select: text;
      overflow-y: auto;
      max-height: 190px;
    }

    #likedVideosList li {
      display: flex;
      justify-content: space-between;
      user-select: text;
      cursor: pointer;
      align-items: center;
      padding: 8px 10px;
      border-bottom: 1px solid #444;
      font-weight: 600;
      border-radius: 8px;
      transition: background-color 0.2s ease;
    }

    #likedVideosList li:last-child {
      border-bottom: none;
    }

    #likedVideosList li:hover,
    #likedVideosList li:focus-visible {
      background-color: #4c9aff;
      outline: none;
      color: white;
    }

    #likedVideosList li span.likeBtn {
      margin-left: 16px;
      user-select: none;
      font-weight: 900;
      font-size: 1.2rem;
      color: gold;
      cursor: pointer;
      transition: transform 0.2s ease;
    }

    #likedVideosList li span.likeBtn:hover,
    #likedVideosList li span.likeBtn:focus-visible {
      transform: scale(1.3);
      outline: none;
    }

    /* --- GAMES LIST --- */

    .container {
      max-width: 600px;
      margin: 90px auto 140px;
      padding: 20px 24px 48px;
      background-color: white;
      border-radius: 18px;
      box-shadow: 0 0 60px rgb(0 0 0 / 0.15);
      user-select: none;
      color: black;
      display: flex;
      flex-direction: column;
    }

    body.dark-mode .container {
      background-color: #333;
      color: #eee;
      box-shadow: 0 0 60px #111;
    }

    .container h2 {
      margin-top: 0;
      text-align: center;
      font-weight: 700;
      user-select: text;
    }

    .container > input[type=text] {
      font-weight: 700;
      font-size: 1.1rem;
      padding: 14px 24px;
      border-radius: 14px;
      border: 1px solid #ddd;
      box-sizing: border-box;
      display: block;
      margin: 8px auto 20px auto;
      width: 90%;
      max-width: 460px;
      user-select: text;
      outline-offset: 3px;
      outline-color: #4c9aff;
    }

    .container > input[type=text]:focus {
      border-color: #4c9aff;
      outline-color: #4c9aff;
      outline-style: solid;
    }

    .glist {
      max-height: 320px;
      overflow-y: auto;
      border-radius: 12px;
      border: 1px solid #ccc;
      box-shadow: inset 0 0 15px #ddd;
      scroll-behavior: smooth;
      user-select: none;
    }

    a.game-link {
      padding: 14px 28px;
      display: block;
      font-weight: 700;
      font-size: 1.3rem;
      border-bottom: 1px solid #ddd;
      transition: background-color 0.25s ease;
      user-select: none;
      color: black;
    }

    a.game-link:hover,
    a.game-link:focus-visible {
      background-color: #eee;
      outline: none;
    }

    .favorite {
      border: 2px solid gold !important;
      background-color: #fffbdd !important;
      color: black !important;
      font-weight: 900;
    }

    body.dark-mode a.game-link {
      color: #eee;
      border-bottom-color: #555;
    }

    body.dark-mode a.game-link:hover,
    body.dark-mode a.game-link:focus-visible {
      background-color: #555;
      color: white;
    }

    body.dark-mode .favorite {
      background-color: gold !important;
      border-color: #b38b0d !important;
      color: black !important;
    }

    button.page-button {
      margin: 20px auto 0 auto;
      display: block;
      background-color: #4c9aff;
      color: white;
      border-radius: 28px;
      font-weight: 800;
      font-size: 1.1rem;
      padding: 14px 42px;
      border: none;
      user-select: none;
      cursor: pointer;
      transition: background-color 0.25s ease;
    }

    button.page-button:hover,
    button.page-button:focus-visible {
      background-color: #2f7de4;
      outline: none;
    }

    button.page-button:disabled {
      background-color: #999;
      cursor: default;
    }

    /* --- Confirmation Dialog --- */

    #confirmationDialog {
      position: fixed;
      inset: auto;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: white;
      padding: 32px 36px;
      border-radius: 20px;
      box-shadow: 0 0 30px rgba(0, 0, 0, 0.75);
      z-index: 300000;
      user-select: text;
      width: 400px;
      max-width: 90vw;
      display: none;
      flex-direction: column;
      color: black;
    }

    #confirmationDialog p {
      font-weight: 700;
      font-size: 1.3rem;
      margin-top: 0;
      margin-bottom: 28px;
    }

    #confirmationDialog > div {
      display: flex;
      justify-content: flex-end;
    }

    #confirmYes,
    #confirmNo {
      font-weight: 700;
      font-size: 1rem;
      padding: 12px 28px;
      border-radius: 18px;
      border: none;
      user-select: none;
      cursor: pointer;
      margin-left: 10px;
    }

    #confirmYes {
      background-color: #4c9aff;
      color: white;
      transition: background-color 0.25s ease;
    }

    #confirmYes:hover,
    #confirmYes:focus-visible {
      background-color: #2f7de4;
      outline: none;
    }

    #confirmNo {
      background-color: #ddd;
      color: #555;
      transition: background-color 0.25s ease;
    }

    #confirmNo:hover,
    #confirmNo:focus-visible {
      background-color: #bbb;
      outline: none;
    }

    /* --- Console panel --- */

    #consoleUI {
      position: fixed;
      bottom: 60px;
      left: 50%;
      transform: translateX(-50%);
      max-width: 720px;
      width: 90vw;
      height: 430px;
      background-color: #111;
      border-radius: 18px;
      box-shadow: 0 0 60px #4c9aff;
      padding: 20px 24px 14px;
      color: #0f0;
      display: none;
      flex-direction: column;
      font-family: monospace;
      user-select: none;
      z-index: 110000;
    }

    #consoleUI.active {
      display: flex;
    }

    #consoleUI h3 {
      margin: 0 0 10px 0;
      user-select: text;
      font-weight: 700;
    }

    /* CodeMirror text area container */
    .CodeMirror {
      height: 180px !important;
      border-radius: 18px;
      font-size: 1rem;
      box-shadow: inset 0 0 10px #0f0;
    }

    #consoleOutputWrapper {
      overflow-y: auto;
      border-radius: 16px;
      padding: 16px;
      height: 135px;
      margin-top: 14px;
      font-size: 0.9rem;
      background-color: black;
      border: 3px solid #0f0;
      user-select: text;
      white-space: pre-wrap;
    }

    #consoleControls {
      margin-top: 18px;
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      justify-content: center;
      user-select: none;
    }

    #consoleControls button {
      background-color: #4c9aff;
      border-radius: 20px;
      border: none;
      padding: 14px 26px;
      font-weight: 700;
      font-size: 1rem;
      color: #111;
      cursor: pointer;
      user-select: none;
      transition: background-color 0.25s ease;
    }

    #consoleControls button:hover,
    #consoleControls button:focus-visible {
      background-color: #2f7de4;
      outline: none;
      color: white;
    }

    #expandButton {
      background-color: #222;
      color: #0f0;
      font-weight: 700;
      border-radius: 24px;
      cursor: pointer;
      padding: 10px 28px;
      user-select: none;
      margin-left: auto;
      margin-top: 14px;
      transition: background-color 0.3s;
    }

    #expandButton:hover,
    #expandButton:focus-visible {
      background-color: #4c9aff;
      outline: none;
      color: #111;
    }

    /* Fullscreen Console */
    body.fullscreen-console #consoleUI {
      top: 5vh !important;
      left: 50% !important;
      max-width: 90vw !important;
      width: 90vw !important;
      height: 80vh !important;
      border-radius: 20px !important;
      box-shadow: 0 0 120px #4c9aff !important;
      transform: translateX(-50%) !important;
    }
  </style>
</head>

<body class="locked">

  <!-- Background -->
  <div id="particles-js"></div>

  <!-- Password Lock overlay -->
  <section id="overlay" role="dialog" aria-modal="true" aria-labelledby="passwordModalLabel">
    <div id="passwordModal">
      <h2 id="passwordModalLabel">Enter Password to Access</h2>
      <input id="passwordInput" type="password" autocomplete="current-password" placeholder="Password here" aria-label="Password input" />
      <button id="submitPassword" aria-label="Submit Password">Submit</button>
      <p id="errorMessage" role="alert">Wrong password. Try again.</p>
    </div>
  </section>

  <!-- Settings bar -->
  <nav class="settings-bar" role="navigation" aria-label="Primary Controls">
    <button id="settingsButton" aria-expanded="false" aria-controls="settingsUI">Settings</button>
    <button id="youtubeUnblockerButton">YouTube Embed</button>
    <button id="gamesListButton">Games List</button>
    <button id="consoleButton">Console</button>
  </nav>

  <!-- Settings Panel -->
  <section id="settingsUI" aria-hidden="true" tabindex="-1" role="region" aria-label="Settings Panel">
    <label for="darkModeToggle">Dark Mode
      <input type="checkbox" id="darkModeToggle" />
    </label>
    <label for="themesDropdown">Background Animation
      <select id="themesDropdown">
        <option value="none" selected>None</option>
        <option value="waves">Waves</option>
        <option value="net">Net</option>
        <option value="clouds">Clouds</option>
        <option value="fog">Fog</option>
        <option value="birds">Birds</option>
        <option value="cells">Cells</option>
        <option value="halo">Halo</option>
        <option value="rings">Rings</option>
        <option value="globe">Globe</option>
      </select>
    </label>
    <label for="enableDrag">Enable Drag & Drop Games
      <input type="checkbox" id="enableDrag" />
    </label>
    <label for="toggleFavorites">Enable Favoriting on Click
      <input type="checkbox" id="toggleFavorites" />
    </label>
    <label for="toggleNotifications">Enable Notifications (Toast)
      <input type="checkbox" id="toggleNotifications" checked />
    </label>
    <label for="autoSaveConsole">Autosave Console Code
      <input type="checkbox" id="autoSaveConsole" checked />
    </label>
    <label for="consoleThemeSelect">Console Theme
      <select id="consoleThemeSelect">
        <option value="monokai" selected>Monokai</option>
        <option value="default">Default</option>
        <option value="eclipse">Eclipse</option>
        <option value="dracula">Dracula</option>
        <option value="material">Material</option>
      </select>
    </label>
    <label for="gameFontSize">Game List Font Size (px)
      <input type="number" min="12" max="30" id="gameFontSize" value="18" />
    </label>

    <!-- Developer Mode embedded UI -->
    <section id="developerModeUI" style="border-top:1px solid #555; margin-top:12px; padding-top:12px; color:#ffcc66; display:none; user-select:text;">
      <h3>Developer Mode</h3>
      <button id="toggleDevMode">Enable Developer Mode</button>
      <div style="margin-top:12px; display:none;" id="devModeContainer">
        <label for="devPageSelect">Select Page:</label>
        <select id="devPageSelect"></select>
        <button id="addDevPageBtn" title="Add New Page" style="margin-left:10px;">+ Add Page</button>

        <div id="devGamesArea" style="margin-top:18px; max-height:250px; overflow-y:auto; background:#222; border-radius:12px; padding:12px;"></div>

        <button id="addDevGameBtn" style="margin-top:12px; background:#44aa44; color:#eee; border:none; padding:8px 18px; border-radius:14px; font-weight:700;">+ Add Dev Game</button>
      </div>
    </section>
  </section>

  <!-- YouTube Embed UI -->
  <section id="youtubeEmbedUI" role="region" aria-label="YouTube Embed Player" tabindex="-1">
    <div class="top-controls">
      <input id="youtubeURL" type="text" placeholder="Enter YouTube URL or Playlist URL" spellcheck="false" aria-label="YouTube URL Input" />
      <select id="youtubeTypeSelect" aria-label="YouTube Content Type">
        <option value="video">Video</option>
        <option value="playlist">Playlist</option>
        <option value="liked">Liked Videos</option>
      </select>
      <button id="loadVideoButton">Load</button>
      <button id="youtubeChangeButton">Change</button>
    </div>

    <div id="video-container" aria-live="polite" aria-atomic="true"></div>
    <div id="likedVideosContainer" style="display:none;">
      <h4>Liked Videos <span style="font-weight: 400; font-size: 0.85rem;">(Click ♥ to Unlike)</span></h4>
      <ul id="likedVideosList" tabindex="0" aria-label="List of liked videos"></ul>
    </div>
  </section>

  <!-- Games List Pages -->
  <section id="gamePage1" class="container" aria-label="HTML5 Games List Page 1" role="region" tabindex="0">
    <h2>HTML5 Games - Page 1</h2>
    <input id="gsearchbar" type="text" placeholder="Search games..." aria-label="Search games page 1" />
    <div id="glist1" class="glist" role="list" aria-label="List of games">
      <!-- Your games here -->
      <a href="javascript:void(0);" data-link="./gfiles/html5/2048/index.html" class="game-link" role="listitem" tabindex="0">2048</a>
      <a href="javascript:void(0);" data-link="./gfiles/html5/adarkroom/index.html" class="game-link" role="listitem" tabindex="0">A Dark Room</a>
      <a href="javascript:void(0);" data-link="./gfiles/html5/asciispace/index.html" class="game-link" role="listitem" tabindex="0">ASCII Space</a>

      <!-- Developer game buttons will be injected here -->

      <button id="nextPageButton" class="page-button" aria-label="Next Page">Next Page</button>
    </div>
  </section>

  <section id="gamePage2" class="container" aria-label="HTML5 Games List Page 2" role="region" tabindex="0" style="display:none;">
    <h2>HTML5 Games - Page 2</h2>
    <input id="secoundgsearchbar" type="text" placeholder="Search games..." aria-label="Search games page 2" />
    <div id="glist2" class="glist" role="list" aria-label="List of games">
      <a href="javascript:void(0);" data-link="./gfiles/html5/extragames/games/wordle.html" class="game-link" role="listitem" tabindex="0">Wordle</a>
      <a href="javascript:void(0);" data-link="./gfiles/html5/FullScreenMario-master/index.html" class="game-link" role="listitem" tabindex="0">Super-Mario-Bros</a>
      <a href="javascript:void(0);" data-link="./gfiles/html5/Games/slopeoffline.html" class="game-link" role="listitem" tabindex="0">Slope</a>

      <button id="prevPageButton" class="page-button" aria-label="Previous Page">Previous Page</button>
    </div>
  </section>

  <!-- Confirmation Dialog -->
  <div id="confirmationDialog" role="dialog" aria-modal="true" aria-labelledby="confirmDialogTitle" aria-describedby="confirmDialogDesc" style="display:none; position:fixed;top:50%;left:50%;transform:translate(-50%, -50%); background:white; color:black; border-radius:16px; padding:28px 36px; box-shadow:0 0 20px #000; max-width:400px;">
    <p id="confirmDialogTitle" style="font-weight:700; font-size:1.3rem; margin-top:0; margin-bottom:24px;">Are you sure you want to open this game?</p>
    <div style="text-align:right;">
      <button id="confirmYes" style="margin-right:16px; padding:12px 28px; font-weight:700; cursor:pointer;">Yes</button>
      <button id="confirmNo" style="padding:12px 28px; font-weight:700; cursor:pointer;">No</button>
    </div>
  </div>

  <!-- Notification container -->
  <div id="notification-container" aria-live="polite" aria-atomic="true" aria-relevant="additions"></div>

  <!-- Console UI -->
  <section id="consoleUI" role="region" aria-label="Developer Console" tabindex="-1">
    <h3>Console</h3>
    <div id="codeTabs" role="tablist" aria-label="Code Tabs" style="margin-bottom: 10px;"></div>
    <textarea id="consoleInput" spellcheck="false" aria-label="Console code input"></textarea>

    <div id="consoleOutputWrapper" role="log" aria-live="polite" aria-atomic="true" style="white-space: pre-wrap; font-family: monospace; background:#000; color:#0f0; padding:16px; border-radius:16px; height:130px; overflow-y:auto; margin-top:14px;"></div>

    <div id="consoleControls" style="margin-top: 16px; display:flex; flex-wrap: wrap; gap: 8px; justify-content: center; user-select:none;">
      <button id="runConsoleCode" title="Run Console Code">Run</button>
      <button id="saveCodeButton" title="Save Code">Save</button>
      <button id="deleteCodeButton" title="Delete All Code">Delete All</button>
      <button id="downloadCodeButton" title="Download Code">Download</button>
      <button id="uploadCodeButton" title="Upload Code">Upload</button>
      <button id="expandButton" title="Expand/Minimize Console">Expand</button>
      <button id="newTabButton" title="New Tab">New Tab</button>
      <button id="openRawConsoleLogs" title="Open raw console logs in new window">Open Logs</button>
    </div>
  </section>

  <!-- External libs -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/mode/javascript/javascript.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/addon/hint/show-hint.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/addon/hint/javascript-hint.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/particles.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.waves.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.clouds.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.fog.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.birds.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.cells.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.halo.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.rings.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.topology.min.js"></script>

  <script>
    (() => {
      'use strict';

      /******************************************
       * Variables and element references
       ******************************************/
      const overlay = document.getElementById('overlay');
      const passwordInput = document.getElementById('passwordInput');
      const submitPassword = document.getElementById('submitPassword');
      const errorMessage = document.getElementById('errorMessage');

      const settingsButton = document.getElementById('settingsButton');
      const settingsUI = document.getElementById('settingsUI');

      const darkModeToggle = document.getElementById('darkModeToggle');
      const themesDropdown = document.getElementById('themesDropdown');
      const enableDragCheckbox = document.getElementById('enableDrag');
      const toggleFavoritesCheckbox = document.getElementById('toggleFavorites');
      const toggleNotificationsCheckbox = document.getElementById('toggleNotifications');
      const autoSaveConsoleCheckbox = document.getElementById('autoSaveConsole');
      const consoleThemeSelect = document.getElementById('consoleThemeSelect');
      const gameFontSizeInput = document.getElementById('gameFontSize');

      const developerModeToggle = document.getElementById('toggleDevMode');
      const developerModeUI = document.getElementById('developerModeUI');
      const devModeContainer = document.getElementById('devModeContainer');
      const devPageSelect = document.getElementById('devPageSelect');
      const devGamesArea = document.getElementById('devGamesArea');
      const addDevPageBtn = document.getElementById('addDevPageBtn');
      const addDevGameBtn = document.getElementById('addDevGameBtn');

      const youtubeEmbedUI = document.getElementById('youtubeEmbedUI');
      const youtubeURLInput = document.getElementById('youtubeURL');
      const youtubeTypeSelect = document.getElementById('youtubeTypeSelect');
      const loadVideoButton = document.getElementById('loadVideoButton');
      const youtubeChangeButton = document.getElementById('youtubeChangeButton');
      const videoContainer = document.getElementById('video-container');
      const likedVideosContainer = document.getElementById('likedVideosContainer');
      const likedVideosList = document.getElementById('likedVideosList');

      const gamePage1 = document.getElementById('gamePage1');
      const gamePage2 = document.getElementById('gamePage2');
      const glist1 = document.getElementById('glist1');
      const glist2 = document.getElementById('glist2');

      const gsearchbar1 = document.getElementById('gsearchbar');
      const gsearchbar2 = document.getElementById('secoundgsearchbar');

      const nextPageButton = document.getElementById('nextPageButton');
      const prevPageButton = document.getElementById('prevPageButton');
      const gamesListButton = document.getElementById('gamesListButton');
      const youtubeUnblockerButton = document.getElementById('youtubeUnblockerButton');
      const consoleButton = document.getElementById('consoleButton');

      const confirmationDialog = document.getElementById('confirmationDialog');
      const confirmYes = document.getElementById('confirmYes');
      const confirmNo = document.getElementById('confirmNo');

      const notificationContainer = document.getElementById('notification-container');

      const consoleUI = document.getElementById('consoleUI');
      const codeTabs = document.getElementById('codeTabs');
      const consoleTextArea = document.getElementById('consoleInput');
      const consoleOutputWrapper = document.getElementById('consoleOutputWrapper');
      const consoleOutput = document.getElementById('consoleOutput');

      const runConsoleCodeBtn = document.getElementById('runConsoleCode');
      const saveConsoleCodeBtn = document.getElementById('saveCodeButton');
      const deleteConsoleCodeBtn = document.getElementById('deleteCodeButton');
      const downloadConsoleCodeBtn = document.getElementById('downloadCodeButton');
      const uploadConsoleCodeBtn = document.getElementById('uploadCodeButton');
      const expandConsoleBtn = document.getElementById('expandButton');
      const newTabBtn = document.getElementById('newTabButton');
      const openRawConsoleLogsBtn = document.getElementById('openRawConsoleLogs');

      let codeMirrorInstance;
      let toastIdCounter = 0;

      // Persistent Data Keys
      const LS_KEYS = {
        SETTINGS: 'app-settings',
        DEVGAMES: 'dev-games',
        DEVPAGES: 'dev-pages',
        CONSOLETABS: 'console-tabs',
        GAMEORDER: 'game-order',
        LIKEDVIDEOS: 'liked-videos'
      };

      // Global States
      let settings = {
        darkMode: false,
        theme: 'none',
        enableDrag: false,
        toggleFavorites: false,
        enableNotifications: true,
        autoSaveConsole: true,
        consoleTheme: 'monokai',
        gameFontSize: 18,
        developerMode: false
      };

      let devGames = []; // {id, label, clickCode, pageId}
      let devPages = [ // default pages
        { id: 'gamePage1', label: 'Games List Page 1' },
        { id: 'gamePage2', label: 'Games List Page 2' }
      ];
      let activeDevPage = 'gamePage1';




      let currentLinkToOpen = null;

      // --- UTILITIES ---

      function safeLocalGet(key, defaultVal) {
        try {
          let val = JSON.parse(localStorage.getItem(key));
          if (val === null) return defaultVal;
          return val;
        } catch (e) {
          return defaultVal;
        }
      }

      function safeLocalSet(key, val) {
        try {
          localStorage.setItem(key, JSON.stringify(val));
        } catch { }
      }

      // debounce utility for input throttling
      function debounce(func, wait = 200) {
        let timeout;
        return (...args) => {
          clearTimeout(timeout);
          timeout = setTimeout(() => func.apply(null, args), wait);
        }
      }

      // --- BACKGROUND VANTA ANIMATION ---

      let activeVantaEffect = null;

      function setupBackgroundAnimation(theme) {
        if (activeVantaEffect) {
          try { activeVantaEffect.destroy(); } catch { }
          activeVantaEffect = null;
        }
        const el = document.getElementById('particles-js');
        if (!el) return;

        if (theme === 'none') {
          el.style.backgroundColor = settings.darkMode ? '#222' : '#777';
          return;
        }

        el.style.backgroundColor = 'transparent';

        const config = {
          el: '#particles-js',
          mouseControls: true,
          touchControls: true,
          gyroControls: false,
          scale: 1.0,
          scaleMobile: 1.0
        };

        switch (theme) {
          case 'waves': activeVantaEffect = VANTA.WAVES(config); break;
          case 'net': activeVantaEffect = VANTA.NET(config); break;
          case 'clouds': activeVantaEffect = VANTA.CLOUDS(config); break;
          case 'fog': activeVantaEffect = VANTA.FOG(config); break;
          case 'birds': activeVantaEffect = VANTA.BIRDS(config); break;
          case 'cells': activeVantaEffect = VANTA.CELLS(config); break;
          case 'halo': activeVantaEffect = VANTA.HALO(config); break;
          case 'rings': activeVantaEffect = VANTA.RINGS(config); break;
          case 'globe': activeVantaEffect = VANTA.GLOBE(config); break;
          default:
            el.style.backgroundColor = settings.darkMode ? '#222' : '#777';
            break;
        }
      }

      // --- TOAST NOTIFICATIONS ---

      function createToast(msg, type = 'info', duration = 4500) {
        if (!settings.enableNotifications) return;
        const toast = document.createElement('div');
        toast.className = 'toast ' + type;
        toast.textContent = msg;
        toast.tabIndex = 0;

        const closeBtn = document.createElement('button');
        closeBtn.className = 'close';
        closeBtn.setAttribute('aria-label', 'Dismiss notification');
        closeBtn.innerHTML = '&times;';
        closeBtn.onclick = e => {
          e.stopPropagation();
          dismissToast(toast);
        };
        toast.appendChild(closeBtn);

        toast.onclick = () => dismissToast(toast);
        toast.onkeydown = e => {
          if(e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            dismissToast(toast);
          }
        };

        notificationContainer.appendChild(toast);
        toast.focus();

        setTimeout(() => dismissToast(toast), duration);

        return toast;
      }

      function dismissToast(toast) {
        if (!toast) return;
        toast.style.animation = "slideOutToast 0.4s forwards";
        toast.onanimationend = () => {
          if(toast.parentElement) toast.parentElement.removeChild(toast);
        }
      }

      // --- PASSWORD LOCK SCREEN ---

      let attemptCount = 0;
      const MAX_ATTEMPTS = 3;
      const CORRECT_PASSWORD = "dja101";

      function lockScreen() {
        overlay.style.display = "flex";
        document.body.classList.add("locked");
        passwordInput.focus();

        document.body.addEventListener("click", blockClick, true);
      }

      function unlockScreen() {
        overlay.style.display = "none";
        document.body.classList.remove("locked");
        document.body.removeEventListener("click", blockClick, true);
        sessionStorage.setItem("accessGranted", "true");
        sessionStorage.setItem("accessTime", Date.now());
        createToast("Access granted. Welcome!", "success");
      }

      function blockClick(e) {
        if (e.target !== passwordInput && e.target !== submitPassword) {
          e.preventDefault();
          e.stopPropagation();
        }
      }

      function checkSession() {
        const accessGranted = sessionStorage.getItem("accessGranted");
        const accessTimeRaw = sessionStorage.getItem("accessTime");
        if (!accessGranted) return false;
        if (!accessTimeRaw) return false;
        return Date.now() - Number(accessTimeRaw) < 30 * 60 * 1000; // 30 minutes
      }

      submitPassword.addEventListener('click', () => {
        if (passwordInput.value === CORRECT_PASSWORD) {
          errorMessage.style.display = 'none';
          unlockScreen();
        } else {
          attemptCount++;
          createToast("Incorrect password", "error");
          errorMessage.style.display = 'block';
          if (attemptCount >= MAX_ATTEMPTS) {
            errorMessage.textContent = "Access denied. Reload to try again.";
            passwordInput.disabled = true;
            submitPassword.disabled = true;
            createToast("Too many attempts. Reload the page to try again.", 'error', 9000);
          }
        }
        passwordInput.value = "";
      });

      if (!checkSession()) lockScreen();
      else unlockScreen();

      // --- SETTINGS PANEL ---

      settingsButton.onclick = () => {
        if (settingsUI.classList.contains("active")) {
          settingsUI.classList.remove("active");
          settingsButton.setAttribute("aria-expanded", "false");
        } else {
          settingsUI.classList.add("active");
          settingsButton.setAttribute("aria-expanded", "true");
          settingsUI.focus();
        }
      };

      // Load settings from localStorage
      function loadAppSettings() {
        let stored = safeLocalGet(LS_KEYS.SETTINGS, null);
        if (stored) settings = Object.assign({}, settings, stored);
      }

      // Save settings to localStorage
      function saveAppSettings() {
        safeLocalSet(LS_KEYS.SETTINGS, settings);
      }

      // Sync UI inputs with settings
      function syncSettingsUI() {
        darkModeToggle.checked = settings.darkMode;
        themesDropdown.value = settings.theme;
        enableDragCheckbox.checked = settings.enableDrag;
        toggleFavoritesCheckbox.checked = settings.toggleFavorites;
        toggleNotificationsCheckbox.checked = settings.enableNotifications;
        autoSaveConsoleCheckbox.checked = settings.autoSaveConsole;
        consoleThemeSelect.value = settings.consoleTheme;
        gameFontSizeInput.value = settings.gameFontSize;
        developerModeToggle.textContent = settings.developerMode ? "Disable Developer Mode" : "Enable Developer Mode";
        developerModeToggle.style.backgroundColor = settings.developerMode ? "#3a903a" : "#cc9933";
      }

      // Apply settings to UI and behavior
      function applyAppSettings() {
        document.body.classList.toggle('dark-mode', settings.darkMode);
        setupBackgroundAnimation(settings.theme);
        enableDrag(settings.enableDrag);
        addFavoriteClickHandler(settings.toggleFavorites);
        applyGameFontSize(settings.gameFontSize);
        if (codeMirrorInstance) codeMirrorInstance.setOption('theme', settings.consoleTheme);
        toggleDeveloperModeUI(settings.developerMode);
        saveAppSettings();
      }

      darkModeToggle.onchange = e => {
        settings.darkMode = e.target.checked;
        applyAppSettings();
      };

      themesDropdown.onchange = e => {
        settings.theme = e.target.value;
        applyAppSettings();
      };

      enableDragCheckbox.onchange = e => {
        settings.enableDrag = e.target.checked;
        applyAppSettings();
      };

      toggleFavoritesCheckbox.onchange = e => {
        settings.toggleFavorites = e.target.checked;
        applyAppSettings();
      };

      toggleNotificationsCheckbox.onchange = e => {
        settings.enableNotifications = e.target.checked;
        saveAppSettings();
      };

      autoSaveConsoleCheckbox.onchange = e => {
        settings.autoSaveConsole = e.target.checked;
        saveAppSettings();
      };

      consoleThemeSelect.onchange = e => {
        settings.consoleTheme = e.target.value;
        applyAppSettings();
      };

      gameFontSizeInput.onchange = e => {
        let val = parseInt(e.target.value);
        if (isNaN(val) || val < 12) val = 12;
        else if (val > 30) val = 30;
        settings.gameFontSize = val;
        applyAppSettings();
      };

      developerModeToggle.onclick = () => {
        settings.developerMode = !settings.developerMode;
        applyAppSettings();
      };

      // --- DRAG & DROP ---

      let dragElement = null;

      function enableDrag(enable) {
        document.querySelectorAll(".glist a.game-link").forEach(el => {
          if (enable) {
            el.setAttribute('draggable', 'true');
            el.style.userSelect = 'none';
            el.addEventListener('dragstart', dragStartHandler);
            el.addEventListener('dragover', dragOverHandler);
            el.addEventListener('drop', dropHandler);
            el.addEventListener('dragend', dragEndHandler);
          } else {
            el.removeAttribute('draggable');
            el.style.userSelect = '';
            el.removeEventListener('dragstart', dragStartHandler);
            el.removeEventListener('dragover', dragOverHandler);
            el.removeEventListener('drop', dropHandler);
            el.removeEventListener('dragend', dragEndHandler);
          }
        });
      }

      function dragStartHandler(e) {
        dragElement = e.target;
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/plain', e.target.dataset.link);
        e.target.style.opacity = '0.5';
      }

      function dragOverHandler(e) {
        e.preventDefault();
        const target = e.target.closest('a.game-link');
        if (target && target !== dragElement) {
          const rect = target.getBoundingClientRect();
          const after = e.clientY > rect.top + rect.height / 2;
          target.parentNode.insertBefore(dragElement, after ? target.nextSibling : target);
        }
      }

      function dropHandler(e) {
        e.preventDefault();
        dragElement.style.opacity = '';
        dragElement = null;
        saveGameOrder();
        createToast('Games reordered!', 'success');
      }

      function dragEndHandler(e) {
        e.target.style.opacity = '';
        dragElement = null;
      }

      // --- Favorites toggle on click ---

      function toggleFavorite(e) {
        if (!settings.toggleFavorites) return;
        e.preventDefault();
        const el = e.currentTarget;
        el.classList.toggle('favorite');
        reorderFavorites();
        saveGameOrder();
        createToast(`${el.textContent} ${el.classList.contains('favorite') ? 'added to' : 'removed from'} favorites`, 'info');
      }

      function addFavoriteClickHandler(enable) {
        document.querySelectorAll('.glist a.game-link').forEach(el => {
          if (enable) el.addEventListener('click', toggleFavorite);
          else el.removeEventListener('click', toggleFavorite);
        });
      }

      function reorderFavorites() {
        document.querySelectorAll('.glist').forEach(container => {
          [...container.querySelectorAll('a.favorite')].forEach(fav => container.prepend(fav));
        });
      }

      // --- Games List Search ---

      function filterGames(query) {
        const q = query.toLowerCase();
        document.querySelectorAll('a.game-link').forEach(link => {
          if (link.textContent.toLowerCase().includes(q)) link.style.display = '';
          else link.style.display = 'none';
        });
      }
      gsearchbar1.addEventListener('input', e => filterGames(e.target.value));
      gsearchbar2.addEventListener('input', e => filterGames(e.target.value));

      // --- CONFIRMATION DIALOG ---

      let linkToOpen = null;

      document.querySelectorAll('.glist a.game-link').forEach(link => {
        link.addEventListener('click', e => {
          if (!settings.enableDrag && !settings.toggleFavorites) {
            e.preventDefault();
            linkToOpen = e.currentTarget.dataset.link;
            confirmationDialog.style.display = 'flex';
            confirmNo.focus();
          }
        });
      });

      confirmYes.onclick = () => {
        confirmationDialog.style.display = 'none';
        if (linkToOpen) window.location.href = linkToOpen;
      };

      confirmNo.onclick = () => {
        confirmationDialog.style.display = 'none';
        linkToOpen = null;
      };

      // --- Console Initialization ---

      let consoleTabs = safeLocalGet(LS_KEYS.CONSOLETABS, { 'tab-0': '' });
      let activeConsoleTab = 0;

      function tabName(index) {
        return 'tab-' + index;
      }

      function saveConsoleTabs() {
        safeLocalSet(LS_KEYS.CONSOLETABS, consoleTabs);
      }

      function createCodeMirrorInstance() {
        codeMirrorInstance = CodeMirror.fromTextArea(consoleTextArea, {
          mode: 'javascript',
          theme: settings.consoleTheme,
          lineNumbers: true,
          autoCloseBrackets: true,
          matchBrackets: true,
          lineWrapping: true,
          extraKeys: { 'Ctrl-Space': 'autocomplete' }
        });
        codeMirrorInstance.on('change', () => {
          if (settings.autoSaveConsole) {
            const key = tabName(activeConsoleTab);
            consoleTabs[key] = codeMirrorInstance.getValue();
            saveConsoleTabs();
          }
        });
      }

      function rebuildConsoleTabsUI() {
        codeTabs.innerHTML = '';
        Object.keys(consoleTabs).sort((a, b) => {
          return parseInt(a.split('-')[1]) - parseInt(b.split('-')[1]);
        }).forEach(tabKey => {
          addConsoleTab(tabKey);
        });
        addNewConsoleTabButton();
        if (Object.keys(consoleTabs).length > 0) switchConsoleTab(0);
      }

      function addConsoleTab(tabKey) {
        const index = parseInt(tabKey.split('-')[1]);
        const tab = document.createElement('div');
        tab.className = 'code-tab';
        tab.textContent = `Tab ${index + 1}`;
        tab.dataset.tabKey = tabKey;
        tab.tabIndex = 0;
        if (index === activeConsoleTab) tab.classList.add('active');

        tab.onclick = () => switchConsoleTab(index);
        tab.onkeydown = e => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            switchConsoleTab(index);
          }
        };

        const closeBtn = document.createElement('span');
        closeBtn.textContent = '×';
        closeBtn.className = 'close-tab';
        closeBtn.tabIndex = 0;
        closeBtn.onclick = e => {
          e.stopPropagation();
          removeConsoleTab(index);
        };
        closeBtn.onkeydown = e => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            removeConsoleTab(index);
          }
        };

        tab.appendChild(closeBtn);
        codeTabs.appendChild(tab);
      }

      function addNewConsoleTabButton() {
        const btn = document.createElement('div');
        btn.className = 'code-tab';
        btn.textContent = '+';
        btn.tabIndex = 0;
        btn.title = "New Tab";
        btn.onclick = () => addConsoleTabHandler();
        btn.onkeydown = e => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            addConsoleTabHandler();
          }
        };
        codeTabs.appendChild(btn);
      }

      function switchConsoleTab(index) {
        const key = tabName(index);
        if (!consoleTabs.hasOwnProperty(key)) return;
        activeConsoleTab = index;
        document.querySelectorAll('.code-tab').forEach(t => {
          t.classList.remove('active');
          if (t.dataset.tabKey === key) t.classList.add('active');
        });
        codeMirrorInstance.setValue(consoleTabs[key]);
        codeMirrorInstance.focus();
        createToast(`Switched to Tab ${index + 1}`, 'info');
      }

      function addConsoleTabHandler() {
        let idx = Object.keys(consoleTabs).length > 0 ? Math.max(...Object.keys(consoleTabs).map(k => parseInt(k.split('-')[1]))) + 1 : 0;
        consoleTabs[tabName(idx)] = '';
        saveConsoleTabs();
        rebuildConsoleTabsUI();
        switchConsoleTab(idx);
        createToast(`Added new tab #${idx + 1}`, 'success');
      }

      function removeConsoleTab(index) {
        const key = tabName(index);
        if (!consoleTabs.hasOwnProperty(key)) return;
        if (!confirm(`Close tab ${index + 1}?`)) return;
        delete consoleTabs[key];
        saveConsoleTabs();
        rebuildConsoleTabsUI();
        const keys = Object.keys(consoleTabs).sort();
        if (keys.length > 0) {
          switchConsoleTab(parseInt(keys[0].split('-')[1]));
        } else {
          addConsoleTabHandler();
        }
        createToast(`Closed tab ${index + 1}`, 'warning');
      }

      function runConsoleCode() {
        const code = codeMirrorInstance.getValue();
        if (/<!DOCTYPE html>|<html/i.test(code)) {
          const newWin = window.open();
          newWin.document.write(code);
          newWin.document.close();
          createToast('HTML content opened in new window', 'success');
          return;
        }
        try {
          const api = window.api;
          const fn = new Function('api', `"use strict"; return (async()=>{${code}})();`);
          const result = fn(api);
          if (result?.then) {
            result.then(res => {
              if (res !== undefined) logConsoleOutput(res);
            }).catch(err => {
              logConsoleOutput('Error: ' + err.message);
              createToast('Error: ' + err.message, 'error');
            });
          } else {
            if (result !== undefined) logConsoleOutput(result);
          }
        } catch (e) {
          logConsoleOutput('Error: ' + e.message);
          createToast('Error: ' + e.message, 'error');
        }
      }

      function logConsoleOutput(msg) {
        const now = new Date().toLocaleTimeString();
        consoleOutput.textContent += `[${now}] ${msg}\n`;
        consoleOutputWrapper.scrollTop = consoleOutputWrapper.scrollHeight;
      }

      newTabBtn.onclick = addConsoleTabHandler;
      runConsoleCodeBtn.onclick = runConsoleCode;
      saveConsoleCodeBtn.onclick = () => {
        consoleTabs[tabName(activeConsoleTab)] = codeMirrorInstance.getValue();
        saveConsoleTabs();
        createToast('Console code saved', 'success');
      };
      deleteConsoleCodeBtn.onclick = () => {
        if (confirm('Delete all saved console code?')) {
          consoleTabs = { 'tab-0': '' };
          activeConsoleTab = 0;
          saveConsoleTabs();
          rebuildConsoleTabsUI();
          codeMirrorInstance.setValue('');
          createToast('Deleted all console code', 'warning');
        }
      };
      downloadConsoleCodeBtn.onclick = () => {
        const code = codeMirrorInstance.getValue();
        const blob = new Blob([code], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `console_tab_${activeConsoleTab + 1}.txt`;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(url);
        createToast('Downloaded console code', 'success');
      };
      uploadConsoleCodeBtn.onclick = () => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.txt';
        input.onchange = e => {
          const file = e.target.files[0];
          if (!file) return;
          const reader = new FileReader();
          reader.onload = evt => {
            codeMirrorInstance.setValue(evt.target.result);
            createToast(`Loaded file: ${file.name}`, 'success');
          };
          reader.readAsText(file);
        };
        input.click();
      };
      expandConsoleBtn.onclick = () => {
        document.body.classList.toggle('fullscreen-console');
        expandConsoleBtn.textContent = document.body.classList.contains('fullscreen-console') ? 'Minimize' : 'Expand';
        codeMirrorInstance.refresh();
      };
      openRawConsoleLogsBtn.onclick = () => {
        const newWin = window.open();
        if (!newWin) {
          alert('Popup blocked!');
          return;
        }
        const safeLogs = consoleOutput.textContent.replace(/</g, "&lt;").replace(/>/g, "&gt;");
        newWin.document.write(`
          <title>Console Logs</title>
          <textarea style="font-family: monospace; font-size: 14px; width: 100vw; height: 100vh;" readonly>${safeLogs}</textarea>
        `);
        newWin.document.close();
      };

      // --- TOAST ALIAS
      window.toast = createToast;

      // --- API Exposed to Console Code ---

      window.api = {
        toast: createToast,
        wait: async (seconds) => new Promise(res => setTimeout(res, seconds * 1000)),
        log: logConsoleOutput,

        listTabs: () => Object.keys(consoleTabs),

        openTab: (index) => { switchConsoleTab(index); },

        createTab: () => addConsoleTabHandler(),

        saveCurrentCode: (code) => {
          consoleTabs[tabName(activeConsoleTab)] = code;
          saveConsoleTabs();
          codeMirrorInstance.setValue(code);
          createToast('Saved current code via API');
        },

        getSettings: () => ({ ...settings }),

        updateSettings: (newSettings) => {
          Object.entries(newSettings).forEach(([k, v]) => {
            if (settings.hasOwnProperty(k)) settings[k] = v;
          });
          syncSettingsUI();
          applyAppSettings();
          createToast('Settings updated via API');
        },

        listGames: () => {
          return Array.from(document.querySelectorAll('.glist a.game-link')).map(el => ({
            title: el.textContent,
            url: el.dataset.link,
            favorite: el.classList.contains('favorite')
          }));
        },

        addFavorite: (url) => {
          const el = document.querySelector(`.glist a[data-link="${url}"]`);
          if (el && !el.classList.contains('favorite')) {
            el.classList.add('favorite');
            reorderFavorites();
            saveGameOrder();
            createToast(`Added to favorites: ${el.textContent}`, 'success');
          }
        },

        removeFavorite: (url) => {
          const el = document.querySelector(`.glist a[data-link="${url}"]`);
          if (el && el.classList.contains('favorite')) {
            el.classList.remove('favorite');
            reorderFavorites();
            saveGameOrder();
            createToast(`Removed from favorites: ${el.textContent}`, 'info');
          }
        },

        // Developer Mode APIs (only active if developerMode enabled)
        addDevGame: (label, clickCode, pageId = activeDevPage) => {
          if (!settings.developerMode) {
            createToast('Developer Mode not enabled', 'error');
            return;
          }
          addDevGame(label, clickCode, pageId);
        },

        removeDevGame: id => {
          if (!settings.developerMode) {
            createToast('Developer Mode not enabled', 'error');
            return;
          }
          devGames = devGames.filter(g => g.id !== id);
          safeLocalSet(LS_KEYS.DEVGAMES, devGames);
          refreshDevGamesUI();
          createToast('Dev game removed', 'warning');
        },

        listDevGames: () => {
          if (!settings.developerMode) {
            createToast('Developer Mode not enabled', 'error');
            return;
          }
          return devGames;
        },

        showPage: pageId => {
          activeDevPage = pageId;
          showPage(pageId);
          if (settings.developerMode) refreshDevGamesUI();
        },
      };

      // --- Dev Mode UI Management ---

      function toggleDeveloperModeUI(enabled) {
        developerModeUI.style.display = enabled ? 'block' : 'none';
        developerModeToggle.textContent = enabled ? 'Disable Developer Mode' : 'Enable Developer Mode';
        developerModeToggle.style.backgroundColor = enabled ? '#2d8f2d' : '#cc9933';
        safeLocalSet(LS_KEYS.SETTINGS, settings);
        if (enabled) {
          buildDevPagesSelect();
          refreshDevGamesUI();
        }
      }

      developerModeToggle.onclick = () => {
        settings.developerMode = !settings.developerMode;
        applyAppSettings();
      };

      // Dev Page Select setup + Adding new pages
      function buildDevPagesSelect() {
        devPageSelect.innerHTML = '';
        devPages.forEach(page => {
          const option = document.createElement('option');
          option.value = page.id;
          option.textContent = page.label;
          devPageSelect.appendChild(option);
        });
        devPageSelect.value = activeDevPage;

        devPageSelect.onchange = e => {
          activeDevPage = e.target.value;
          refreshDevGamesUI();
          showPage(activeDevPage);
        };

        addDevPageBtn.onclick = () => {
          const label = prompt('Enter new page label (e.g. Custom Page)');
          if (!label) return;
          const id = 'custom-' + Date.now();
          devPages.push({ id, label });
          safeLocalSet(LS_KEYS.DEVPAGES, devPages);
          buildDevPagesSelect();
          devPageSelect.value = id;
          devPageSelect.dispatchEvent(new Event('change'));
          createToast(`New page created: ${label}`, 'success');
        };
      }

      // Dev games UI rendering
      function refreshDevGamesUI() {
        devGamesArea.innerHTML = '';
        const gamesOnPage = devGames.filter(g => g.pageId === activeDevPage);
        if (gamesOnPage.length === 0) {
          devGamesArea.innerHTML = `<p style="color:#aaa; font-style: italic;">No developer games on this page.</p>`;
          return;
        }
        gamesOnPage.forEach(game => {
          const div = document.createElement('div');
          div.style.display = 'flex';
          div.style.justifyContent = 'space-between';
          div.style.alignItems = 'center';
          div.style.backgroundColor = '#555';
          div.style.padding = '6px 12px';
          div.style.borderRadius = '10px';
          div.style.marginBottom = '10px';
          div.style.color = 'white';

          const span = document.createElement('span');
          span.textContent = game.label;

          const btnsContainer = document.createElement('div');
          btnsContainer.style.display = 'flex';
          btnsContainer.style.gap = '12px';

          const runBtn = document.createElement('button');
          runBtn.textContent = 'Run';
          runBtn.style.backgroundColor = '#4c9aff';
          runBtn.onclick = () => {
            try {
              const fn = new Function('toast', 'api', `'use strict'; ${game.clickCode}`);
              fn(createToast, window.api);
              createToast(`Ran dev game "${game.label}"`, 'success');
            } catch (e) {
              createToast(`Error running dev game: ${e.message}`, 'error');
            }
          };

          const editBtn = document.createElement('button');
          editBtn.textContent = 'Edit';
          editBtn.style.backgroundColor = '#ffaa33';
          editBtn.onclick = () => editDevGame(game.id);

          const delBtn = document.createElement('button');
          delBtn.textContent = 'Delete';
          delBtn.style.backgroundColor = '#cc2222';
          delBtn.onclick = () => {
            if (confirm(`Delete "${game.label}"? This cannot be undone.`)) {
              devGames = devGames.filter(g => g.id !== game.id);
              safeLocalSet(LS_KEYS.DEVGAMES, devGames);
              refreshDevGamesUI();
              createToast('Deleted dev game', 'warning');
            }
          };

          btnsContainer.appendChild(runBtn);
          btnsContainer.appendChild(editBtn);
          btnsContainer.appendChild(delBtn);

          div.appendChild(span);
          div.appendChild(btnsContainer);

          devGamesArea.appendChild(div);
        });
      }

      // Edit dev game popup
      function editDevGame(id) {
        const game = devGames.find(g => g.id === id);
        if (!game) {
          createToast('Game not found', 'error');
          return;
        }

        createModalPrompt({
          title: `Edit "${game.label}"`,
          body: `
            <label>Label:<br><input id="editDevLabel" type="text" value="${game.label}" style="width: calc(100% - 16px); padding: 6px; font-weight: 600; font-size: 1rem;"></label><br>
            <label>Click Code (JS):<br><textarea id="editDevCode" style="width: calc(100% - 16px); height: 140px; font-family: monospace; font-weight: 700; font-size: 1rem;">${game.clickCode}</textarea></label><br>
            <label>Page:<br>
              <select id="editDevPageSelect">${devPages.map(p => `<option value="${p.id}" ${p.id === game.pageId ? 'selected' : ''}>${p.label}</option>`).join('')}</select>
            </label>
            <div style="text-align: right;">
              <button id="saveDevGameBtn" style="background: #4c9aff; padding: 12px 28px; font-weight: 700; color: white; border:none; border-radius:14px; cursor:pointer;">Save</button>
              <button id="cancelDevGameBtn" style="margin-left: 16px; padding: 12px 28px; font-weight: 700; background:#ccc; border:none; border-radius:14px; cursor:pointer;">Cancel</button>
            </div>
          `,
          onSave: () => {
            const newLabel = document.getElementById('editDevLabel').value.trim();
            const newCode = document.getElementById('editDevCode').value;
            const newPage = document.getElementById('editDevPageSelect').value;
            if (newLabel.length === 0) {
              alert('Label cannot be empty');
              return false;
            }
            game.label = newLabel;
            game.clickCode = newCode;
            game.pageId = newPage;
            safeLocalSet(LS_KEYS.DEVGAMES, devGames);
            refreshDevGamesUI();
            createToast('Saved dev game changes', 'success');
            return true; // close modal
          }
        });
      }

      // Modal prompt constructor
      function createModalPrompt({ title, body, onSave }) {
        const overlay = document.createElement('div');
        overlay.style.cssText = `
          position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 101000;
          display: flex; align-items: center; justify-content: center; user-select:none;
        `;

        const modal = document.createElement('div');
        modal.style.cssText = `
          background: #222; border-radius: 24px; padding: 20px 28px; max-width: 460px;
          color: white; font-weight: 700;
          user-select: text;
        `;

        const h2 = document.createElement('h2');
        h2.textContent = title;
        h2.style.marginTop = 0;
        h2.style.textAlign = 'center';

        const bodyWrapper = document.createElement('div');
        bodyWrapper.innerHTML = body;
        bodyWrapper.style.marginBottom = '12px';

        modal.appendChild(h2);
        modal.appendChild(bodyWrapper);
        overlay.appendChild(modal);
        document.body.appendChild(overlay);

        function close() { document.body.removeChild(overlay); }

        document.getElementById('saveDevGameBtn').onclick = () => {
          const success = onSave();
          if (success) close();
        };
        document.getElementById('cancelDevGameBtn').onclick = close;

        return modal;
      }

      // Add dev game button click inside developer mode UI
      addDevGameBtn.onclick = () => {
        createModalPrompt({
          title: 'Add New Dev Game',
          body: `
            <label>Label:<br><input id="newDevLabel" type="text" style="width: calc(100% - 16px); padding: 8px;" value="New Dev Game"></label><br>
            <label>Click JS Code:<br><textarea id="newDevCode" style="width: calc(100% - 16px); height: 140px; font-family: monospace; font-weight: 700; font-size: 1rem;">toast('Hello from new dev game!');</textarea></label><br>
            <label>Page:<br>
              <select id="newDevPageSelect">${devPages.map(p => `<option value="${p.id}">${p.label}</option>`).join('')}</select>
            </label>
            <div style="text-align: right;">
              <button id="newDevSaveBtn" style="background: #4c9aff; padding: 12px 28px; font-weight: 700; color: white; border:none; border-radius:14px; cursor:pointer;">Add</button>
              <button id="newDevCancelBtn" style="margin-left: 16px; padding: 12px 28px; font-weight: 700; background:#ccc; border:none; border-radius:14px; cursor:pointer;">Cancel</button>
            </div>
          `,
          onSave: () => {
            const label = document.getElementById('newDevLabel').value.trim();
            const code = document.getElementById('newDevCode').value;
            const pageId = document.getElementById('newDevPageSelect').value;
            if (!label) { alert('Label cannot be empty'); return false; }
            addDevGame(label, code, pageId);
            return true;
          }
        });
      };

      function addDevGame(label, clickCode, pageId = 'gamePage1') {
        const newGame = {
          id: 'devgame-' + Date.now() + '-' + Math.floor(Math.random() * 1e6),
          label,
          clickCode,
          pageId
        };
        devGames.push(newGame);
        safeLocalSet(LS_KEYS.DEVGAMES, devGames);
        if (pageId === activeDevPage && settings.developerMode) {
          refreshDevGamesUI();
        }
        createToast(`Developer game "${label}" added!`, 'success');
      }

      // --- Developer mode toggle refresh ---
      function refreshDevGamesUI() {
        devGamesArea.innerHTML = '';
        const filteredGames = devGames.filter(g => g.pageId === activeDevPage);
        if (filteredGames.length === 0) {
          devGamesArea.innerHTML = '<p style="color:#ccc; font-style:italic;">No developer games on this page.</p>';
          return;
        }
        filteredGames.forEach(game => {
          const div = document.createElement('div');
          const labelSpan = document.createElement('span');
          labelSpan.textContent = game.label;
          labelSpan.style.fontWeight = '700';

          const btnRun = document.createElement('button');
          btnRun.textContent = 'Run JS';
          btnRun.onclick = () => {
            try {
              const fn = new Function('toast', 'api', `'use strict'; ${game.clickCode}`);
              fn(createToast, window.api);
              createToast(`Ran developer game "${game.label}"`, 'success');
            } catch (e) {
              createToast(`Error: ${e.message}`, 'error');
            }
          };

          const btnEdit = document.createElement('button');
          btnEdit.textContent = 'Edit';
          btnEdit.style.backgroundColor = '#ffaa33';
          btnEdit.onclick = () => editDevGame(game.id);

          const btnDelete = document.createElement('button');
          btnDelete.textContent = 'Delete';
          btnDelete.style.backgroundColor = '#cc2222';
          btnDelete.onclick = () => {
            if (confirm(`Delete dev game "${game.label}"?`)) {
              devGames = devGames.filter(g => g.id !== game.id);
              safeLocalSet(LS_KEYS.DEVGAMES, devGames);
              refreshDevGamesUI();
              createToast('Deleted dev game', 'warning');
            }
          };

          div.style.display = 'flex';
          div.style.justifyContent = 'space-between';
          div.style.alignItems = 'center';
          div.style.marginBottom = '12px';

          const btnGroup = document.createElement('div');
          btnGroup.style.display = 'flex';
          btnGroup.style.gap = '10px';

          btnGroup.appendChild(btnRun);
          btnGroup.appendChild(btnEdit);
          btnGroup.appendChild(btnDelete);

          div.appendChild(labelSpan);
          div.appendChild(btnGroup);

          devGamesArea.appendChild(div);
        });
      }

      // --- Initial Setup ---

      function showPage(id) {
        gamePage1.style.display = gamePage2.style.display = youtubeEmbedUI.classList.remove('active') && consoleUI.classList.remove('active') && 'none';

        switch (id) {
          case 'gamePage1': gamePage1.style.display = 'flex'; break;
          case 'gamePage2': gamePage2.style.display = 'flex'; break;
          case 'youtubeEmbedUI': youtubeEmbedUI.classList.add('active'); break;
          case 'consoleUI': consoleUI.classList.add('active'); break;
          default: break;
        }
      }

      // --- YouTube Embed & Likes ---

      let likedVideosMap = new Map(safeLocalGet(LS_KEYS.LIKEDVIDEOS, []));

      function saveLikedVideos() {
        safeLocalSet(LS_KEYS.LIKEDVIDEOS, Array.from(likedVideosMap.entries()));
      }

      function refreshLikedVideosUI() {
        likedVideosList.innerHTML = '';
        if (likedVideosMap.size === 0) {
          likedVideosList.innerHTML = '<li>No liked videos yet.</li>';
          return;
        }
        likedVideosMap.forEach((title, id) => {
          const li = document.createElement('li');
          li.textContent = title;
          li.tabIndex = 0;
          li.title = `Play or unlike ${title}`;

          const spanLike = document.createElement('span');
          spanLike.textContent = '♥';
          spanLike.className = 'likeBtn';
          spanLike.tabIndex = 0;
          spanLike.title = "Unlike video";
          spanLike.onclick = e => {
            e.stopPropagation();
            likedVideosMap.delete(id);
            saveLikedVideos();
            refreshLikedVideosUI();
            createToast(`Unliked video: ${title}`, 'warning');
          };
          spanLike.onkeydown = e => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              spanLike.onclick();
            }
          };

          li.appendChild(spanLike);

          li.onclick = () => playYouTube(videoId = id, title);
          li.onkeydown = e => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              li.onclick();
            }
          };

          likedVideosList.appendChild(li);
        });
      }

      function playYouTube(videoId, title = '') {
        youtubeEmbedUI.querySelector('#video-container').innerHTML = `<iframe width="100%" height="100%" src="https://www.youtube-nocookie.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe>`;
        likedVideosContainer.style.display = 'none';
        videoContainer.style.display = 'block';
        showLikeButton(videoId);
        createToast(`Playing ${title || 'video'}`, 'info');
      }

      function showLikeButton(videoId) {
        let existingBtn = document.getElementById('youtubeLikeBtn');
        if (existingBtn) existingBtn.remove();

        const btn = document.createElement('button');
        btn.id = 'youtubeLikeBtn';
        btn.style.marginTop = '10px';
        btn.style.padding = '12px 30px';
        btn.style.borderRadius = '20px';
        btn.style.fontWeight = '700';
        btn.style.fontSize = '1.1rem';
        btn.style.userSelect = 'none';
        btn.style.cursor = 'pointer';

        const liked = likedVideosMap.has(videoId);
        btn.textContent = liked ? '♥ Unlike' : '♡ Like';
        btn.style.backgroundColor = liked ? 'gold' : '#4c9aff';
        btn.style.color = liked ? 'black' : 'white';

        btn.onclick = () => {
          if (likedVideosMap.has(videoId)) {
            likedVideosMap.delete(videoId);
            btn.textContent = '♡ Like';
            btn.style.backgroundColor = '#4c9aff';
            btn.style.color = 'white';
            createToast('Video unliked', 'warning');
          } else {
            likedVideosMap.set(videoId, videoId);
            btn.textContent = '♥ Unlike';
            btn.style.backgroundColor = 'gold';
            btn.style.color = 'black';
            createToast('Video liked', 'success');
          }
          saveLikedVideos();
          refreshLikedVideosUI();
        };
        videoContainer.appendChild(btn);
      }

      // Load video or playlist or liked list based on YouTube UI
      loadVideoButton.onclick = async () => {
        likedVideosContainer.style.display = 'none';
        videoContainer.style.display = 'none';
        videoContainer.innerHTML = '';
        youtubeChangeButton.style.display = 'inline-block';
        youtubeURLInput.style.display = 'none';
        loadVideoButton.style.display = 'none';

        const url = youtubeURLInput.value.trim();
        if (!url) {
          createToast('Please enter a YouTube link URL!', 'warning');
          youtubeURLInput.style.display = 'block';
          loadVideoButton.style.display = 'inline-block';
          youtubeChangeButton.style.display = 'none';
          return;
        }

        const type = youtubeTypeSelect.value;
        if (type === 'video') {
          const videoId = extractYouTubeVideoID(url);
          if (!videoId) {
            createToast('Invalid YouTube video URL!', 'error');
            youtubeURLInput.style.display = 'block';
            loadVideoButton.style.display = 'inline-block';
            youtubeChangeButton.style.display = 'none';
            return;
          }
          playYouTube(videoId);
          videoContainer.style.display = 'block';
        } else if (type === 'playlist') {
          const playlistId = extractYouTubePlaylistId(url);
          if (!playlistId) {
            createToast('Invalid playlist URL!', 'error');
            youtubeURLInput.style.display = 'block';
            loadVideoButton.style.display = 'inline-block';
            youtubeChangeButton.style.display = 'none';
            return;
          }
          videoContainer.innerHTML = `<iframe src="https://www.youtube-nocookie.com/embed/videoseries?list=${playlistId}" width="100%" height="100%" frameborder="0" allowfullscreen></iframe>`;
          videoContainer.style.display = 'block';
          createToast('Playlist loaded', 'success');
        } else if (type === 'liked') {
          likedVideosContainer.style.display = 'block';
          refreshLikedVideosUI();
        }
      };

      youtubeChangeButton.onclick = () => {
        likedVideosContainer.style.display = 'none';
        videoContainer.style.display = 'none';
        videoContainer.innerHTML = '';
        youtubeChangeButton.style.display = 'none';
        youtubeURLInput.style.display = 'block';
        youtubeURLInput.value = '';
        youtubeURLInput.focus();
        loadVideoButton.style.display = 'inline-block';
      };

      // --- Games List page navigation
      nextPageButton.onclick = () => {
        showPage('gamePage2');
        gsearchbar2.value = '';
        gsearchbar2.dispatchEvent(new Event('input'));
      };

      prevPageButton.onclick = () => {
        showPage('gamePage1');
        gsearchbar1.value = '';
        gsearchbar1.dispatchEvent(new Event('input'));
      };

      gamesListButton.onclick = () => showPage('gamePage1');
      youtubeUnblockerButton.onclick = () => {
        if (youtubeEmbedUI.classList.contains('active')) showPage('gamePage1');
        else showPage('youtubeEmbedUI');
      };
      consoleButton.onclick = () => {
        if (consoleUI.classList.contains('active')) showPage('gamePage1');
        else showPage('consoleUI');
      };

      // --- Initialize CodeMirror for Console ---
      function setupConsole() {
        codeMirrorInstance = CodeMirror.fromTextArea(consoleTextArea, {
          mode: 'javascript',
          theme: settings.consoleTheme,
          lineNumbers: true,
          autoCloseBrackets: true,
          matchBrackets: true,
          lineWrapping: true,
          extraKeys: { 'Ctrl-Space': 'autocomplete' },
          viewportMargin: Infinity
        });

        codeMirrorInstance.on('change', () => {
          if (settings.autoSaveConsole) {
            const key = `tab-${activeConsoleTab}`;
            consoleTabs[key] = codeMirrorInstance.getValue();
            saveConsoleTabs();
          }
        });

        rebuildConsoleTabsUI();

        runConsoleCodeBtn.onclick = runConsoleCode;
        saveConsoleCodeBtn.onclick = () => {
          const key = `tab-${activeConsoleTab}`;
          consoleTabs[key] = codeMirrorInstance.getValue();
          saveConsoleTabs();
          createToast('Console saved', 'success');
        };
        deleteConsoleCodeBtn.onclick = () => {
          if (confirm('Delete all console code?')) {
            consoleTabs = { 'tab-0': ''};
            activeConsoleTab = 0;
            saveConsoleTabs();
            rebuildConsoleTabsUI();
            codeMirrorInstance.setValue('');
            createToast('Console cleared', 'warning');
          }
        };
        downloadConsoleCodeBtn.onclick = () => {
          const code = codeMirrorInstance.getValue();
          const blob = new Blob([code], {type:'text/plain'});
          const url = URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.style.display = 'none';
          a.href = url;
          a.download = `console_tab_${activeConsoleTab + 1}.txt`;
          document.body.appendChild(a);
          a.click();
          URL.revokeObjectURL(url);
          a.remove();
          createToast('Console code downloaded', 'success');
        };
        uploadConsoleCodeBtn.onclick = () => {
          const input = document.createElement('input');
          input.type = 'file';
          input.accept = '.txt';
          input.onclick = e => e.stopPropagation();
          input.onchange = e => {
            const file = e.target.files[0];
            if (!file) return;
            const reader = new FileReader();
            reader.onload = ev => {
              codeMirrorInstance.setValue(ev.target.result);
              createToast(`Loaded ${file.name}`, 'success');
            };
            reader.readAsText(file);
          };
          input.click();
        };
        expandConsoleBtn.onclick = () => {
          document.body.classList.toggle('fullscreen-console');
          const collapsed = !document.body.classList.contains('fullscreen-console');
          expandConsoleBtn.textContent = collapsed ? 'Expand' : 'Minimize';
          setTimeout(() => codeMirrorInstance.refresh(), 200);
        };
        newTabBtn.onclick = () => {
          let idx = Object.keys(consoleTabs).length > 0 ? Math.max(...Object.keys(consoleTabs).map(k => parseInt(k.split('-')[1]))) + 1 : 0;
          consoleTabs[`tab-${idx}`] = '';
          saveConsoleTabs();
          rebuildConsoleTabsUI();
          switchConsoleTab(idx);
          createToast('New tab created', 'success');
        };
        openRawConsoleLogsBtn.onclick = () => {
          const newWin = window.open();
          if (!newWin) return alert('Popup blocked. Allow popups please.');
          const safeContent = consoleOutput.textContent.replace(/</g,'&lt;').replace(/>/g,'&gt;');
          newWin.document.write(`<textarea style="width:100vw;height:100vh;font-family:monospace;" readonly>${safeContent}</textarea>`);
          newWin.document.title = 'Console Logs';
          newWin.document.close();
        };
      }

      function rebuildConsoleTabsUI() {
        codeTabs.innerHTML = '';
        Object.keys(consoleTabs).sort((a,b) => parseInt(a.split('-')[1]) - parseInt(b.split('-')[1]))
          .forEach(k => addConsoleTab(k));
        addNewConsoleTabButton();
        switchConsoleTab(activeConsoleTab);
      }
      function addConsoleTab(tabKey) {
        const index = parseInt(tabKey.split('-')[1]);
        const tab = document.createElement('div');
        tab.className = 'code-tab';
        tab.tabIndex = 0;
        tab.textContent = `Tab ${index + 1}`;
        tab.dataset.tabKey = tabKey;
        if (index === activeConsoleTab) tab.classList.add('active');

        tab.onclick = () => {
          switchConsoleTab(index);
        };
        tab.onkeydown = e => {
          if(e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            switchConsoleTab(index);
          }
        };

        const closeBtn = document.createElement('span');
        closeBtn.textContent = '×';
        closeBtn.className = 'close-tab';
        closeBtn.tabIndex = 0;
        closeBtn.title = 'Close tab';
        closeBtn.onclick = e => {
          e.stopPropagation();
          removeConsoleTab(index);
        };
        closeBtn.onkeydown = e => {
          if(e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            removeConsoleTab(index);
          }
        };

        tab.appendChild(closeBtn);
        codeTabs.appendChild(tab);
      }
      function addNewConsoleTabButton() {
        const btn = document.createElement('div');
        btn.className = 'code-tab';
        btn.textContent = '+';
        btn.title = 'New tab';
        btn.tabIndex = 0;
        btn.onclick = () => {
          let idx = Object.keys(consoleTabs).length > 0 ? Math.max(...Object.keys(consoleTabs).map(k => parseInt(k.split('-')[1]))) + 1 : 0;
          consoleTabs[`tab-${idx}`] = '';
          saveConsoleTabs();
          rebuildConsoleTabsUI();
          switchConsoleTab(idx);
          createToast('New tab created', 'success');
        };
        btn.onkeydown = e => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            btn.onclick();
          }
        };
        codeTabs.appendChild(btn);
      }
      function switchConsoleTab(index) {
        if (!consoleTabs.hasOwnProperty(`tab-${index}`)) return;
        activeConsoleTab = index;
        Array.from(document.querySelectorAll('.code-tab')).forEach(t => {
          t.classList.remove('active');
          if (t.dataset.tabKey === `tab-${index}`) t.classList.add('active');
        });
        if (codeMirrorInstance) {
          codeMirrorInstance.setValue(consoleTabs[`tab-${index}`]);
          codeMirrorInstance.focus();
        }
        createToast(`Switched to Tab ${index + 1}`, 'info');
      }
      function removeConsoleTab(index) {
        if (!consoleTabs.hasOwnProperty(`tab-${index}`)) return;
        if (!confirm(`Close tab ${index + 1}?`)) return;
        delete consoleTabs[`tab-${index}`];
        saveConsoleTabs();
        rebuildConsoleTabsUI();
        const keys = Object.keys(consoleTabs);
        if (keys.length > 0) {
          switchConsoleTab(Math.min(...keys.map(k => parseInt(k.split('-')[1]))));
        }
        else {
          consoleTabs = { 'tab-0': '' };
          saveConsoleTabs();
          rebuildConsoleTabsUI();
          switchConsoleTab(0);
        }
        createToast(`Closed tab ${index + 1}`, 'warning');
      }

      // --- Console code execution ---
      function runConsoleCode() {
        const code = codeMirrorInstance.getValue();
        // Treat as HTML
        if (/<\s*!doctype\s+html>/i.test(code) || /<html/i.test(code)) {
          const newWin = window.open();
          newWin.document.write(code);
          newWin.document.close();
          createToast("HTML content opened new tab", "success");
          return;
        }
        try {
          const api = window.api;
          const fn = new Function("api", `"use strict"; return (async function(api) {${code}})(api);`);
          const result = fn(api);
          if (result?.then) {
            result.then(res => {
              if (res !== undefined) logConsoleOutput(res);
            })
              .catch(err => {
                logConsoleOutput('Error ' + err.message);
                createToast('Error: ' + err.message, 'error');
              });
          }
          else if (result !== undefined) logConsoleOutput(result);
        } catch (e) {
          logConsoleOutput('Error: ' + e.message);
          createToast('Error: ' + e.message, 'error');
        }
      }

      function logConsoleOutput(msg) {
        const now = new Date().toLocaleTimeString();
        let out = typeof msg === 'string' ? msg : JSON.stringify(msg, null, 2);
        consoleOutput.textContent += `[${now}] ${out}\n`;
        consoleOutputWrapper.scrollTop = consoleOutputWrapper.scrollHeight;
      }

      // --- Initialization ---

      function applyGameFontSize(size) {
        const finalSize = size || settings.gameFontSize || 18;
        document.querySelectorAll('a.game-link').forEach(el => { el.style.fontSize = finalSize + 'px'; });
      }

      // Load localStorage data
      function loadPersistentData() {
        settings = Object.assign(settings, safeLocalGet(LS_KEYS.SETTINGS, {}));
        devGames = safeLocalGet(LS_KEYS.DEVGAMES, []);
        devPages = safeLocalGet(LS_KEYS.DEVPAGES, devPages); // default pages above
        consoleTabs = safeLocalGet(LS_KEYS.CONSOLETABS, { 'tab-0': '' });
        likedVideosMap = new Map( safeLocalGet(LS_KEYS.LIKEDVIDEOS, []) );
      }

      // Save localStorage data
      function saveAllData() {
        safeLocalSet(LS_KEYS.SETTINGS, settings);
        safeLocalSet(LS_KEYS.DEVGAMES, devGames);
        safeLocalSet(LS_KEYS.DEVPAGES, devPages);
        safeLocalSet(LS_KEYS.CONSOLETABS, consoleTabs);
        safeLocalSet(LS_KEYS.LIKEDVIDEOS, Array.from(likedVideosMap.entries()));
      }

      // Set up event handlers for UI
      function setEventListeners() {
        // Settings checkbox event handlers handle above in onChange

        nextPageButton.onclick = () => {
          showPage('gamePage2');
          gsearchbar2.value = '';
          gsearchbar2.dispatchEvent(new Event('input'));
        };

        prevPageButton.onclick = () => {
          showPage('gamePage1');
          gsearchbar1.value = '';
          gsearchbar1.dispatchEvent(new Event('input'));
        };

        // Game link confirmation handled above

        loadVideoButton.onclick = () => {
          // handled above
        };

        youtubeChangeButton.onclick = () => {
          // handled above
        };
      }

      // Initialize everything
      async function initializeApp() {
        loadPersistentData();
        syncSettingsUI();
        applyAppSettings();

        setupBackgroundAnimation(settings.theme);

        enableDrag(settings.enableDrag);
        addFavoriteClickHandler(settings.toggleFavorites);
        applyGameFontSize(settings.gameFontSize);

        setupConsole();

        showPage('gamePage1');

        setEventListeners();
      }

      initializeApp();

      // Expose API object for Console and other uses
      window.api = {
        toast: createToast,
        wait: async seconds => new Promise(res => setTimeout(res, seconds * 1000)),
        log: logConsoleOutput,
        listTabs: () => Object.keys(consoleTabs),
        openTab: idx => switchConsoleTab(idx),
        createTab: () => addConsoleTabHandler(),
        saveCurrentCode: code => {
          consoleTabs[`tab-${activeConsoleTab}`] = code;
          saveConsoleTabs();
          codeMirrorInstance.setValue(code);
          createToast('Saved console code via API');
        },
        getSettings: () => ({ ...settings }),
        updateSettings: obj => {
          Object.entries(obj).forEach(([k, v]) => {
            if (settings.hasOwnProperty(k)) settings[k] = v;
          });
          syncSettingsUI();
          applyAppSettings();
          createToast('Updated settings via API');
        },
        listGames: () => Array.from(document.querySelectorAll('a.game-link')).map(el => ({
          title: el.textContent,
          url: el.dataset.link,
          favorite: el.classList.contains('favorite')
        })),
        addFavorite: url => {
          const el = document.querySelector(`a[data-link="${url}"]`);
          if (!el) return createToast('Game not found', 'error');
          if (!el.classList.contains('favorite')) {
            el.classList.add('favorite');
            reorderFavorites();
            saveGameOrder();
            createToast('Favorited game via API', 'success');
          }
        },
        removeFavorite: url => {
          const el = document.querySelector(`a[data-link="${url}"]`);
          if (!el) return createToast('Game not found', 'error');
          if (el.classList.contains('favorite')) {
            el.classList.remove('favorite');
            reorderFavorites();
            saveGameOrder();
            createToast('Unfavorited game via API', 'info');
          }
        },
        // Developer Mode API
        addDevGame: (label, clickCode, pageId = activeDevPage) => {
          if (!settings.developerMode) return createToast('Developer Mode not enabled', 'error');
          addDevGame(label, clickCode, pageId);
        },
        removeDevGame: id => {
          if (!settings.developerMode) return createToast('Developer Mode not enabled', 'error');
          devGames = devGames.filter(g => g.id !== id);
          safeLocalSet(LS_KEYS.DEVGAMES, devGames);
          refreshDevGamesUI();
          createToast('Dev game removed via API', 'warning');
        },
        listDevGames: () => {
          if (!settings.developerMode) return createToast('Developer Mode not enabled', 'error');
          return devGames;
        },
        showPage: pageId => {
          activeDevPage = pageId;
          showPage(pageId);
          if (settings.developerMode) refreshDevGamesUI();
        }
      };
    })();
  </script>
</body>

</html>