Diep.io Build Browser & Share by Kronati

Browse & share public builds for diep.io tanks, with highscores, slash stats and a menu button next to "Shop".

2025-11-20 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Diep.io Build Browser & Share by Kronati
// @namespace    https://diep.kronea.app
// @version      0.1.0
// @description  Browse & share public builds for diep.io tanks, with highscores, slash stats and a menu button next to "Shop".
// @author       Kronati
// @match        *://diep.io/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
  
    const API_BASE = 'https://diep.kronea.app';
  
    const API_ROUTES = {
      tanks: '/api/tanks',
      buildsByTank: '/api/builds?tankId=',
      buildsAll: '/api/builds/all',
      createBuild: '/api/builds',
      voteBuild: (buildId) => `/api/builds/${buildId}/vote`,
      submitHighscore: (buildId) => `/api/builds/${buildId}/highscore`
    };
  
    const TANK_IMAGE_BASE = 'https://diep.kronea.app/img/tanks/';
  
    const TANK_IMAGE_FALLBACK_COLOR = '#60a5fa';

    let uiRoot = null;
    let tanksCache = null;
    let currentTankId = null;
    let currentTankName = null;
    let currentView = 'general';
    let currentSortBy = 'rating';
    let currentSortOrder = 'desc';
    let currentSearch = '';
    let settingsOpen = false;

    const DEFAULT_SETTINGS = {
    };
    
    function loadSettings() {
      try {
        const saved = localStorage.getItem('kbui_settings');
        if (saved) {
          return { ...DEFAULT_SETTINGS, ...JSON.parse(saved) };
        }
      } catch (e) {
        console.error('[KBUI] Failed to load settings:', e);
      }
      return { ...DEFAULT_SETTINGS };
    }
    
    function saveSettings(settings) {
      try {
        localStorage.setItem('kbui_settings', JSON.stringify(settings));
      } catch (e) {
        console.error('[KBUI] Failed to save settings:', e);
      }
    }
    
    let currentSettings = loadSettings();
    let currentTankSearch = '';
  
    function injectStyles() {
      if (document.getElementById('kronati-build-ui-style')) return;
      const style = document.createElement('style');
      style.id = 'kronati-build-ui-style';
      style.textContent = `
        .kbui-root {
          position: fixed;
          inset: 0;
          z-index: 99998;
          display: none;
          align-items: center;
          justify-content: center;
          font-family: "Nunito", "Segoe UI", sans-serif;
        }
        .kbui-root.visible {
          display: flex;
        }
        .kbui-backdrop {
          position: absolute;
          inset: 0;
          background: radial-gradient(circle at top, rgba(0,0,0,0.7), rgba(0,0,0,0.9));
        }
        .kbui-panel {
          position: relative;
          width: min(95vw, 1400px);
          height: min(85vh, 800px);
          background: #2b3238;
          border-radius: 12px;
          border: 2px solid #4b5966;
          box-shadow: 0 0 40px rgba(0,0,0,0.8);
          padding: 20px 24px;
          display: flex;
          flex-direction: column;
          color: #dfe9f4;
        }
        .kbui-header {
          display: flex;
          align-items: center;
          justify-content: space-between;
          margin-bottom: 16px;
        }
        .kbui-title {
          font-size: 24px;
          font-weight: 700;
          color: #f1f5f9;
        }
        .kbui-subtitle {
          font-size: 13px;
          opacity: 0.75;
        }
        .kbui-close-btn {
          cursor: pointer;
          border: 1px solid #8b99a6;
          border-radius: 8px;
          padding: 6px 14px;
          background: #1c2126;
          color: #f8fafc;
          font-size: 13px;
          text-transform: uppercase;
          letter-spacing: 0.04em;
        }
        .kbui-close-btn:hover {
          border-color: #facc15;
          color: #facc15;
        }
        .kbui-body {
          flex: 1;
          display: flex;
          gap: 16px;
          overflow: hidden;
        }
        .kbui-sidebar {
          width: 300px;
          border-right: 1px solid #3b454f;
          padding-right: 12px;
          display: flex;
          flex-direction: column;
        }
        .kbui-main {
          flex: 1;
          display: flex;
          flex-direction: column;
          overflow: hidden;
        }
        .kbui-section-title {
          font-size: 14px;
          text-transform: uppercase;
          letter-spacing: 0.08em;
          color: #9ca3af;
          margin-bottom: 10px;
        }
        .kbui-tank-grid {
          display: flex;
          flex-direction: column;
          overflow-y: auto;
          padding-right: 6px;
          gap: 8px;
        }
        .kbui-level-header {
          font-size: 12px;
          font-weight: 700;
          color: #facc15;
          text-transform: uppercase;
          letter-spacing: 0.1em;
          margin-top: 8px;
          margin-bottom: 4px;
          padding: 4px 0;
          border-bottom: 1px solid #374151;
        }
        .kbui-tank-grid-level {
          display: grid;
          grid-template-columns: repeat(3, minmax(0,1fr));
          gap: 8px;
        }
        .kbui-tank-card {
          background: #1f252b;
          border-radius: 10px;
          border: 1px solid #3b444f;
          padding: 10px 6px;
          cursor: pointer;
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 6px;
          transition: background 0.1s, transform 0.08s, border-color 0.1s;
        }
        .kbui-tank-card:hover {
          background: #27313a;
          transform: translateY(-1px);
          border-color: #facc15;
        }
        .kbui-tank-card.selected {
          border-color: #22c55e;
          box-shadow: 0 0 0 1px rgba(34,197,94,0.5);
        }
        .kbui-tank-icon {
          width: 40px;
          height: 40px;
          border-radius: 8px;
          background-size: contain;
          background-position: center;
          background-repeat: no-repeat;
          background-color: #111827;
          border: 1px solid #4b5563;
        }
        .kbui-tank-name {
          font-size: 13px;
          text-align: center;
        }
        .kbui-list-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 10px;
          flex-wrap: wrap;
          gap: 8px;
        }
        .kbui-tabs {
          display: flex;
          gap: 6px;
          margin-bottom: 10px;
        }
        .kbui-tab {
          padding: 6px 14px;
          border-radius: 8px;
          border: 1px solid #4b5563;
          background: #1f252b;
          color: #9ca3af;
          cursor: pointer;
          font-size: 13px;
          font-weight: 600;
          transition: all 0.1s;
        }
        .kbui-tab:hover {
          border-color: #facc15;
          color: #facc15;
        }
        .kbui-tab.active {
          background: #facc15;
          color: #111827;
          border-color: #facc15;
        }
        .kbui-search-sort {
          display: flex;
          gap: 6px;
          align-items: center;
          flex-wrap: wrap;
        }
        .kbui-search-input {
          border-radius: 8px;
          border: 1px solid #4b5563;
          background: #020617;
          color: #e5e7eb;
          padding: 8px 12px;
          font-size: 13px;
          min-width: 200px;
        }
        .kbui-search-input:focus {
          outline: none;
          border-color: #facc15;
          box-shadow: 0 0 0 1px rgba(250,204,21,0.4);
        }
        .kbui-sort-select {
          border-radius: 8px;
          border: 1px solid #4b5563;
          background: #020617;
          color: #e5e7eb;
          padding: 8px 12px;
          font-size: 13px;
          cursor: pointer;
        }
        .kbui-sort-select:focus {
          outline: none;
          border-color: #facc15;
          box-shadow: 0 0 0 1px rgba(250,204,21,0.4);
        }
        .kbui-build-list {
          flex: 1;
          overflow-y: auto;
          border-radius: 10px;
          border: 1px solid #38414a;
          background: radial-gradient(circle at top, #232a30, #181c20);
          padding: 10px;
        }
        .kbui-build-card {
          border-radius: 10px;
          border: 1px solid #374151;
          padding: 12px 14px;
          margin-bottom: 8px;
          background: rgba(15,23,42,0.7);
          display: flex;
          flex-direction: column;
          gap: 8px;
        }
        .kbui-build-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
        }
        .kbui-build-name {
          font-size: 16px;
          font-weight: 600;
        }
        .kbui-rating {
          display: inline-flex;
          align-items: center;
          gap: 6px;
          font-size: 13px;
        }
        .kbui-rating button {
          border-radius: 999px;
          border: 1px solid #4b5563;
          background: #111827;
          color: #e5e7eb;
          padding: 4px 10px;
          font-size: 12px;
          cursor: pointer;
          min-width: 32px;
        }
        .kbui-rating button:hover {
          border-color: #facc15;
          color: #facc15;
        }
        .kbui-stat-grid {
          display: grid;
          grid-template-columns: repeat(4, minmax(0,1fr));
          gap: 6px 12px;
          font-size: 12px;
        }
        .kbui-stat-label {
          opacity: 0.75;
        }
        .kbui-stat-value {
          font-weight: 600;
          color: #e5e7eb;
          font-size: 13px;
        }
        .kbui-slash-stats {
          margin: 8px 0;
          padding: 10px 12px;
          background: rgba(15,23,42,0.5);
          border-radius: 8px;
          border: 1px solid #374151;
          font-family: 'Courier New', monospace;
          font-size: 16px;
          font-weight: 600;
          color: #facc15;
          text-align: center;
          letter-spacing: 0.05em;
        }
        .kbui-build-footer {
          display: flex;
          justify-content: space-between;
          align-items: center;
          font-size: 12px;
          opacity: 0.75;
        }
        .kbui-pill {
          border-radius: 999px;
          border: 1px solid #4b5563;
          padding: 4px 10px;
        }
        .kbui-button-main {
          border-radius: 999px;
          border: 1px solid #fbbf24;
          background: linear-gradient(135deg, #facc15, #f97316);
          color: #111827;
          font-size: 13px;
          padding: 8px 16px;
          cursor: pointer;
          font-weight: 600;
          box-shadow: 0 0 12px rgba(250,204,21,0.4);
        }
        .kbui-button-main:hover {
          filter: brightness(1.05);
        }
        .kbui-form {
          margin-top: 10px;
          border-radius: 10px;
          border: 1px solid #374151;
          padding: 12px 14px;
          background: rgba(15,23,42,0.8);
          display: flex;
          flex-direction: column;
          gap: 8px;
          font-size: 13px;
        }
        .kbui-form-row {
          display: flex;
          gap: 8px;
        }
        .kbui-form-group {
          flex: 1;
          display: flex;
          flex-direction: column;
          gap: 4px;
        }
        .kbui-form-group label {
          opacity: 0.75;
          font-size: 12px;
        }
        .kbui-form-group input,
        .kbui-form-group select {
          border-radius: 8px;
          border: 1px solid #4b5563;
          background: #020617;
          color: #e5e7eb;
          padding: 8px 10px;
          font-size: 13px;
        }
        .kbui-form-group input:focus,
        .kbui-form-group select:focus {
          outline: none;
          border-color: #facc15;
          box-shadow: 0 0 0 1px rgba(250,204,21,0.4);
        }
        .kbui-form-footer {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-top: 8px;
        }
        .kbui-small {
          font-size: 12px;
          opacity: 0.7;
        }
        .kbui-toast {
          position: fixed;
          bottom: 20px;
          right: 20px;
          background: rgba(15,23,42,0.95);
          color: #e5e7eb;
          padding: 10px 16px;
          border-radius: 999px;
          border: 1px solid #4b5563;
          font-size: 13px;
          z-index: 99999;
          opacity: 0;
          transform: translateY(8px);
          transition: opacity 0.15s ease, transform 0.15s ease;
        }
        .kbui-toast.visible {
          opacity: 1;
          transform: translateY(0);
        }
  #kbui-builds-menu-button.kbui-builds-btn {
    --color: var(--ui-color-3);
    margin-left: 6px;
    position: relative;
    overflow: hidden;
    font-family: "Nunito", "Verdana", sans-serif !important;
    background: #2b3238 !important;
    border: 1px solid #374151 !important;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  #kbui-builds-menu-button.kbui-builds-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(255,255,255,0.1), rgba(0,0,0,0.1));
    opacity: 0.6;
    pointer-events: none;
    z-index: 1;
  }
  
  #kbui-builds-menu-button .kbui-builds-icon {
    width: 1.5em;
    height: 1.5em;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 20%, #a5b4fc, #6366f1);
    border: 2px solid rgba(15,23,42,0.9);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: "Nunito", "Verdana", sans-serif !important;
    font-weight: 800;
    font-size: 0.9em;
    color: #ffffff;
    text-shadow: 0 0 3px rgba(0,0,0,0.45);
  }
  
  #kbui-builds-menu-button .kbui-builds-inner {
    position: relative;
    z-index: 2;
  }
  
  #kbui-builds-menu-button .kbui-no-icon {
    padding: 0 16px;
  }
  
  #kbui-builds-menu-button .kbui-builds-label {
    font-family: "Nunito", "Verdana", sans-serif !important;
    font-size: 16px;
    font-weight: 700;
    color: #f1f5f9 !important;
    text-shadow: 0 1px 2px rgba(0,0,0,0.5);
    position: relative;
    z-index: 2;
  }
  
  #kbui-builds-menu-button:hover {
    background: #374151 !important;
    filter: brightness(1.1);
  }
  
  #kbui-builds-menu-button:active {
    background: #1f2937 !important;
  }
  
  
      `;
      document.head.appendChild(style);
    }
  
    let toastEl = null;
    let toastTimeout = null;
  
    function showToast(message) {
      if (!toastEl) {
        toastEl = document.createElement('div');
        toastEl.className = 'kbui-toast';
        document.body.appendChild(toastEl);
      }
      toastEl.textContent = message;
      toastEl.classList.add('visible');
      if (toastTimeout) clearTimeout(toastTimeout);
      toastTimeout = setTimeout(() => {
        toastEl.classList.remove('visible');
      }, 2200);
    }
  
    async function apiGet(path) {
      const res = await fetch(API_BASE + path, { credentials: 'omit' });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      return res.json();
    }
  
    async function apiPost(path, body) {
      const res = await fetch(API_BASE + path, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'omit',
        body: JSON.stringify(body)
      });
      if (!res.ok) {
        let errorMessage = `HTTP ${res.status}`;
        try {
          const errorData = await res.json();
          if (errorData.error) {
            errorMessage = errorData.error;
          }
          if (errorData.message) {
            errorMessage = errorData.message;
          }
          const error = new Error(errorMessage);
          error.status = res.status;
          error.data = errorData;
          throw error;
        } catch (parseError) {
          const error = new Error(errorMessage);
          error.status = res.status;
          throw error;
        }
      }
      return res.json();
    }

    async function apiPostFormData(path, formData) {
      const res = await fetch(API_BASE + path, {
        method: 'POST',
        credentials: 'omit',
        body: formData
      });
      if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`HTTP ${res.status}: ${errorText}`);
      }
      return res.json();
    }
  
    async function copyToClipboard(text) {
      try {
        await navigator.clipboard.writeText(text);
        return true;
      } catch (err) {
        try {
          const textArea = document.createElement('textarea');
          textArea.value = text;
          textArea.style.position = 'fixed';
          textArea.style.left = '-999999px';
          textArea.style.top = '-999999px';
          document.body.appendChild(textArea);
          textArea.focus();
          textArea.select();
          const successful = document.execCommand('copy');
          document.body.removeChild(textArea);
          return successful;
        } catch (e) {
          return false;
        }
      }
    }

    function createUIRoot() {
      if (uiRoot) return uiRoot;
      uiRoot = document.createElement('div');
      uiRoot.className = 'kbui-root';
  
      const backdrop = document.createElement('div');
      backdrop.className = 'kbui-backdrop';
      backdrop.addEventListener('click', () => toggleUI(false));
  
      const panel = document.createElement('div');
      panel.className = 'kbui-panel';
  
      const header = document.createElement('div');
      header.className = 'kbui-header';
  
      const leftHeader = document.createElement('div');
      const title = document.createElement('div');
      title.className = 'kbui-title';
      title.textContent = 'Diep.io Build Browser';
  
      const subtitle = document.createElement('div');
      subtitle.className = 'kbui-subtitle';
      subtitle.textContent = 'Browse & share public builds – by Kronati';
  
      leftHeader.appendChild(title);
      leftHeader.appendChild(subtitle);

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

      const settingsBtn = document.createElement('button');
      settingsBtn.className = 'kbui-button-main';
      settingsBtn.innerHTML = '⚙️';
      settingsBtn.style.padding = '6px 10px';
      settingsBtn.style.fontSize = '16px';
      settingsBtn.style.cursor = 'pointer';
      settingsBtn.title = 'Settings';
      settingsBtn.addEventListener('click', () => openSettings());

      const closeBtn = document.createElement('button');
      closeBtn.className = 'kbui-close-btn';
      closeBtn.textContent = 'Close';
      closeBtn.addEventListener('click', () => toggleUI(false));

      rightHeader.appendChild(settingsBtn);
      rightHeader.appendChild(closeBtn);

      header.appendChild(leftHeader);
      header.appendChild(rightHeader);
  
      const body = document.createElement('div');
      body.className = 'kbui-body';
  
      const sidebar = document.createElement('div');
      sidebar.className = 'kbui-sidebar';

      const sidebarTitle = document.createElement('div');
      sidebarTitle.className = 'kbui-section-title';
      sidebarTitle.textContent = 'Tanks';

      const tankSearchInput = document.createElement('input');
      tankSearchInput.type = 'text';
      tankSearchInput.className = 'kbui-search-input';
      tankSearchInput.placeholder = 'Search tanks...';
      tankSearchInput.id = 'kbui-tank-search-input';
      tankSearchInput.style.marginBottom = '10px';
      let tankSearchTimeout = null;
      tankSearchInput.addEventListener('input', (e) => {
        clearTimeout(tankSearchTimeout);
        tankSearchTimeout = setTimeout(() => {
          currentTankSearch = e.target.value.trim().toLowerCase();
          loadTanks().then(renderTankGrid).catch((e) => console.error(e));
        }, 200);
      });

      const tankGrid = document.createElement('div');
      tankGrid.className = 'kbui-tank-grid';
      tankGrid.id = 'kbui-tank-grid';

      sidebar.appendChild(sidebarTitle);
      sidebar.appendChild(tankSearchInput);
      sidebar.appendChild(tankGrid);
  
      const main = document.createElement('div');
      main.className = 'kbui-main';

      const tabs = document.createElement('div');
      tabs.className = 'kbui-tabs';
      
      const generalTab = document.createElement('button');
      generalTab.className = 'kbui-tab active';
      generalTab.textContent = 'General';
      generalTab.addEventListener('click', () => switchView('general'));
      
      const tankTab = document.createElement('button');
      tankTab.className = 'kbui-tab';
      tankTab.textContent = 'By Tank';
      tankTab.addEventListener('click', () => switchView('tank'));
      
      tabs.appendChild(generalTab);
      tabs.appendChild(tankTab);

      const listHeader = document.createElement('div');
      listHeader.className = 'kbui-list-header';

      const listHeaderLeft = document.createElement('div');
      listHeaderLeft.style.display = 'flex';
      listHeaderLeft.style.flexDirection = 'column';
      listHeaderLeft.style.gap = '6px';
      listHeaderLeft.style.flex = '1';

      const listTitle = document.createElement('div');
      listTitle.className = 'kbui-section-title';
      listTitle.textContent = 'Builds';

      const searchSort = document.createElement('div');
      searchSort.className = 'kbui-search-sort';
      
      const searchInput = document.createElement('input');
      searchInput.type = 'text';
      searchInput.className = 'kbui-search-input';
      searchInput.placeholder = 'Search builds...';
      searchInput.id = 'kbui-search-input';
      let searchTimeout = null;
      searchInput.addEventListener('input', (e) => {
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(() => {
          currentSearch = e.target.value.trim();
          if (currentView === 'general') {
            loadAllBuilds();
          }
        }, 300);
      });

      const sortSelect = document.createElement('select');
      sortSelect.className = 'kbui-sort-select';
      sortSelect.id = 'kbui-sort-select';
      sortSelect.innerHTML = `
        <option value="rating">Rating</option>
        <option value="highscore">Highscore</option>
        <option value="upvotes">Upvotes</option>
        <option value="downvotes">Downvotes</option>
        <option value="name">Name</option>
      `;
      sortSelect.value = currentSortBy;
      sortSelect.addEventListener('change', (e) => {
        currentSortBy = e.target.value;
        if (currentView === 'general') {
          loadAllBuilds();
        }
      });

      const orderSelect = document.createElement('select');
      orderSelect.className = 'kbui-sort-select';
      orderSelect.id = 'kbui-order-select';
      orderSelect.innerHTML = `
        <option value="desc">Descending</option>
        <option value="asc">Ascending</option>
      `;
      orderSelect.value = currentSortOrder;
      orderSelect.addEventListener('change', (e) => {
        currentSortOrder = e.target.value;
        if (currentView === 'general') {
          loadAllBuilds();
        }
      });

      searchSort.appendChild(searchInput);
      searchSort.appendChild(sortSelect);
      searchSort.appendChild(orderSelect);

      listHeaderLeft.appendChild(listTitle);
      listHeaderLeft.appendChild(searchSort);

      const createBtn = document.createElement('button');
      createBtn.className = 'kbui-button-main';
      createBtn.textContent = 'Create Build';
      createBtn.addEventListener('click', () => openCreateBuildForm());

      listHeader.appendChild(listHeaderLeft);
      listHeader.appendChild(createBtn);

      const buildList = document.createElement('div');
      buildList.className = 'kbui-build-list';
      buildList.id = 'kbui-build-list';
      buildList.textContent = 'Loading builds...';

      main.appendChild(tabs);
      main.appendChild(listHeader);
      main.appendChild(buildList);
  
      body.appendChild(sidebar);
      body.appendChild(main);
  
      panel.appendChild(header);
      panel.appendChild(body);
  
      uiRoot.appendChild(backdrop);
      uiRoot.appendChild(panel);
      document.body.appendChild(uiRoot);
      return uiRoot;
    }
  
    function toggleUI(show) {
      const root = createUIRoot();
      if (show) {
        root.classList.add('visible');
        if (currentView === 'general') {
          loadAllBuilds();
        }
      } else {
        root.classList.remove('visible');
      }
    }

    function switchView(view) {
      currentView = view;
      const tabs = document.querySelectorAll('.kbui-tab');
      tabs.forEach(tab => tab.classList.remove('active'));
      
      if (view === 'general') {
        tabs[0].classList.add('active');
        document.getElementById('kbui-search-input').style.display = '';
        document.getElementById('kbui-sort-select').style.display = '';
        document.getElementById('kbui-order-select').style.display = '';
        loadAllBuilds();
      } else {
        tabs[1].classList.add('active');
        document.getElementById('kbui-search-input').style.display = 'none';
        document.getElementById('kbui-sort-select').style.display = 'none';
        document.getElementById('kbui-order-select').style.display = 'none';
        if (currentTankId) {
          loadBuildsForTank(currentTankId, currentTankName);
        } else {
          const list = document.getElementById('kbui-build-list');
          if (list) list.textContent = 'Select a tank on the left to view builds.';
        }
      }
    }
  
  function injectMenuBuildButton() {
    if (document.getElementById('kbui-builds-menu-button')) return;
  
    const container = document.querySelector('.corner-buttons.top.left[data-is-active="true"]');
    if (!container) return;
  
    const btn = document.createElement('button');
    btn.id = 'kbui-builds-menu-button';
    btn.className = 'updated-standard-button active minimal diep-style-button kbui-builds-btn';
    btn.setAttribute('tabindex', '-1');
    btn.setAttribute('data-is-clickable', 'true');
    btn.setAttribute('data-is-flashing', 'false');
    btn.style.setProperty('--color', 'var(--ui-color-3)');
  
    const inner = document.createElement('div');
    inner.className = 'kbui-builds-inner kbui-no-icon';
    const label = document.createElement('div');
    label.className = 'kbui-builds-label';
    label.textContent = 'Builds';
    inner.appendChild(label);
    btn.appendChild(inner);
  
    btn.addEventListener('click', (e) => {
      e.stopPropagation();
      toggleUI(true);
    });
  
    container.appendChild(btn);
  }
    async function loadTanks() {
      if (tanksCache) return tanksCache;
      const tanks = await apiGet(API_ROUTES.tanks);
      tanksCache = tanks;
      return tanks;
    }
  
    function renderTankGrid(tanks) {
      const grid = document.getElementById('kbui-tank-grid');
      if (!grid) return;
      grid.innerHTML = '';
  
      if (!tanks || !tanks.length) {
        const msg = document.createElement('div');
        msg.className = 'kbui-small';
        msg.textContent = 'No tanks from API yet. Configure your backend.';
        grid.appendChild(msg);
        return;
      }
  
      let filteredTanks = tanks;
      if (currentTankSearch) {
        filteredTanks = tanks.filter(tank => {
          const name = (tank.name || '').toLowerCase();
          const shortName = (tank.shortName || '').toLowerCase();
          return name.includes(currentTankSearch) || shortName.includes(currentTankSearch);
        });
      }

      if (!filteredTanks.length) {
        const msg = document.createElement('div');
        msg.className = 'kbui-small';
        msg.textContent = 'No tanks found matching your search.';
        grid.appendChild(msg);
        return;
      }

      const tanksByLevel = {
        1: [],
        15: [],
        30: [],
        45: []
      };

      filteredTanks.forEach(tank => {
        const level = tank.level || tank.sortOrder || 0;
        if (level === 1) tanksByLevel[1].push(tank);
        else if (level === 15) tanksByLevel[15].push(tank);
        else if (level === 30) tanksByLevel[30].push(tank);
        else if (level === 45) tanksByLevel[45].push(tank);
        else tanksByLevel[45].push(tank);
      });

      const levels = [1, 15, 30, 45];
      levels.forEach(level => {
        const levelTanks = tanksByLevel[level];
        if (levelTanks.length === 0) return;

        const levelHeader = document.createElement('div');
        levelHeader.className = 'kbui-level-header';
        levelHeader.textContent = `Level ${level}`;
        grid.appendChild(levelHeader);

        const levelGrid = document.createElement('div');
        levelGrid.className = 'kbui-tank-grid-level';
        levelGrid.style.gridTemplateColumns = 'repeat(3, minmax(0,1fr))';
        levelGrid.style.gap = '8px';
        levelGrid.style.marginBottom = '12px';

        levelTanks.forEach((tank) => {
          const card = document.createElement('div');
          card.className = 'kbui-tank-card';
          card.dataset.tankId = tank.id;
          card.dataset.tankName = tank.name;

          const icon = document.createElement('div');
          icon.className = 'kbui-tank-icon';

          let imgUrl = tank.imageUrl || null;
          if (!imgUrl && TANK_IMAGE_BASE && tank.imageKey) {
            imgUrl = TANK_IMAGE_BASE + tank.imageKey;
          }
          if (imgUrl) {
            icon.style.backgroundImage = `url("${imgUrl}")`;
          } else {
            icon.style.borderRadius = '50%';
            icon.style.border = '3px solid rgba(0,0,0,0.8)';
            icon.style.backgroundImage = '';
            icon.style.backgroundColor = tank.colorHex || TANK_IMAGE_FALLBACK_COLOR;
          }

          const name = document.createElement('div');
          name.className = 'kbui-tank-name';
          name.textContent = tank.shortName || tank.name;

          card.appendChild(icon);
          card.appendChild(name);

          card.addEventListener('click', () => {
            document
              .querySelectorAll('.kbui-tank-card.selected')
              .forEach((el) => el.classList.remove('selected'));
            card.classList.add('selected');
            currentTankId = tank.id;
            currentTankName = tank.name;
            switchView('tank');
            loadBuildsForTank(tank.id, tank.name);
          });

          levelGrid.appendChild(card);
        });

        grid.appendChild(levelGrid);
      });
    }
  
    async function loadAllBuilds() {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;
      list.innerHTML = 'Loading builds...';

      try {
        const params = new URLSearchParams({
          all: 'true',
          sortBy: currentSortBy,
          sortOrder: currentSortOrder
        });
        if (currentSearch) {
          params.append('search', currentSearch);
        }
        const builds = await apiGet(API_ROUTES.buildsAll + '?' + params.toString());
        renderBuildList(builds, null, true);
      } catch (e) {
        list.innerHTML = '';
        const msg = document.createElement('div');
        msg.className = 'kbui-small';
        msg.textContent = 'Failed to load builds. Check console.';
        list.appendChild(msg);
        console.error(e);
      }
    }

    async function loadBuildsForTank(tankId, tankName) {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;
      list.innerHTML = 'Loading builds...';

      try {
        const builds = await apiGet(API_ROUTES.buildsByTank + encodeURIComponent(tankId));
        renderBuildList(builds, tankName, false);
      } catch (e) {
        list.innerHTML = '';
        const msg = document.createElement('div');
        msg.className = 'kbui-small';
        msg.textContent = 'Failed to load builds. Check console.';
        list.appendChild(msg);
        console.error(e);
      }
    }
  
    function renderBuildList(builds, tankName, isGeneral = false) {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;
      list.innerHTML = '';

      if (!isGeneral && tankName) {
        const headerLine = document.createElement('div');
        headerLine.className = 'kbui-small';
        headerLine.textContent = `Tank: ${tankName || 'Unknown'}`;
        list.appendChild(headerLine);
      }

      if (!builds || !builds.length) {
        const msg = document.createElement('div');
        msg.className = 'kbui-small';
        msg.style.marginTop = '6px';
        msg.textContent = isGeneral 
          ? (currentSearch ? 'No builds found matching your search.' : 'No builds yet. Be the first to create one!')
          : 'No builds yet. Be the first to create one!';
        list.appendChild(msg);
        return;
      }

      builds.forEach((build) => {
        const card = document.createElement('div');
        card.className = 'kbui-build-card';

        const header = document.createElement('div');
        header.className = 'kbui-build-header';

        const nameContainer = document.createElement('div');
        nameContainer.style.display = 'flex';
        nameContainer.style.flexDirection = 'column';
        nameContainer.style.gap = '2px';

        const name = document.createElement('div');
        name.className = 'kbui-build-name';
        name.textContent = build.name || 'Unnamed Build';

        if (isGeneral && build.tankName) {
          const tankLabel = document.createElement('div');
          tankLabel.className = 'kbui-small';
          tankLabel.style.opacity = '0.7';
          tankLabel.textContent = `Tank: ${build.tankName}`;
          nameContainer.appendChild(name);
          nameContainer.appendChild(tankLabel);
        } else {
          nameContainer.appendChild(name);
        }

        const ratingBox = document.createElement('div');
        ratingBox.className = 'kbui-rating';
        ratingBox.style.display = 'flex';
        ratingBox.style.flexDirection = 'column';
        ratingBox.style.alignItems = 'flex-end';
        ratingBox.style.gap = '2px';

        const ratingValue = document.createElement('span');
        ratingValue.textContent = `Score: ${build.rating ?? 0}`;

        const voteCounts = document.createElement('div');
        voteCounts.className = 'kbui-small';
        voteCounts.style.opacity = '0.7';
        voteCounts.style.fontSize = '11px';
        voteCounts.textContent = `▲${build.upvotes || 0} ▼${build.downvotes || 0}`;

        const voteButtons = document.createElement('div');
        voteButtons.style.display = 'flex';
        voteButtons.style.gap = '4px';
        const upBtn = document.createElement('button');
        upBtn.textContent = '▲';
        upBtn.setAttribute('data-build-id', build.id);
        const downBtn = document.createElement('button');
        downBtn.textContent = '▼';
        downBtn.setAttribute('data-build-id', build.id);

        upBtn.addEventListener('click', () => voteBuild(build.id, +1, ratingValue, voteCounts, build));
        downBtn.addEventListener('click', () => voteBuild(build.id, -1, ratingValue, voteCounts, build));

        voteButtons.appendChild(upBtn);
        voteButtons.appendChild(downBtn);

        ratingBox.appendChild(ratingValue);
        ratingBox.appendChild(voteCounts);
        ratingBox.appendChild(voteButtons);

        header.appendChild(nameContainer);
        header.appendChild(ratingBox);
  
        const stats = build.stats || {};
        const statGrid = document.createElement('div');
        statGrid.className = 'kbui-stat-grid';
  
        const statColors = {
          healthRegen: '#e8b08a',
          maxHealth: '#e666ea',
          bodyDamage: '#9466ea',
          bulletSpeed: '#638ce4',
          bulletPenetration: '#ead366',
          bulletDamage: '#ea6666',
          reload: '#92ea66',
          movementSpeed: '#66eae6'
        };

        const statDefs = [
          ['Health Regen', 'healthRegen'],
          ['Max Health', 'maxHealth'],
          ['Body Damage', 'bodyDamage'],
          ['Bullet Speed', 'bulletSpeed'],
          ['Bullet Penetration', 'bulletPenetration'],
          ['Bullet Damage', 'bulletDamage'],
          ['Reload', 'reload'],
          ['Movement Speed', 'movementSpeed']
        ];
  
        statDefs.forEach(([label, key]) => {
          const wrap = document.createElement('div');
          const l = document.createElement('div');
          l.className = 'kbui-stat-label';
          l.textContent = label;
          const v = document.createElement('div');
          v.className = 'kbui-stat-value';
          v.textContent = stats[key] ?? '-';
          if (stats[key] !== null && stats[key] !== undefined) {
            v.style.color = statColors[key] || '#e5e7eb';
          }
          wrap.appendChild(l);
          wrap.appendChild(v);
          statGrid.appendChild(wrap);
        });

        const slashStatsContainer = document.createElement('div');
        slashStatsContainer.style.display = 'flex';
        slashStatsContainer.style.alignItems = 'center';
        slashStatsContainer.style.gap = '10px';
        slashStatsContainer.style.marginTop = '8px';

        const keysInOrder = [
          'healthRegen',
          'maxHealth',
          'bodyDamage',
          'bulletSpeed',
          'bulletPenetration',
          'bulletDamage',
          'reload',
          'movementSpeed'
        ];
        const slashValues = keysInOrder.map(key => stats[key] ?? 0);
        const slashValuesString = slashValues.join('/');

        const slashStats = document.createElement('div');
        slashStats.className = 'kbui-slash-stats';
        slashStats.style.display = 'flex';
        slashStats.style.alignItems = 'center';
        slashStats.style.justifyContent = 'center';
        slashStats.style.gap = '2px';
        slashStats.style.cursor = 'text';
        slashStats.style.userSelect = 'all';
        slashStats.title = 'Click to select and copy';

        slashValues.forEach((value, index) => {
          const span = document.createElement('span');
          span.textContent = value;
          span.style.color = statColors[keysInOrder[index]] || '#facc15';
          span.style.fontWeight = '600';
          slashStats.appendChild(span);
          
          if (index < slashValues.length - 1) {
            const slash = document.createElement('span');
            slash.textContent = '/';
            slash.style.color = '#facc15';
            slashStats.appendChild(slash);
          }
        });

        const copyBtn = document.createElement('button');
        copyBtn.className = 'kbui-button-main';
        copyBtn.textContent = 'Copy';
        copyBtn.style.padding = '4px 10px';
        copyBtn.style.fontSize = '11px';
        copyBtn.style.cursor = 'pointer';
        copyBtn.addEventListener('click', async () => {
          const success = await copyToClipboard(slashValuesString);
          if (success) {
            showToast('Copied to clipboard!');
            copyBtn.textContent = 'Copied!';
            setTimeout(() => {
              copyBtn.textContent = 'Copy';
            }, 2000);
          } else {
            showToast('Failed to copy');
          }
        });

        slashStatsContainer.appendChild(slashStats);
        slashStatsContainer.appendChild(copyBtn);

        const footer = document.createElement('div');
        footer.className = 'kbui-build-footer';
  
        function formatScore(score) {
          if (!score || score === null) return '-';
          if (score >= 1000000) {
            return (score / 1000000).toFixed(1).replace(/\.0$/, '') + 'm';
          } else if (score >= 1000) {
            return (score / 1000).toFixed(0) + 'K';
          }
          return score.toString();
        }

        const best = document.createElement('div');
        best.className = 'kbui-pill';
        const scoreText = build.bestScoreFormatted || formatScore(build.bestScore);
        const usernameText = build.bestUsername ? ` by ${build.bestUsername}` : '';
        best.textContent = `Best: ${scoreText}${usernameText}${build.bestLevel ? ` (LVL ${build.bestLevel})` : ''}${build.bestTime ? `, ${build.bestTime}` : ''}`;
  
        const highscoreBtn = document.createElement('button');
        highscoreBtn.className = 'kbui-button-main';
        highscoreBtn.textContent = 'Submit Highscore';
        highscoreBtn.style.padding = '2px 8px';
        highscoreBtn.style.fontSize = '12px';
        highscoreBtn.addEventListener('click', () => openHighscoreForm(build));
  
        footer.appendChild(best);
        footer.appendChild(highscoreBtn);
  
        card.appendChild(header);
        card.appendChild(statGrid);
        card.appendChild(slashStatsContainer);
        card.appendChild(footer);
  
        list.appendChild(card);
      });
    }
  
    async function voteBuild(buildId, value, ratingLabelEl, voteCountsEl, build) {
      const buttons = document.querySelectorAll(`[data-build-id="${buildId}"] button`);
      buttons.forEach(btn => btn.disabled = true);

      try {
        const res = await apiPost(API_ROUTES.voteBuild(buildId), { value });
        if (ratingLabelEl && res && typeof res.newRating === 'number') {
          ratingLabelEl.textContent = `Score: ${res.newRating}`;
        }
        if (voteCountsEl && build) {
          if (res && res.alreadyVoted) {
          }
        }
        if (res && res.alreadyVoted) {
          showToast('Vote changed');
        } else {
          showToast('Vote submitted');
        }
        if (currentView === 'general') {
          loadAllBuilds();
        } else if (currentTankId) {
          loadBuildsForTank(currentTankId, currentTankName);
        }
      } catch (e) {
        const errorMsg = e.message || 'Vote failed';
        if (errorMsg.includes('already voted')) {
          showToast('You already voted on this build');
        } else {
          showToast('Vote failed: ' + errorMsg);
        }
        console.error(e);
      } finally {
        buttons.forEach(btn => btn.disabled = false);
      }
    }
  
    function openCreateBuildForm() {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;
  
      list.innerHTML = '';
  
      const form = document.createElement('div');
      form.className = 'kbui-form';
  
      const title = document.createElement('div');
      title.className = 'kbui-section-title';
      title.textContent = 'Create Build';
  
      const info = document.createElement('div');
      info.className = 'kbui-small';
      info.textContent = 'Choose how to enter stats: separate fields or "0/0/0/0/0/0/0/0".';
  
      const nameRow = document.createElement('div');
      nameRow.className = 'kbui-form-row';
  
      const tankGroup = document.createElement('div');
      tankGroup.className = 'kbui-form-group';
      const tankLabel = document.createElement('label');
      tankLabel.textContent = 'Tank *';
      const tankSelect = document.createElement('select');
      tankSelect.id = 'kbui-tank-select';
      tankSelect.required = true;
      
      loadTanks().then(tanks => {
        if (!tanks || !tanks.length) {
          const option = document.createElement('option');
          option.value = '';
          option.textContent = 'No tanks available';
          tankSelect.appendChild(option);
          return;
        }

        const sortedTanks = [...tanks].sort((a, b) => {
          const levelA = a.level || a.sortOrder || 999;
          const levelB = b.level || b.sortOrder || 999;
          if (levelA !== levelB) return levelA - levelB;
          return (a.name || '').localeCompare(b.name || '');
        });

        const defaultOption = document.createElement('option');
        defaultOption.value = '';
        defaultOption.textContent = '-- Select Tank --';
        if (!currentTankId) {
          defaultOption.selected = true;
        }
        tankSelect.appendChild(defaultOption);

        const levels = [1, 15, 30, 45];
        const processedTankIds = new Set();
        
        levels.forEach(level => {
          const levelTanks = sortedTanks.filter(t => {
            const tankLevel = t.level || t.sortOrder || 0;
            return tankLevel === level;
          });
          if (levelTanks.length === 0) return;

          const optgroup = document.createElement('optgroup');
          optgroup.label = `Level ${level}`;
          
          levelTanks.forEach(tank => {
            processedTankIds.add(tank.id);
            const option = document.createElement('option');
            option.value = tank.id;
            option.textContent = tank.name;
            if (currentTankId && tank.id === currentTankId) {
              option.selected = true;
            }
            optgroup.appendChild(option);
          });
          
          tankSelect.appendChild(optgroup);
        });

        const otherTanks = sortedTanks.filter(t => !processedTankIds.has(t.id));
        if (otherTanks.length > 0) {
          const optgroup = document.createElement('optgroup');
          optgroup.label = 'Other';
          
          otherTanks.forEach(tank => {
            const option = document.createElement('option');
            option.value = tank.id;
            option.textContent = tank.name;
            if (currentTankId && tank.id === currentTankId) {
              option.selected = true;
            }
            optgroup.appendChild(option);
          });
          
          tankSelect.appendChild(optgroup);
        }
      }).catch(err => {
        console.error('Failed to load tanks:', err);
        const option = document.createElement('option');
        option.value = '';
        option.textContent = 'Error loading tanks';
        tankSelect.appendChild(option);
      });

      tankGroup.appendChild(tankLabel);
      tankGroup.appendChild(tankSelect);
  
      const nameGroup = document.createElement('div');
      nameGroup.className = 'kbui-form-group';
      const nameLabel = document.createElement('label');
      nameLabel.textContent = 'Build Name';
      const nameInput = document.createElement('input');
      nameInput.type = 'text';
      nameInput.placeholder = 'My sniper build';
      nameGroup.appendChild(nameLabel);
      nameGroup.appendChild(nameInput);
  
      nameRow.appendChild(tankGroup);
      nameRow.appendChild(nameGroup);
  
      let inputMode = 'fields';
  
      const modeRow = document.createElement('div');
      modeRow.className = 'kbui-form-row';
      const modeGroup = document.createElement('div');
      modeGroup.className = 'kbui-form-group';
      const modeLabel = document.createElement('label');
      modeLabel.textContent = 'Stats input mode';
  
      const modeOptions = document.createElement('div');
      modeOptions.style.display = 'flex';
      modeOptions.style.gap = '8px';
      modeOptions.style.alignItems = 'center';
  
      const fieldsRadio = document.createElement('input');
      fieldsRadio.type = 'radio';
      fieldsRadio.name = 'kbui-stat-mode';
      fieldsRadio.checked = true;
      const fieldsLabel = document.createElement('span');
      fieldsLabel.textContent = 'Fields';
  
      const slashRadio = document.createElement('input');
      slashRadio.type = 'radio';
      slashRadio.name = 'kbui-stat-mode';
      const slashLabel = document.createElement('span');
      slashLabel.textContent = 'Slash "0/0/0/0/0/0/0/0"';
  
      modeOptions.appendChild(fieldsRadio);
      modeOptions.appendChild(fieldsLabel);
      modeOptions.appendChild(slashRadio);
      modeOptions.appendChild(slashLabel);
  
      modeGroup.appendChild(modeLabel);
      modeGroup.appendChild(modeOptions);
      modeRow.appendChild(modeGroup);
  
      const statsFieldRows = [];
  
      function makeStatRow(labels) {
        const row = document.createElement('div');
        row.className = 'kbui-form-row';
        labels.forEach(([label, key]) => {
          const g = document.createElement('div');
          g.className = 'kbui-form-group';
          const l = document.createElement('label');
          l.textContent = label;
          const inp = document.createElement('input');
          inp.type = 'number';
          inp.min = '0';
          inp.max = '7';
          inp.step = '1';
          inp.dataset.statKey = key;
          g.appendChild(l);
          g.appendChild(inp);
          row.appendChild(g);
        });
        return row;
      }
  
      statsFieldRows.push(
        makeStatRow([
          ['Health Regen', 'healthRegen'],
          ['Max Health', 'maxHealth']
        ]),
        makeStatRow([
          ['Body Damage', 'bodyDamage'],
          ['Bullet Speed', 'bulletSpeed']
        ]),
        makeStatRow([
          ['Bullet Penetration', 'bulletPenetration'],
          ['Bullet Damage', 'bulletDamage']
        ]),
        makeStatRow([
          ['Reload', 'reload'],
          ['Movement Speed', 'movementSpeed']
        ])
      );
  
      const statsFieldsWrapper = document.createElement('div');
      statsFieldRows.forEach(r => statsFieldsWrapper.appendChild(r));
  
      const statsSlashWrapper = document.createElement('div');
      statsSlashWrapper.style.display = 'none';
      statsSlashWrapper.className = 'kbui-form-group';
      const slashInfo = document.createElement('label');
      slashInfo.textContent = 'Stats (HR/HP/BD/BS/BP/BDmg/RL/MS) - Use /, space, comma, ; or |';
      const slashInput = document.createElement('input');
      slashInput.type = 'text';
      slashInput.placeholder = '0/0/0/0/0/0/0/0 or 0 0 0 0 0 0 0 0';
      statsSlashWrapper.appendChild(slashInfo);
      statsSlashWrapper.appendChild(slashInput);
  
      fieldsRadio.addEventListener('change', () => {
        if (fieldsRadio.checked) {
          inputMode = 'fields';
          statsFieldsWrapper.style.display = '';
          statsSlashWrapper.style.display = 'none';
        }
      });
      slashRadio.addEventListener('change', () => {
        if (slashRadio.checked) {
          inputMode = 'string';
          statsFieldsWrapper.style.display = 'none';
          statsSlashWrapper.style.display = '';
        }
      });
  
      const footer = document.createElement('div');
      footer.className = 'kbui-form-footer';
  
      const hint = document.createElement('div');
      hint.className = 'kbui-small';
      hint.textContent = 'Stats 0–7. You can set highscores later via "Submit Highscore".';
  
      const saveBtn = document.createElement('button');
      saveBtn.className = 'kbui-button-main';
      saveBtn.textContent = 'Save Build';
  
      saveBtn.addEventListener('click', async () => {
        const name = nameInput.value.trim() || 'Unnamed Build';
        const selectedTankId = tankSelect.value ? parseInt(tankSelect.value, 10) : null;
        
        if (!selectedTankId || !Number.isFinite(selectedTankId)) {
          showToast('Please select a tank');
          return;
        }

        const stats = {};
  
        const keysInOrder = [
          'healthRegen',
          'maxHealth',
          'bodyDamage',
          'bulletSpeed',
          'bulletPenetration',
          'bulletDamage',
          'reload',
          'movementSpeed'
        ];
  
        if (inputMode === 'fields') {
          form.querySelectorAll('input[data-stat-key]').forEach((inp) => {
            const key = inp.dataset.statKey;
            const v = inp.value.trim();
            stats[key] = v === '' ? null : Number(v);
          });
        } else {
          const raw = slashInput.value.trim();
          if (!raw) {
            showToast('Please enter stats like "0/0/0/0/0/0/0/0" or "0 0 0 0 0 0 0 0" or "0,0,0,0,0,0,0,0"');
            return;
          }
          
          let parts = raw.split('/');
          if (parts.length !== 8) {
            parts = raw.split(/\s+/);
          }
          if (parts.length !== 8) {
            parts = raw.split(',');
          }
          if (parts.length !== 8) {
            parts = raw.split(';');
          }
          if (parts.length !== 8) {
            parts = raw.split('|');
          }
          
          if (parts.length !== 8) {
            showToast('Exactly 8 values required. Use /, space, comma, semicolon, or | as separator');
            return;
          }
          
          for (let i = 0; i < 8; i++) {
            const num = Number(parts[i].trim());
            if (!Number.isFinite(num) || num < 0 || num > 7) {
              showToast('Stats must be numbers 0–7');
              return;
            }
            stats[keysInOrder[i]] = num;
          }
        }

        const totalStats = Object.values(stats).reduce((sum, val) => sum + (val || 0), 0);
        if (totalStats > 33) {
          showToast(`Total stats (${totalStats}) exceeds maximum of 33. Max: 4×7 + 1×5 = 33`);
          return;
        }

        const payload = {
          tankId: selectedTankId,
          name,
          stats
        };
  
        try {
          await apiPost(API_ROUTES.createBuild, payload);
          showToast('Build saved');
          if (currentView === 'tank' && currentTankId) {
            loadBuildsForTank(currentTankId, currentTankName);
          } else if (currentView === 'general') {
            loadAllBuilds();
          }
        } catch (e) {
          let errorMessage = 'Saving failed';
          try {
            if (e.data) {
              const errorData = e.data;
              if (errorData.error === 'DUPLICATE_BUILD' || errorData.message) {
                const details = errorData.details || {};
                const statsStr = details.stats || `${stats.healthRegen || 0}/${stats.maxHealth || 0}/${stats.bodyDamage || 0}/${stats.bulletSpeed || 0}/${stats.bulletPenetration || 0}/${stats.bulletDamage || 0}/${stats.reload || 0}/${stats.movementSpeed || 0}`;
                errorMessage = `${errorData.message || 'A build with identical stats already exists for this tank.'}\n\nTank: ${details.tankName || 'Unknown'}\nExisting Build: "${details.buildName || 'Unknown'}"\nStats: ${statsStr}`;
              } else {
                errorMessage = errorData.error || errorData.message || e.message || 'Unknown error';
              }
            } else {
              const errorText = e.message || '';
              if (errorText.includes('identical stats already exists') || errorText.includes('DUPLICATE_BUILD')) {
                const statsString = `${stats.healthRegen || 0}/${stats.maxHealth || 0}/${stats.bodyDamage || 0}/${stats.bulletSpeed || 0}/${stats.bulletPenetration || 0}/${stats.bulletDamage || 0}/${stats.reload || 0}/${stats.movementSpeed || 0}`;
                errorMessage = `A build with identical stats already exists for this tank.\n\nStats: ${statsString}`;
              } else {
                errorMessage = errorText || 'Unknown error';
              }
            }
          } catch (parseError) {
            errorMessage = e.message || 'Unknown error';
          }
          
          showToast(errorMessage);
          console.error('[KBUI] Build save error:', e);
        }
      });
  
      footer.appendChild(hint);
      footer.appendChild(saveBtn);
  
      form.appendChild(title);
      form.appendChild(info);
      form.appendChild(nameRow);
      form.appendChild(modeRow);
      form.appendChild(statsFieldsWrapper);
      form.appendChild(statsSlashWrapper);
      form.appendChild(footer);
  
      list.appendChild(form);
    }
  
    function openSettings() {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;

      list.innerHTML = '';

      const form = document.createElement('div');
      form.className = 'kbui-form';

      const title = document.createElement('div');
      title.className = 'kbui-section-title';
      title.textContent = 'Settings - Special Options';

      const info = document.createElement('div');
      info.className = 'kbui-small';
      info.style.marginTop = '16px';
      info.style.opacity = '0.7';
      info.textContent = 'No special options available at the moment.';

      const footer = document.createElement('div');
      footer.className = 'kbui-form-footer';
      footer.style.marginTop = '20px';

      const backBtn = document.createElement('button');
      backBtn.className = 'kbui-button-main';
      backBtn.textContent = 'Back';
      backBtn.addEventListener('click', () => {
        if (currentView === 'general') {
          loadAllBuilds();
        } else if (currentTankId) {
          loadBuildsForTank(currentTankId, currentTankName);
        }
      });

      footer.appendChild(backBtn);

      form.appendChild(title);
      form.appendChild(info);
      form.appendChild(footer);

      list.appendChild(form);
    }

    function openHighscoreForm(build) {
      const list = document.getElementById('kbui-build-list');
      if (!list) return;

      list.innerHTML = '';

      const form = document.createElement('div');
      form.className = 'kbui-form';

      const title = document.createElement('div');
      title.className = 'kbui-section-title';
      title.textContent = `Submit Highscore for "${build.name || 'Build'}"`;

      const info = document.createElement('div');
      info.className = 'kbui-small';
      info.textContent = 'Upload a screenshot showing your score, level, time, and the build. Admin will verify and approve.';

      const row1 = document.createElement('div');
      row1.className = 'kbui-form-row';

      const usernameGroup = document.createElement('div');
      usernameGroup.className = 'kbui-form-group';
      const usernameLabel = document.createElement('label');
      usernameLabel.textContent = 'Username *';
      const usernameInput = document.createElement('input');
      usernameInput.type = 'text';
      usernameInput.placeholder = 'Your username';
      usernameInput.maxLength = 50;
      usernameGroup.appendChild(usernameLabel);
      usernameGroup.appendChild(usernameInput);

      row1.appendChild(usernameGroup);

      const row2 = document.createElement('div');
      row2.className = 'kbui-form-row';

      const imageGroup = document.createElement('div');
      imageGroup.className = 'kbui-form-group';
      imageGroup.style.flex = '1';
      const imageLabel = document.createElement('label');
      imageLabel.textContent = 'Screenshot (Proof) *';
      const imageInput = document.createElement('input');
      imageInput.type = 'file';
      imageInput.accept = 'image/jpeg,image/jpg,image/png,image/gif,image/webp';
      imageInput.style.width = '100%';
      imageInput.style.padding = '4px';
      imageGroup.appendChild(imageLabel);
      imageGroup.appendChild(imageInput);

      row2.appendChild(imageGroup);

      const footer = document.createElement('div');
      footer.className = 'kbui-form-footer';

      const hint = document.createElement('div');
      hint.className = 'kbui-small';
      hint.textContent = 'Screenshot must show: Score, Level, Time, and the Build. Max 10MB.';

      const submitBtn = document.createElement('button');
      submitBtn.className = 'kbui-button-main';
      submitBtn.textContent = 'Submit Highscore';

      submitBtn.addEventListener('click', async () => {
        const username = usernameInput.value.trim();
        const imageFile = imageInput.files[0];

        if (!username) {
          showToast('Username is required');
          return;
        }

        if (!imageFile) {
          showToast('Screenshot is required');
          return;
        }

        if (imageFile.size > 10 * 1024 * 1024) {
          showToast('Image must be smaller than 10MB');
          return;
        }

        const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
        if (!allowedTypes.includes(imageFile.type)) {
          showToast('Only image files are allowed (jpeg, jpg, png, gif, webp)');
          return;
        }

        try {
          submitBtn.disabled = true;
          submitBtn.textContent = 'Uploading...';

          const formData = new FormData();
          formData.append('image', imageFile);
          formData.append('username', username);

          await apiPostFormData(API_ROUTES.submitHighscore(build.id), formData);
          showToast('Highscore submitted! Waiting for admin approval.');
          if (currentTankId) {
            loadBuildsForTank(currentTankId, currentTankName);
          }
        } catch (e) {
          showToast('Submit failed: ' + (e.message || 'Unknown error'));
          console.error(e);
        } finally {
          submitBtn.disabled = false;
          submitBtn.textContent = 'Submit Highscore';
        }
      });

      footer.appendChild(hint);
      footer.appendChild(submitBtn);

      form.appendChild(title);
      form.appendChild(info);
      form.appendChild(row1);
      form.appendChild(row2);
      form.appendChild(footer);

      list.appendChild(form);
    }
  
    function init() {
      injectStyles();
      createUIRoot();

      currentSettings = loadSettings();

      loadTanks().then(renderTankGrid).catch((e) => console.error(e));
  
      injectMenuBuildButton();
      const mo = new MutationObserver(() => injectMenuBuildButton());
      mo.observe(document.body, { childList: true, subtree: true });
    }
  
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', init);
    } else {
      init();
    }
  })();