Duolingo Auto-Super

Duolingo Super Manager - Create referral links, activate Super, manage accounts

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Duolingo Auto-Super
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Duolingo Super Manager - Create referral links, activate Super, manage accounts
// @author       MeowWoof
// @match        https://www.duolingo.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @connect      duolingo-super022.vercel.app
// @run-at       document-idle
// @license      MIT
// @icon         https://d35aaqx5ub95lt.cloudfront.net/vendor/38dc6a042b0de3f6aeb44ff2aa70de73.svg
// ==/UserScript==

(function () {
'use strict';

const SCRIPT_VERSION = '3.0';
const API_BASE       = 'https://duolingo-super022.vercel.app';
const FREE_KEY       = 'DS-FREE-PUBLIC-KEY-2025';
const DISCORD_URL    = 'https://discord.gg/ufBrcGemBH';
const CD_STORE       = 'duods_cd_expire';
const POLL_INTERVAL  = 30000;

let _sess        = null;
let _keyData     = null;
let _cdTimer     = null;
let _pollTimer   = null;
let _hist        = [];
let _hidden      = false;
let _animLock    = false;
let _pgLock      = false;
let _curPg       = 'auth';
let _ntTimer;
let _currentType = 'free';
let _fxActive    = false;
let _expireTimer = null;
let _sparkleInterval = null;
let _glitchTimer     = null;

function _detectDark() {
    const html = document.documentElement;
    if (html.dataset.theme === 'dark') return true;
    if (html.dataset.theme === 'light') return false;
    const htmlCl = html.className || '';
    const bodyCl = document.body.className || '';
    if (htmlCl.includes('dark') || bodyCl.includes('dark')) return true;
    if (htmlCl.includes('light') || bodyCl.includes('light')) return false;
    const bodyStyle = window.getComputedStyle(document.body);
    const htmlStyle = window.getComputedStyle(html);
    for (const s of [bodyStyle, htmlStyle]) {
        const bg = s.backgroundColor;
        if (bg) {
            const m = bg.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
            if (m) {
                const lum = 0.299 * +m[1] + 0.587 * +m[2] + 0.114 * +m[3];
                if (lum < 60) return true;
                if (lum > 180) return false;
            }
        }
    }
    try {
        const testEl = document.querySelector('[class*="duo"][class*="dark"], [data-color-mode="dark"], [color-scheme="dark"]');
        if (testEl) return true;
    } catch {}
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
}

function _applyTheme() {
    const root = document.getElementById('DDS_Root');
    if (!root) return;
    if (_detectDark()) {
        root.setAttribute('data-dds-dark', '1');
    } else {
        root.removeAttribute('data-dds-dark');
    }
}

function _watchTheme() {
    _applyTheme();
    const obs = new MutationObserver(() => _applyTheme());
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme', 'class', 'data-color-mode'], subtree: false });
    obs.observe(document.body, { attributes: true, attributeFilter: ['data-theme', 'class', 'data-color-mode'], subtree: false });
    const duoAppRoot = document.getElementById('root') || document.getElementById('app') || document.querySelector('[id^="__next"]');
    if (duoAppRoot) obs.observe(duoAppRoot, { attributes: true, attributeFilter: ['class', 'data-theme'] });
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', _applyTheme);
    setInterval(_applyTheme, 500);
}

function _req(path, method, body) {
    return new Promise(resolve => {
        const hdrs = _hdrs();
        if (!hdrs && path !== '/api/key/info' && path !== '/api/admin/version') return resolve({ error: 'Unauthorized' });
        const cfg = {
            method: method || 'POST',
            url: API_BASE + path,
            headers: hdrs || { 'Content-Type': 'application/json' },
            timeout: 90000,
            onload: r => {
                try { resolve(JSON.parse(r.responseText)); }
                catch { resolve({ error: 'Parse error: ' + r.responseText.slice(0, 120) }); }
            },
            onerror: () => resolve({ error: 'Network error' }),
            ontimeout: () => resolve({ error: 'Timeout (90s)' })
        };
        if (body) cfg.data = JSON.stringify(body);
        GM_xmlhttpRequest(cfg);
    });
}

function _hdrs() {
    if (!_sess) return null;
    if (Date.now() > _sess.exp) { _sess = null; return null; }
    return {
        'Content-Type': 'application/json',
        'x-ds-key': _sess.key,
        'x-ds-token': _sess.tok
    };
}

function _fetchKey(key) {
    return new Promise(resolve => {
        GM_xmlhttpRequest({
            method: 'GET',
            url: `${API_BASE}/api/key/info?key=${encodeURIComponent(key)}`,
            headers: { 'Content-Type': 'application/json' },
            timeout: 30000,
            onload: r => {
                try {
                    const d = JSON.parse(r.responseText);
                    if (d.ok) {
                        _sess = {
                            key,
                            tok: d.session_token || _fnv(key),
                            exp: Date.now() + (d.session_ttl_ms || 3600000)
                        };
                    }
                    resolve(d);
                } catch { resolve({ error: 'Parse error' }); }
            },
            onerror: () => resolve({ error: 'Network error' }),
            ontimeout: () => resolve({ error: 'Timeout' })
        });
    });
}

function _checkVersion() {
    return new Promise(resolve => {
        GM_xmlhttpRequest({
            method: 'GET',
            url: `${API_BASE}/api/admin/version`,
            headers: { 'Content-Type': 'application/json' },
            timeout: 15000,
            onload: r => {
                try { resolve(JSON.parse(r.responseText)); }
                catch { resolve(null); }
            },
            onerror: () => resolve(null),
            ontimeout: () => resolve(null)
        });
    });
}

function _fnv(s) {
    let h = 0x811c9dc5;
    for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = (h * 0x01000193) >>> 0; }
    return h.toString(16).padStart(8, '0') + Date.now().toString(36);
}

const _set = (k, v) => GM_setValue(k, v);
const _get = (k, d) => GM_getValue(k, d);

function _tsGMT7() {
    const now = new Date(Date.now() + 7 * 3600000);
    const hh = String(now.getUTCHours()).padStart(2, '0');
    const mm = String(now.getUTCMinutes()).padStart(2, '0');
    const ss = String(now.getUTCSeconds()).padStart(2, '0');
    return `${hh}:${mm}:${ss}`;
}

GM_addStyle(`
@property --dds-event-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: true;
}
@property --dds-admin-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: true;
}

#DDS_Root {
    --dds-blue:    0, 122, 255;
    --dds-green:   52, 199, 89;
    --dds-red:     255, 59, 48;
    --dds-orange:  255, 149, 0;
    --dds-purple:  88, 101, 242;
    --dds-gold:    255, 193, 7;
    --dds-card:    255, 255, 255;
    --dds-border:  200, 200, 210;
    --dds-text1:   30, 30, 40;
    --dds-text2:   100, 100, 115;
    --dds-inbg:    0, 122, 255;
    --dds-cd-bg:   255, 149, 0;
    --dds-tab-bg:  180, 180, 195;
    --dds-surface: 245, 245, 250;
    --dds-shadow:  0, 0, 0;
    --dds-spin-fg: 0, 122, 255;
    --dds-spin-bg: 0, 122, 255;
}
#DDS_Root[data-dds-dark] {
    --dds-blue:    10, 132, 255;
    --dds-green:   48, 209, 88;
    --dds-red:     255, 69, 58;
    --dds-orange:  255, 159, 10;
    --dds-purple:  100, 115, 255;
    --dds-gold:    255, 204, 0;
    --dds-card:    28, 28, 32;
    --dds-border:  60, 60, 70;
    --dds-text1:   240, 240, 248;
    --dds-text2:   160, 160, 175;
    --dds-inbg:    10, 132, 255;
    --dds-cd-bg:   255, 159, 10;
    --dds-tab-bg:  70, 70, 80;
    --dds-surface: 38, 38, 44;
    --dds-shadow:  0, 0, 0;
    --dds-spin-fg: 255, 255, 255;
    --dds-spin-bg: 255, 255, 255;
}

#DDS_Root * { box-sizing: border-box; }
#DDS_Root p, #DDS_Root span, #DDS_Root button,
#DDS_Root input, #DDS_Root label, #DDS_Root div, #DDS_Root textarea {
    font-family: 'din-round', -apple-system, sans-serif !important;
}
#DDS_Root p, #DDS_Root span { margin: 0; padding: 0; }
#DDS_Root svg { flex-shrink: 0; }
#DDS_Root a { text-decoration: none; }

.dds-shell {
    display: inline-flex; flex-direction: column;
    justify-content: flex-end; align-items: flex-end;
    gap: 8px; position: fixed; right: 16px; bottom: 16px;
    z-index: 2147483647;
}
@media (max-width: 699px) { .dds-shell { margin-bottom: 80px; } }

.dds-box {
    display: flex; width: 320px; padding: 16px;
    flex-direction: column; align-items: center; gap: 8px;
    overflow: hidden; border-radius: 24px;
    outline: 1.5px solid rgba(var(--dds-border), 0.55); outline-offset: -1px;
    background: rgba(var(--dds-card), 0.97);
    backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
    box-shadow: 0 12px 48px rgba(var(--dds-shadow),.22), 0 2px 8px rgba(var(--dds-shadow),.10);
    transition: height .6s cubic-bezier(.34,1.56,.64,1),
                width  .6s cubic-bezier(.34,1.56,.64,1);
    position: relative;
}

.dds-box.tier-event {
    outline: 2px solid rgba(255,193,7,.70);
    outline-offset: -1px;
    box-shadow: 0 12px 48px rgba(var(--dds-shadow),.22), 0 2px 8px rgba(var(--dds-shadow),.10);
    animation: dds-event-outline-breathe 3.5s ease-in-out infinite;
}
.dds-box.tier-event::before { content: none; display: none; }
.dds-box.tier-event::after  { content: none; display: none; }
@keyframes dds-event-outline-breathe {
    0%, 100% { outline-color: rgba(255,193,7,.55); }
    50%       { outline-color: rgba(255,193,7,.95); }
}

.dds-box.tier-admin {
    outline: 2px solid rgba(100,115,255,.70);
    outline-offset: -1px;
    box-shadow: 0 12px 48px rgba(var(--dds-shadow),.22), 0 2px 8px rgba(var(--dds-shadow),.10);
    animation: dds-admin-outline-breathe 2.8s ease-in-out infinite;
}
.dds-box.tier-admin::before { content: none; display: none; }
.dds-box.tier-admin::after  { content: none; display: none; }
@keyframes dds-admin-outline-breathe {
    0%, 100% { outline-color: rgba(100,115,255,.55); }
    50%       { outline-color: rgba(100,115,255,.95); }
}

.dds-tier-canvas {
    position: absolute; inset: 0;
    pointer-events: none; z-index: 0;
    border-radius: 22px; overflow: hidden;
}

.dds-row    { display: flex; align-items: center; justify-content: space-between; align-self: stretch; }
.dds-hstack { display: flex; align-items: center; gap: 8px; align-self: stretch; }
.dds-vstack { display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 8px; align-self: stretch; }
.dds-nosel  { user-select: none; -webkit-user-select: none; }
.dds-hr     { align-self: stretch; height: 1px; background: rgba(var(--dds-border), .35); flex-shrink: 0; }

.dds-t1 { font-size: 15px; font-weight: 700; line-height: normal; color: rgb(var(--dds-text1)); margin: 0; }
.dds-t2 { font-size: 13px; font-weight: 600; line-height: normal; color: rgba(var(--dds-text2), .80); margin: 0; }

.dds-input-wrap {
    display: flex; height: 48px; padding: 0 14px;
    align-items: center; flex: 1 0 0; gap: 8px; border-radius: 12px;
    outline: 2px solid rgba(var(--dds-inbg), .30); outline-offset: -2px;
    background: rgba(var(--dds-inbg), .10);
    position: relative; overflow: hidden;
}
.dds-input-wrap.ta {
    height: auto; min-height: 72px; padding: 12px 14px; align-items: flex-start;
}
.dds-input {
    border: none !important; outline: none !important; background: none !important;
    text-align: right; font-size: 14px !important; font-weight: 600 !important;
    color: rgb(var(--dds-blue)) !important; font-family: inherit !important;
    width: 100%; -moz-appearance: textfield; line-height: 1.4;
}
.dds-input::placeholder { color: rgba(var(--dds-blue), .40) !important; }
.dds-input::-webkit-outer-spin-button,
.dds-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
textarea.dds-input {
    resize: none; text-align: left; overflow-y: auto;
    font-size: 12px !important; min-height: 48px; padding-top: 2px;
}

.dds-main-btn {
    display: flex; height: 48px; padding: 12px 18px;
    justify-content: center; align-items: center; gap: 8px;
    border-radius: 14px; border: none; cursor: pointer;
    user-select: none; -webkit-user-select: none;
    outline: 2px solid rgba(var(--dds-shadow),.18); outline-offset: -2px;
    background: rgb(var(--dds-blue)); white-space: nowrap; flex-shrink: 0;
    transition: width .7s cubic-bezier(.77,0,.18,1),
                background .7s cubic-bezier(.16,1,.32,1),
                outline .7s cubic-bezier(.16,1,.32,1),
                filter .35s cubic-bezier(.16,1,.32,1),
                transform .35s cubic-bezier(.16,1,.32,1);
}
.dds-main-btn:hover  { filter: brightness(.88); transform: scale(1.03); }
.dds-main-btn:active { filter: brightness(.80); transform: scale(.97); }
.dds-main-btn:disabled { opacity: .38; pointer-events: none; }

.dds-lbl {
    font-size: 15px; font-weight: 800; letter-spacing: .2px;
    transition: opacity .35s, filter .35s, color .35s;
    white-space: nowrap;
}

.dds-sm-btn {
    display: flex; height: 40px; padding: 0 16px;
    justify-content: center; align-items: center; gap: 8px;
    border-radius: 12px; border: none; cursor: pointer;
    user-select: none; flex-shrink: 0;
    outline: 2px solid rgba(var(--dds-shadow),.18); outline-offset: -2px;
    background: rgb(var(--dds-blue)); white-space: nowrap;
    transition: background .7s cubic-bezier(.16,1,.32,1),
                filter .35s cubic-bezier(.16,1,.32,1),
                transform .35s cubic-bezier(.16,1,.32,1);
}
.dds-sm-btn:hover  { filter: brightness(.88); transform: scale(1.04); }
.dds-sm-btn:active { filter: brightness(.80); transform: scale(.96); }
.dds-sm-btn:disabled { opacity: .38; pointer-events: none; }
.dds-sm-lbl { font-size: 13px; font-weight: 800; transition: opacity .35s, filter .35s, color .35s; white-space: nowrap; }

.dds-prog-wrap {
    align-self: stretch; height: 0; border-radius: 4px;
    background: rgba(var(--dds-blue), .12); overflow: hidden;
    transition: height .4s cubic-bezier(.16,1,.32,1);
}
.dds-prog-wrap.on { height: 5px; }
.dds-prog-fill {
    height: 100%; border-radius: 4px; background: rgb(var(--dds-blue));
    width: 0%; transition: width .5s cubic-bezier(.16,1,.32,1);
    box-shadow: 0 0 8px rgba(var(--dds-blue), .45);
}
.dds-prog-fill.warn { background: rgb(var(--dds-red)); }

.dds-log {
    background: rgba(var(--dds-blue), .06);
    border: 1.5px solid rgba(var(--dds-blue), .18);
    border-radius: 12px; padding: 10px 14px;
    font-size: 11px !important; font-weight: 600 !important;
    color: rgba(var(--dds-text1), .75) !important;
    max-height: 160px; overflow-y: auto;
    line-height: 1.8; font-family: monospace !important;
    white-space: pre-wrap; word-break: break-all; align-self: stretch;
}
.dds-log::-webkit-scrollbar { width: 3px; }
.dds-log::-webkit-scrollbar-thumb { background: rgba(var(--dds-blue), .28); border-radius: 3px; }
.lo { color: rgb(var(--dds-green)); }
.le { color: rgb(var(--dds-red)); }
.li { color: rgb(var(--dds-blue)); }
.lw { color: rgb(var(--dds-orange)); }

.dds-badge {
    display: flex; align-items: center; justify-content: space-between;
    align-self: stretch; padding: 10px 14px; border-radius: 16px;
    outline: 1.5px solid rgba(var(--dds-blue), .25); outline-offset: -1px;
    background: rgba(var(--dds-blue), .08);
    transition: outline-color .5s, background .5s;
    position: relative; overflow: hidden;
}
.dds-badge.tier-event {
    outline-color: rgba(255,193,7,.60);
    background: linear-gradient(135deg, rgba(255,193,7,.11) 0%, rgba(255,140,0,.08) 50%, rgba(255,193,7,.11) 100%);
    animation: dds-badge-event-bg 4s ease-in-out infinite;
}
.dds-badge.tier-event::before {
    content: '✦ EVENT KEY ✦';
    position: absolute; top: 1px; right: 10px;
    font-size: 7px !important; font-weight: 900 !important;
    color: rgba(255,193,7,.60); letter-spacing: 2px;
    font-family: monospace !important;
    animation: dds-event-label-pulse 2s ease-in-out infinite;
}
.dds-badge.tier-event::after {
    content: '';
    position: absolute;
    top: 0; left: -80%; width: 55%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,215,0,.28), rgba(255,193,7,.14), transparent);
    animation: dds-badge-event-sweep 3.8s ease-in-out infinite;
    pointer-events: none;
}
@keyframes dds-badge-event-bg {
    0%, 100% { background-position: 0% 50%; box-shadow: inset 0 0 10px rgba(255,193,7,.06); }
    50%       { background-position: 100% 50%; box-shadow: inset 0 0 22px rgba(255,193,7,.14); }
}
@keyframes dds-event-label-pulse {
    0%, 100% { opacity: .60; }
    50%       { opacity: 1; text-shadow: 0 0 6px rgba(255,193,7,.80); }
}
@keyframes dds-badge-event-sweep {
    0%    { left: -60%; }
    40%, 100% { left: 150%; }
}
.dds-badge.tier-admin {
    outline-color: rgba(100,115,255,.60);
    background: linear-gradient(135deg, rgba(100,115,255,.13) 0%, rgba(160,32,240,.08) 50%, rgba(0,212,255,.09) 100%);
    animation: dds-badge-admin-bg 2.5s ease-in-out infinite;
}
.dds-badge.tier-admin::before {
    content: '⬡ ADMIN ACCESS ⬡';
    position: absolute; top: 1px; right: 10px;
    font-size: 7px !important; font-weight: 900 !important;
    color: rgba(100,115,255,.65); letter-spacing: 2px;
    font-family: monospace !important;
    animation: dds-admin-label-flicker 3s ease-in-out infinite;
}
.dds-badge.tier-admin::after {
    content: '';
    position: absolute;
    top: -100%; left: 0; width: 100%; height: 50%;
    background: linear-gradient(180deg, transparent, rgba(0,212,255,.11), rgba(100,115,255,.07), transparent);
    animation: dds-badge-admin-scan 2.2s linear infinite;
    pointer-events: none;
}
@keyframes dds-badge-admin-bg {
    0%, 100% { box-shadow: inset 0 0 12px rgba(100,115,255,.08); }
    50%       { box-shadow: inset 0 0 26px rgba(100,115,255,.20); }
}
@keyframes dds-admin-label-flicker {
    0%, 85%, 100% { opacity: .65; }
    88% { opacity: 1; text-shadow: 0 0 8px rgba(100,115,255,.90); }
    90% { opacity: .5; }
    92% { opacity: 1; text-shadow: 0 0 8px rgba(0,212,255,.80); }
}
@keyframes dds-badge-admin-scan {
    0%   { top: -50%; }
    100% { top: 150%; }
}

.dds-badge-key  { font-size: 12px; font-weight: 800; color: rgb(var(--dds-blue)); font-family: monospace !important; letter-spacing: .5px; }
.dds-badge-key.key-event {
    color: rgb(255,193,7);
    text-shadow: 0 0 10px rgba(255,193,7,.55);
    animation: dds-key-event-glow 2s ease-in-out infinite;
}
@keyframes dds-key-event-glow {
    0%, 100% { text-shadow: 0 0 8px rgba(255,193,7,.45); }
    50%       { text-shadow: 0 0 18px rgba(255,193,7,.85), 0 0 30px rgba(255,140,0,.35); }
}
.dds-badge-key.key-admin {
    color: rgb(100,115,255);
    animation: dds-key-admin-flicker 2.5s ease-in-out infinite;
}
@keyframes dds-key-admin-flicker {
    0%, 88%, 100% { color: rgb(100,115,255); text-shadow: 0 0 8px rgba(100,115,255,.50); }
    90%            { color: rgb(160,180,255); text-shadow: 0 0 16px rgba(100,115,255,.85); }
    93%            { color: rgb(80,100,240); }
    96%            { color: rgb(0,212,255); text-shadow: 0 0 14px rgba(0,212,255,.70); }
    98%            { color: rgb(100,115,255); }
}
.dds-badge-meta { font-size: 10px !important; font-weight: 600 !important; color: rgba(var(--dds-text2), .75) !important; margin-top: 2px; }

.dds-tier-tag {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 3px 10px; min-width: 44px;
    border-radius: 7px; font-size: 10px !important; font-weight: 800 !important;
    flex-shrink: 0; white-space: nowrap; letter-spacing: .5px;
}
.dds-tier-tag.tag-free {
    background: rgba(var(--dds-green), .16);
    outline: 1.5px solid rgba(var(--dds-green), .32); outline-offset: -1px;
    color: rgb(var(--dds-green)) !important;
}
.dds-tier-tag.tag-paid {
    background: rgba(var(--dds-blue), .14);
    outline: 1.5px solid rgba(var(--dds-blue), .30); outline-offset: -1px;
    color: rgb(var(--dds-blue)) !important;
}
.dds-tier-tag.tag-event {
    background: linear-gradient(135deg, rgba(255,140,0,.28), rgba(255,215,0,.22));
    outline: 1.5px solid rgba(255,193,7,.65); outline-offset: -1px;
    color: rgb(255,193,7) !important;
    text-shadow: 0 0 8px rgba(255,193,7,.80);
    animation: dds-tag-event-pulse 1.6s ease-in-out infinite;
    letter-spacing: 1.2px;
}
@keyframes dds-tag-event-pulse {
    0%, 100% {
        box-shadow: 0 0 6px rgba(255,193,7,.35), inset 0 0 5px rgba(255,193,7,.10);
        outline-color: rgba(255,193,7,.60);
    }
    50% {
        box-shadow: 0 0 16px rgba(255,193,7,.70), 0 0 28px rgba(255,140,0,.25), inset 0 0 10px rgba(255,193,7,.18);
        outline-color: rgba(255,193,7,1);
    }
}
.dds-tier-tag.tag-admin {
    background: linear-gradient(135deg, rgba(100,115,255,.28), rgba(160,32,240,.20), rgba(0,212,255,.14));
    outline: 1.5px solid rgba(100,115,255,.70); outline-offset: -1px;
    color: rgb(100,115,255) !important;
    animation: dds-tag-admin-pulse 1.3s ease-in-out infinite;
    letter-spacing: 1.5px;
    font-size: 9px !important;
}
@keyframes dds-tag-admin-pulse {
    0%, 100% {
        box-shadow: 0 0 8px rgba(100,115,255,.40), 0 0 18px rgba(160,32,240,.15);
        color: rgb(100,115,255) !important;
        outline-color: rgba(100,115,255,.65);
        text-shadow: 0 0 8px rgba(100,115,255,.70);
    }
    50% {
        box-shadow: 0 0 20px rgba(100,115,255,.75), 0 0 36px rgba(0,212,255,.35);
        color: rgb(160,190,255) !important;
        outline-color: rgba(0,212,255,.80);
        text-shadow: 0 0 16px rgba(0,212,255,.90);
    }
}

.dds-quota-wrap {
    align-self: stretch; display: flex; flex-direction: column; gap: 6px;
    padding: 10px 14px; border-radius: 16px;
    background: rgba(var(--dds-surface), .90);
    outline: 1.5px solid rgba(var(--dds-border), .35); outline-offset: -1px;
    transition: background .5s, outline-color .5s;
}
.dds-quota-wrap.tier-event {
    background: linear-gradient(135deg, rgba(255,193,7,.08), rgba(255,140,0,.05));
    outline-color: rgba(255,193,7,.32);
}
.dds-quota-wrap.tier-admin {
    background: linear-gradient(135deg, rgba(100,115,255,.09), rgba(0,212,255,.05));
    outline-color: rgba(100,115,255,.38);
}
.dds-quota-row   { display: flex; justify-content: space-between; align-items: center; }
.dds-quota-lbl   { font-size: 10px !important; font-weight: 700 !important; text-transform: uppercase; letter-spacing: .8px; color: rgba(var(--dds-text2), .65) !important; }
.dds-quota-val   { font-size: 11px !important; font-weight: 800 !important; color: rgb(var(--dds-blue)) !important; }
.dds-quota-val.qv-event { color: rgb(255,193,7) !important; }
.dds-quota-val.qv-admin { color: rgb(100,115,255) !important; }
.dds-track   { height: 5px; background: rgba(var(--dds-blue), .14); border-radius: 4px; overflow: hidden; }
.dds-track.tr-event { background: rgba(255,193,7,.20); }
.dds-track.tr-admin { background: rgba(100,115,255,.20); }
.dds-tfill   { height: 100%; background: rgb(var(--dds-blue)); border-radius: 4px; transition: width .6s cubic-bezier(.34,1.56,.64,1); }
.dds-tfill.warn { background: rgb(var(--dds-red)); }
.dds-tfill.tf-event {
    background: linear-gradient(90deg, #ffb300, #ffd700, #ffec6e);
    box-shadow: 0 0 8px rgba(255,193,7,.55);
    animation: dds-tfill-event-shimmer 2s ease-in-out infinite;
}
@keyframes dds-tfill-event-shimmer {
    0%, 100% { box-shadow: 0 0 6px rgba(255,193,7,.50); }
    50%       { box-shadow: 0 0 14px rgba(255,193,7,.90), 0 0 22px rgba(255,140,0,.35); }
}
.dds-tfill.tf-admin {
    background: linear-gradient(90deg, #6464ff, #a020f0, #00d4ff);
    box-shadow: 0 0 8px rgba(100,115,255,.55);
    animation: dds-tfill-admin-flow 1.8s linear infinite;
}
@keyframes dds-tfill-admin-flow {
    0%   { filter: hue-rotate(0deg) brightness(1); }
    50%  { filter: hue-rotate(30deg) brightness(1.3); }
    100% { filter: hue-rotate(0deg) brightness(1); }
}

.dds-cd {
    display: none; align-items: center; justify-content: space-between;
    align-self: stretch; padding: 8px 14px; border-radius: 14px;
    background: rgba(var(--dds-cd-bg), .12);
    outline: 1.5px solid rgba(var(--dds-cd-bg), .28); outline-offset: -1px;
}
.dds-cd.on    { display: flex; animation: dds-slidein .35s cubic-bezier(.34,1.56,.64,1); }
.dds-cd-lbl   { display: flex; align-items: center; gap: 5px; font-size: 11px !important; font-weight: 700 !important; color: rgb(var(--dds-orange)) !important; }
.dds-cd-time  { font-size: 14px !important; font-weight: 800 !important; color: rgb(var(--dds-orange)) !important; font-family: monospace !important; }

.dds-cd-info {
    display: none; align-self: stretch;
    align-items: center; gap: 5px;
    padding: 5px 10px; border-radius: 9px;
    background: rgba(var(--dds-orange), .06);
    outline: 1px solid rgba(var(--dds-orange), .16); outline-offset: -1px;
    color: rgba(var(--dds-text2), .68);
    font-size: 9.5px !important; font-weight: 600 !important; line-height: 1.45;
    flex-wrap: nowrap; overflow: hidden;
}
.dds-cd-info.on { display: flex; animation: dds-slidein .35s cubic-bezier(.34,1.56,.64,1); }
.dds-cd-info svg { flex-shrink: 0; color: rgb(var(--dds-orange)); }
.dds-cd-info-link {
    color: rgb(var(--dds-orange)) !important;
    font-weight: 800 !important; text-decoration: none;
    white-space: nowrap; flex-shrink: 0;
    transition: opacity .2s;
}
.dds-cd-info-link:hover { opacity: .70; }
.dds-cd-info-text { min-width: 0; overflow: hidden; }

.dds-tabs {
    display: flex; gap: 2px; align-self: stretch;
    background: rgba(var(--dds-tab-bg), .15);
    border-radius: 14px; padding: 3px;
    outline: 1.5px solid rgba(var(--dds-border), .25); outline-offset: -1px;
    position: relative; z-index: 1;
}
.dds-tab {
    flex: 1; padding: 7px 4px; border: none; border-radius: 11px;
    background: none; color: rgba(var(--dds-text2), .65);
    font-size: 10px !important; font-weight: 700 !important; cursor: pointer;
    transition: all .28s cubic-bezier(.34,1.56,.64,1);
}
.dds-tab.on {
    background: rgb(var(--dds-blue)); color: #fff;
    box-shadow: 0 2px 10px rgba(var(--dds-blue), .42);
    transform: scale(1.05);
}
.dds-tab.on.tab-event {
    background: linear-gradient(135deg, #ffb300, #ffd700);
    box-shadow: 0 2px 14px rgba(255,193,7,.60);
    color: rgba(0,0,0,.75) !important;
}
.dds-tab.on.tab-admin {
    background: linear-gradient(135deg, #6464ff, #a020f0);
    box-shadow: 0 2px 16px rgba(100,115,255,.65);
}
.dds-tab:hover:not(.on) { color: rgb(var(--dds-text1)); background: rgba(var(--dds-blue), .08); transform: scale(1.02); }

.dds-pane        { display: none; flex-direction: column; gap: 8px; align-self: stretch; }
.dds-pane.active { display: flex; animation: dds-fadein .22s cubic-bezier(.16,1,.32,1); }
.dds-page        { display: none; }
.dds-page.active {
    display: flex; flex-direction: column; gap: 8px;
    align-self: stretch; align-items: center;
    position: relative; z-index: 1;
}

@keyframes dds-fadein {
    from { opacity: 0; transform: translateY(6px) scale(.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes dds-slidein {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
@keyframes dds-float {
    0%, 100% { transform: translateY(0) rotate(-1deg); }
    50%       { transform: translateY(-6px) rotate(1deg); }
}

.dds-lock-ring {
    width: 58px; height: 58px; border-radius: 18px;
    background: rgba(var(--dds-blue), .12);
    outline: 1.5px solid rgba(var(--dds-blue), .28); outline-offset: -1px;
    display: flex; align-items: center; justify-content: center;
    animation: dds-float 3.4s ease-in-out infinite;
}

.dds-copy-tag {
    display: inline-flex; align-items: center;
    padding: 2px 8px; border-radius: 6px;
    background: rgba(var(--dds-blue), .12);
    outline: 1px solid rgba(var(--dds-blue), .25); outline-offset: -1px;
    font-size: 9px !important; font-weight: 700 !important;
    cursor: pointer; color: rgb(var(--dds-blue)) !important;
    margin-left: 6px; transition: background .15s, transform .15s; vertical-align: middle;
}
.dds-copy-tag:hover { background: rgba(var(--dds-blue), .24); transform: scale(1.08); }
.dds-copy-tag:active { transform: scale(.94); }

.dds-err {
    font-size: 11px !important; font-weight: 600 !important;
    color: rgb(var(--dds-red)) !important; text-align: center;
    min-height: 14px; align-self: stretch;
}

.dds-ico-box {
    width: 26px; height: 26px; border-radius: 8px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
}

.dds-danger-btn {
    display: flex; height: 30px; padding: 0 12px;
    justify-content: center; align-items: center; border-radius: 10px; border: none;
    cursor: pointer; font-size: 11px !important; font-weight: 800 !important;
    background: rgba(var(--dds-red), .10);
    outline: 1.5px solid rgba(var(--dds-red), .25); outline-offset: -1px;
    color: rgb(var(--dds-red)) !important; white-space: nowrap;
    transition: filter .3s, transform .3s, background .3s, color .3s;
}
.dds-danger-btn:hover  { background: rgb(var(--dds-red)); color: #fff !important; transform: scale(1.04); }
.dds-danger-btn:active { transform: scale(.95); }

.dds-hide-btn {
    display: flex; height: 40px; padding: 0 16px;
    align-items: center; gap: 8px;
    border-radius: 14px; border: none; cursor: pointer; user-select: none;
    outline: 2px solid rgba(var(--dds-shadow),.18); outline-offset: -2px;
    background: rgb(var(--dds-blue));
    transition: filter .35s cubic-bezier(.16,1,.32,1),
                transform .35s cubic-bezier(.16,1,.32,1),
                background .4s, outline .4s;
}
.dds-hide-btn:hover  { filter: brightness(.88); transform: scale(1.04); }
.dds-hide-btn:active { filter: brightness(.80); transform: scale(.96); }

.dds-ntf-shell {
    display: flex; justify-content: center; align-items: center;
    width: 300px; position: fixed; left: calc(50% - 150px);
    z-index: 2147483647; bottom: 16px; border-radius: 18px;
    transition: .8s cubic-bezier(.16,1,.32,1); pointer-events: none;
}
.dds-ntf-box {
    display: flex; width: 300px; padding: 14px 16px;
    flex-direction: column; gap: 3px; border-radius: 18px;
    outline: 1.5px solid rgba(var(--dds-border), .40); outline-offset: -1px;
    background: rgba(var(--dds-card), 0.97);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 8px 32px rgba(var(--dds-shadow),.16);
    transition: .8s cubic-bezier(.16,1,.32,1); filter: blur(16px); opacity: 0;
    pointer-events: auto;
}
.dds-ntf-box.show { filter: blur(0); opacity: 1; }

.dds-discord-card {
    align-self: stretch; padding: 10px 14px; border-radius: 14px;
    background: rgba(var(--dds-purple),.10);
    outline: 1.5px solid rgba(var(--dds-purple),.28); outline-offset: -1px;
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.dds-discord-link {
    font-size: 11px !important; font-weight: 800 !important;
    color: rgb(var(--dds-purple)) !important;
    padding: 5px 12px; border-radius: 9px;
    background: rgba(var(--dds-purple),.14);
    outline: 1px solid rgba(var(--dds-purple),.25); outline-offset: -1px;
    white-space: nowrap; flex-shrink: 0;
    transition: background .2s, transform .2s;
}
.dds-discord-link:hover { background: rgba(var(--dds-purple),.26); transform: scale(1.05); }

.dds-sec-lbl {
    font-size: 10px !important; font-weight: 700 !important;
    text-transform: uppercase; letter-spacing: .7px;
    color: rgba(var(--dds-text2), .65) !important; align-self: flex-start;
}

.dds-info-card {
    padding: 10px 14px; border-radius: 14px;
    background: rgba(var(--dds-surface), .90);
    outline: 1.5px solid rgba(var(--dds-border), .30); outline-offset: -1px;
    align-self: stretch;
}

.dds-dot-ring { display: inline-flex; gap: 4px; align-items: center; }
.dds-dot-ring span {
    width: 5px; height: 5px; border-radius: 50%; background: currentColor;
    animation: dds-dot-pulse 1.2s ease-in-out infinite;
}
.dds-dot-ring span:nth-child(2) { animation-delay: .18s; }
.dds-dot-ring span:nth-child(3) { animation-delay: .36s; }
@keyframes dds-dot-pulse {
    0%, 80%, 100% { transform: scale(.55); opacity: .35; }
    40%            { transform: scale(1.1); opacity: 1; }
}

.dds-spin-ring {
    width: 16px; height: 16px; border-radius: 50%;
    border: 2.5px solid rgba(var(--dds-spin-bg), .28);
    border-top-color: rgb(var(--dds-spin-fg));
    animation: dds-spin 0.75s linear infinite;
    flex-shrink: 0;
}
@keyframes dds-spin { to { transform: rotate(360deg); } }

.dds-pulse-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: rgb(var(--dds-green));
    animation: dds-pulse-glow 2s ease-in-out infinite;
    flex-shrink: 0;
}
@keyframes dds-pulse-glow {
    0%, 100% { box-shadow: 0 0 0 0 rgba(var(--dds-green), .60); transform: scale(1); }
    50%       { box-shadow: 0 0 0 5px rgba(var(--dds-green), 0); transform: scale(1.18); }
}

.dds-shimmer {
    position: absolute; top: 0; left: -120px; width: 80px; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.22), transparent);
    animation: dds-shimmer-move 2.8s ease-in-out infinite 1.4s;
    pointer-events: none;
}
@keyframes dds-shimmer-move {
    0%   { left: -120px; }
    38%  { left: 360px; }
    100% { left: 360px; }
}

.dds-ripple-btn { position: relative; overflow: hidden; }
.dds-ripple-btn::after {
    content: ''; position: absolute; border-radius: 50%;
    width: 4px; height: 4px;
    background: rgba(255,255,255,.38);
    transform: scale(0); opacity: 1;
    pointer-events: none;
}
.dds-ripple-btn.rippling::after { animation: dds-ripple .55s linear; }
@keyframes dds-ripple { to { transform: scale(80); opacity: 0; } }

#dds-fx-canvas {
    position: fixed; inset: 0; pointer-events: none;
    z-index: 2147483646; display: none;
}
#dds-fx-canvas.on { display: block; }

.dds-blocked-banner {
    align-self: stretch; padding: 12px 14px; border-radius: 14px;
    background: rgba(var(--dds-red), .10);
    outline: 1.5px solid rgba(var(--dds-red), .28); outline-offset: -1px;
    display: flex; flex-direction: column; gap: 4px;
}
.dds-blocked-title {
    font-size: 13px !important; font-weight: 800 !important;
    color: rgb(var(--dds-red)) !important;
}
.dds-blocked-sub {
    font-size: 11px !important; font-weight: 600 !important;
    color: rgba(var(--dds-red), .75) !important; line-height: 1.5;
}

.dds-update-banner {
    align-self: stretch; padding: 12px 14px; border-radius: 14px;
    background: rgba(var(--dds-orange), .10);
    outline: 1.5px solid rgba(var(--dds-orange), .30); outline-offset: -1px;
    display: flex; flex-direction: column; gap: 6px;
}
.dds-update-title {
    font-size: 13px !important; font-weight: 800 !important;
    color: rgb(var(--dds-orange)) !important;
}
.dds-update-sub {
    font-size: 11px !important; font-weight: 600 !important;
    color: rgba(var(--dds-orange), .80) !important; line-height: 1.5;
}

.dds-create-btn-event {
    background: linear-gradient(135deg, #ff8c00, #ffd700) !important;
    outline-color: rgba(255,193,7,.45) !important;
    box-shadow: 0 4px 22px rgba(255,193,7,.45) !important;
}
.dds-create-btn-event:hover { filter: brightness(.90) !important; box-shadow: 0 6px 32px rgba(255,193,7,.65) !important; }

.dds-create-btn-admin {
    background: linear-gradient(135deg, #5555ee, #a020f0) !important;
    outline-color: rgba(100,115,255,.45) !important;
    box-shadow: 0 4px 22px rgba(100,115,255,.50) !important;
}
.dds-create-btn-admin:hover { filter: brightness(.90) !important; box-shadow: 0 6px 32px rgba(100,115,255,.70) !important; }

.dds-expiry-banner {
    align-self: stretch; padding: 8px 12px; border-radius: 12px;
    background: rgba(var(--dds-orange), .08);
    outline: 1px solid rgba(var(--dds-orange), .25); outline-offset: -1px;
    display: none; align-items: center; gap: 6px;
}
.dds-expiry-banner.on { display: flex; }
.dds-expiry-txt { font-size: 10px !important; font-weight: 700 !important; color: rgb(var(--dds-orange)) !important; }

.dds-footer-event { color: rgba(255,193,7,.65) !important; text-shadow: 0 0 8px rgba(255,193,7,.35); }
.dds-footer-admin {
    animation: dds-footer-admin-cycle 3s ease-in-out infinite;
}
@keyframes dds-footer-admin-cycle {
    0%, 100% { color: rgba(100,115,255,.65) !important; }
    50%       { color: rgba(0,212,255,.75) !important; text-shadow: 0 0 6px rgba(0,212,255,.35); }
}
`);

const _root = document.createElement('div');
_root.id = 'DDS_Root';
_root.innerHTML = `
<canvas id="dds-fx-canvas"></canvas>

<div class="dds-ntf-shell" id="dds-ntf">
    <div class="dds-ntf-box" id="dds-ntf-box">
        <p class="dds-t1 dds-nosel" id="dds-ntf-title"></p>
        <p class="dds-t2 dds-nosel" id="dds-ntf-body" style="align-self:stretch;overflow-wrap:break-word;"></p>
    </div>
</div>

<div class="dds-shell" id="dds-shell">

    <div class="dds-hstack" style="align-self:flex-end;">
        <button class="dds-hide-btn dds-nosel" id="dds-toggle">
            <div class="dds-ico-box" id="dds-ico-wrap" style="background:rgba(255,255,255,.20);">
                <svg id="dds-ico-eye" width="14" height="14" viewBox="0 0 24 18" fill="none">
                    <path d="M12 3C7.5 3 3.73 5.5 2 9c1.73 3.5 5.5 6 10 6s8.27-2.5 10-6c-1.73-3.5-5.5-6-10-6zm0 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5z" fill="#fff"/>
                    <line x1="2" y1="2" x2="22" y2="16" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
                </svg>
                <svg id="dds-ico-eyeoff" width="14" height="14" viewBox="0 0 24 18" fill="none" style="display:none;">
                    <path d="M12 3C7.5 3 3.73 5.5 2 9c1.73 3.5 5.5 6 10 6s8.27-2.5 10-6c-1.73-3.5-5.5-6-10-6zm0 10a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5z" fill="rgb(var(--dds-blue))"/>
                </svg>
            </div>
            <p class="dds-t1 dds-nosel" id="dds-toggle-txt" style="color:#fff;font-size:14px;">Hide</p>
        </button>
    </div>

    <div class="dds-box" id="dds-box">

        <div class="dds-page" id="dds-page-blocked">
            <div class="dds-lock-ring" style="background:rgba(var(--dds-red),.12);outline-color:rgba(var(--dds-red),.28);">
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                    <rect x="3" y="11" width="18" height="11" rx="3" fill="none" stroke="rgb(var(--dds-red))" stroke-width="2"/>
                    <path d="M7 11V7a5 5 0 0 1 10 0v4" stroke="rgb(var(--dds-red))" stroke-width="2" stroke-linecap="round"/>
                    <line x1="9" y1="15" x2="15" y2="19" stroke="rgb(var(--dds-red))" stroke-width="2" stroke-linecap="round"/>
                    <line x1="15" y1="15" x2="9" y2="19" stroke="rgb(var(--dds-red))" stroke-width="2" stroke-linecap="round"/>
                </svg>
            </div>
            <div class="dds-blocked-banner">
                <p class="dds-blocked-title dds-nosel">Key In Use</p>
                <p class="dds-blocked-sub dds-nosel">This key is currently being used by another session. Please use a different key or contact Discord to get your own private key.</p>
            </div>
            <button class="dds-main-btn dds-nosel" id="dds-blocked-chkey-btn" style="width:100%;background:rgba(var(--dds-red),.12);outline:2px solid rgba(var(--dds-red),.28);outline-offset:-2px;">
                <span class="dds-lbl" style="color:rgb(var(--dds-red));">Change Key</span>
            </button>
            <div class="dds-discord-card">
                <div style="display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;">
                    <p class="dds-t1 dds-nosel" style="font-size:11px;color:rgb(var(--dds-purple));">Need support?</p>
                    <p class="dds-t2 dds-nosel" style="font-size:10px;">Join our Discord server</p>
                </div>
                <a class="dds-discord-link" href="${DISCORD_URL}" target="_blank" rel="noopener">Join</a>
            </div>
            <div class="dds-row" style="align-self:stretch;padding-top:2px;">
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">discord.gg/ufBrcGemBH</p>
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">v${SCRIPT_VERSION}</p>
            </div>
        </div>

        <div class="dds-page" id="dds-page-update">
            <div class="dds-lock-ring" style="background:rgba(var(--dds-orange),.12);outline-color:rgba(var(--dds-orange),.28);">
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                    <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" stroke="rgb(var(--dds-orange))" stroke-width="2" fill="none"/>
                    <path d="M12 7v6" stroke="rgb(var(--dds-orange))" stroke-width="2.5" stroke-linecap="round"/>
                    <circle cx="12" cy="16.5" r="1.2" fill="rgb(var(--dds-orange))"/>
                </svg>
            </div>
            <div class="dds-update-banner">
                <p class="dds-update-title dds-nosel">Update Required</p>
                <p class="dds-update-sub dds-nosel" id="dds-update-msg">Your script version is outdated. Please update to the latest version to continue using.</p>
            </div>
            <a class="dds-main-btn dds-nosel" id="dds-update-btn" href="#" target="_blank" rel="noopener" style="width:100%;text-decoration:none;">
                <span class="dds-lbl" style="color:#fff;">Update Now</span>
            </a>
            <div class="dds-row" style="align-self:stretch;padding-top:2px;">
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-orange),.60);">Current version: v${SCRIPT_VERSION}</p>
            </div>
        </div>

        <div class="dds-page active" id="dds-page-auth">
            <div class="dds-lock-ring">
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                    <rect x="3" y="11" width="18" height="11" rx="3" fill="none" stroke="rgb(var(--dds-blue))" stroke-width="2"/>
                    <path d="M7 11V7a5 5 0 0 1 10 0v4" stroke="rgb(var(--dds-blue))" stroke-width="2" stroke-linecap="round"/>
                    <circle cx="12" cy="16.5" r="1.5" fill="rgb(var(--dds-blue))"/>
                </svg>
            </div>
            <div style="display:flex;flex-direction:column;gap:4px;align-items:center;align-self:stretch;">
                <p class="dds-t1 dds-nosel" style="font-size:16px;text-align:center;">Authenticate to continue</p>
                <p class="dds-t2 dds-nosel" style="text-align:center;font-size:12px;">Enter your key to unlock all features</p>
            </div>
            <div class="dds-hr"></div>
            <div class="dds-vstack" style="align-self:stretch;">
                <div class="dds-hstack">
                    <div class="dds-input-wrap">
                        <div class="dds-ico-box" style="background:rgba(var(--dds-blue),.16);">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                                <path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" stroke="rgba(var(--dds-blue),.75)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <input id="dds-key-in" class="dds-input dds-nosel" type="password" placeholder="DS-XXXXXXXXXXXXXXXX" style="text-align:left;" autocomplete="off">
                    </div>
                    <button class="dds-main-btn dds-nosel dds-ripple-btn" id="dds-unlock-btn" style="flex:none;height:48px;border-radius:14px;padding:0 18px;position:relative;overflow:hidden;">
                        <div class="dds-shimmer"></div>
                        <span class="dds-lbl" id="dds-unlock-lbl" style="color:#fff;">UNLOCK</span>
                    </button>
                </div>
                <p class="dds-err" id="dds-auth-err"></p>
                <div id="dds-auth-spin" style="display:none;justify-content:center;">
                    <div class="dds-dot-ring" style="color:rgb(var(--dds-blue));"><span></span><span></span><span></span></div>
                </div>
            </div>
            <button class="dds-main-btn dds-nosel" id="dds-free-btn" style="width:100%;background:rgba(var(--dds-green),.13);outline:2px solid rgba(var(--dds-green),.30);outline-offset:-2px;">
                <div class="dds-pulse-dot"></div>
                <span class="dds-lbl" style="color:rgb(var(--dds-green));">Use Free Key</span>
            </button>
            <div class="dds-discord-card">
                <div style="display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;">
                    <p class="dds-t1 dds-nosel" style="font-size:11px;color:rgb(var(--dds-purple));">Get your own key</p>
                    <p class="dds-t2 dds-nosel" style="font-size:10px;">Join our Discord server</p>
                </div>
                <a class="dds-discord-link" href="${DISCORD_URL}" target="_blank" rel="noopener">Join</a>
            </div>
            <div class="dds-row" style="align-self:stretch;padding-top:2px;">
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">discord.gg/ufBrcGemBH</p>
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">v${SCRIPT_VERSION}</p>
            </div>
        </div>

        <div class="dds-page" id="dds-page-dash">
            <div class="dds-badge" id="dds-badge">
                <div style="display:flex;flex-direction:column;gap:4px;min-width:0;flex:1;">
                    <div style="display:flex;align-items:center;gap:7px;flex-wrap:nowrap;">
                        <p class="dds-badge-key dds-nosel" id="dds-key-disp" style="min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">DS-XXXX...</p>
                        <span class="dds-tier-tag dds-nosel tag-free" id="dds-tier-tag" style="display:none;">FREE</span>
                    </div>
                    <p class="dds-badge-meta dds-nosel" id="dds-key-meta">Batch: ? · CD: ?s</p>
                </div>
                <button class="dds-danger-btn dds-nosel" id="dds-chkey-btn">Change key</button>
            </div>
            <div class="dds-expiry-banner" id="dds-expiry-banner">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                    <circle cx="12" cy="12" r="9" stroke="rgb(var(--dds-orange))" stroke-width="2"/>
                    <path d="M12 7v5l3 3" stroke="rgb(var(--dds-orange))" stroke-width="2" stroke-linecap="round"/>
                </svg>
                <span class="dds-expiry-txt" id="dds-expiry-txt">Key expires in --:--</span>
            </div>
            <div class="dds-quota-wrap" id="dds-quota-wrap">
                <div class="dds-quota-row">
                    <span class="dds-quota-lbl dds-nosel">DAILY QUOTA</span>
                    <span class="dds-quota-val dds-nosel" id="dds-quota-val">0 / 0</span>
                </div>
                <div class="dds-track" id="dds-quota-track"><div class="dds-tfill" id="dds-quota-fill" style="width:0%"></div></div>
            </div>
            <div class="dds-cd" id="dds-cd">
                <span class="dds-cd-lbl dds-nosel">
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                        <circle cx="12" cy="12" r="9" stroke="rgb(var(--dds-orange))" stroke-width="2"/>
                        <path d="M12 7v5l3 3" stroke="rgb(var(--dds-orange))" stroke-width="2" stroke-linecap="round"/>
                    </svg>
                    Cooldown
                </span>
                <span class="dds-cd-time dds-nosel" id="dds-cd-time">00:00</span>
            </div>
            <div class="dds-cd-info" id="dds-cd-info">
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" style="flex-shrink:0;">
                    <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
                    <path d="M12 8v4M12 16h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
                <span class="dds-cd-info-text">Shared key — cooldown can be set by other users.</span>
                <a class="dds-cd-info-link" href="${DISCORD_URL}" target="_blank" rel="noopener">Get private key →</a>
            </div>
            <div class="dds-tabs" id="dds-tabs">
                <button class="dds-tab on dds-nosel" data-tab="link">Links</button>
                <button class="dds-tab dds-nosel"    data-tab="active">Active</button>
                <button class="dds-tab dds-nosel"    data-tab="hist">History</button>
            </div>

            <div class="dds-pane active" id="dds-pane-link">
                <div class="dds-info-card">
                    <p class="dds-t2 dds-nosel" style="font-size:11px;line-height:1.65;">
                        Create <span id="dds-batch-n" style="color:rgb(var(--dds-blue));font-weight:800;">?</span> links per batch. System runs in parallel.
                    </p>
                </div>
                <button class="dds-main-btn dds-nosel dds-ripple-btn" id="dds-create-btn" style="width:100%;position:relative;overflow:hidden;">
                    <div class="dds-shimmer"></div>
                    <div class="dds-ico-box" id="dds-create-ico" style="background:rgba(255,255,255,.20);">
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5">
                            <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
                        </svg>
                    </div>
                    <span class="dds-lbl" id="dds-create-lbl" style="color:#fff;">Create Link Batch</span>
                </button>
                <div class="dds-prog-wrap" id="dds-create-prog">
                    <div class="dds-prog-fill" id="dds-create-fill"></div>
                </div>
                <p class="dds-sec-lbl">Output</p>
                <div class="dds-log" id="dds-log-link">Ready...</div>
            </div>

            <div class="dds-pane" id="dds-pane-active">
                <p class="dds-sec-lbl">Duolingo JWT</p>
                <div class="dds-input-wrap ta">
                    <textarea id="dds-jwt-in" class="dds-input dds-nosel" placeholder="eyJhbGci..." rows="3"></textarea>
                </div>
                <button class="dds-main-btn dds-nosel dds-ripple-btn" id="dds-activate-btn" style="width:100%;position:relative;overflow:hidden;">
                    <div class="dds-shimmer"></div>
                    <div class="dds-ico-box" id="dds-activate-ico" style="background:rgba(255,255,255,.20);">
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5">
                            <path d="M5 12h14M12 5l7 7-7 7"/>
                        </svg>
                    </div>
                    <span class="dds-lbl" id="dds-activate-lbl" style="color:#fff;">Activate Super</span>
                </button>
                <div class="dds-log" id="dds-log-active">Waiting for command...</div>
            </div>

            <div class="dds-pane" id="dds-pane-hist">
                <div class="dds-hstack">
                    <button class="dds-main-btn dds-nosel dds-ripple-btn" id="dds-loadhist-btn" style="flex:1;height:40px;border-radius:12px;padding:0 14px;position:relative;overflow:hidden;">
                        <div class="dds-ico-box" id="dds-loadhist-ico" style="background:rgba(255,255,255,.20);">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5">
                                <polyline points="1 4 1 10 7 10"/>
                                <path d="M3.51 15a9 9 0 1 0 .49-3.68"/>
                            </svg>
                        </div>
                        <span class="dds-lbl" id="dds-loadhist-lbl" style="color:#fff;font-size:13px;">Load history</span>
                    </button>
                    <button class="dds-sm-btn dds-nosel" id="dds-copyall-btn">
                        <div class="dds-ico-box" style="background:rgba(255,255,255,.20);">
                            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5">
                                <rect x="9" y="9" width="13" height="13" rx="2" stroke-linejoin="round"/>
                                <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
                            </svg>
                        </div>
                        <span class="dds-sm-lbl" style="color:#fff;">Copy all</span>
                    </button>
                </div>
                <div class="dds-log" id="dds-hist-log" style="max-height:200px;">Press load to view...</div>
            </div>

            <div class="dds-row" style="align-self:stretch;padding-top:2px;">
                <p class="dds-t2 dds-nosel" id="dds-footer-discord" style="color:rgba(var(--dds-blue),.50);">discord.gg/ufBrcGemBH</p>
                <p class="dds-t2 dds-nosel" id="dds-footer-ver" style="color:rgba(var(--dds-blue),.50);">v${SCRIPT_VERSION}</p>
            </div>
        </div>

        <div class="dds-page" id="dds-page-chkey">
            <div style="display:flex;flex-direction:column;gap:4px;align-items:center;align-self:stretch;">
                <p class="dds-t1 dds-nosel" style="font-size:15px;text-align:center;">Switch Key</p>
                <p class="dds-t2 dds-nosel" style="text-align:center;font-size:12px;">Enter a new key or return to free tier</p>
            </div>
            <div class="dds-hr"></div>
            <div class="dds-vstack" style="align-self:stretch;">
                <div class="dds-hstack">
                    <div class="dds-input-wrap">
                        <div class="dds-ico-box" style="background:rgba(var(--dds-blue),.16);">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                                <path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" stroke="rgba(var(--dds-blue),.75)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <input id="dds-newkey-in" class="dds-input dds-nosel" type="password" placeholder="DS-XXXXXXXXXXXXXXXX" style="text-align:left;" autocomplete="off">
                    </div>
                    <button class="dds-main-btn dds-nosel dds-ripple-btn" id="dds-newkey-btn" style="flex:none;height:48px;border-radius:14px;padding:0 18px;position:relative;overflow:hidden;">
                        <div class="dds-shimmer"></div>
                        <span class="dds-lbl" id="dds-newkey-lbl" style="color:#fff;">Apply</span>
                    </button>
                </div>
                <p class="dds-err" id="dds-chkey-err"></p>
                <div id="dds-chkey-spin" style="display:none;justify-content:center;">
                    <div class="dds-dot-ring" style="color:rgb(var(--dds-blue));"><span></span><span></span><span></span></div>
                </div>
            </div>
            <button class="dds-main-btn dds-nosel" id="dds-activefree-btn" style="width:100%;background:rgba(var(--dds-green),.13);outline:2px solid rgba(var(--dds-green),.30);outline-offset:-2px;">
                <div class="dds-pulse-dot"></div>
                <span class="dds-lbl" style="color:rgb(var(--dds-green));">Activate Free Key</span>
            </button>
            <div class="dds-discord-card">
                <div style="display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;">
                    <p class="dds-t1 dds-nosel" style="font-size:11px;color:rgb(var(--dds-purple));">Get a premium key</p>
                    <p class="dds-t2 dds-nosel" style="font-size:10px;">More quota, faster cooldown</p>
                </div>
                <a class="dds-discord-link" href="${DISCORD_URL}" target="_blank" rel="noopener">Discord</a>
            </div>
            <button class="dds-sm-btn dds-nosel" id="dds-back-btn" style="width:100%;background:rgba(var(--dds-surface),.95);outline:2px solid rgba(var(--dds-border),.35);outline-offset:-2px;">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="rgba(var(--dds-text2),.75)" stroke-width="2.5">
                    <path d="M19 12H5M12 19l-7-7 7-7"/>
                </svg>
                <span class="dds-sm-lbl" style="color:rgba(var(--dds-text2),.75);">Back</span>
            </button>
            <div class="dds-row" style="align-self:stretch;padding-top:2px;">
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">duods.vercel.app</p>
                <p class="dds-t2 dds-nosel" style="color:rgba(var(--dds-blue),.50);">v${SCRIPT_VERSION}</p>
            </div>
        </div>

    </div>
</div>
`;
document.body.appendChild(_root);

_watchTheme();

function _clearTierFxDOM() {
    const box = document.getElementById('dds-box');
    if (!box) return;
    box.querySelectorAll('.dds-tier-canvas').forEach(c => {
        if (c._stop) c._stop();
        c.remove();
    });
    if (_sparkleInterval) { clearInterval(_sparkleInterval); _sparkleInterval = null; }
    if (_glitchTimer)     { clearInterval(_glitchTimer);     _glitchTimer     = null; }
}

function _injectEventDOM() {
    const box = document.getElementById('dds-box');
    if (!box) return;
    _clearTierFxDOM();

    const canvas = document.createElement('canvas');
    canvas.className = 'dds-tier-canvas';
    box.insertBefore(canvas, box.firstChild);

    let w, h;
    const resize = () => { w = canvas.width = box.offsetWidth; h = canvas.height = box.offsetHeight; };
    resize();

    const ctx = canvas.getContext('2d');
    const particles = [];
    let lastSpawn = 0;
    let rafId;

    const TYPES = ['dot', 'star4', 'diamond', 'flare', 'ring'];

    function _drawStar4(x, y, r, rot) {
        ctx.beginPath();
        for (let i = 0; i < 8; i++) {
            const angle = (i * Math.PI) / 4 + rot;
            const radius = i % 2 === 0 ? r : r * 0.38;
            const px = x + radius * Math.cos(angle);
            const py = y + radius * Math.sin(angle);
            i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
        }
        ctx.closePath();
    }

    function spawn(count) {
        for (let n = 0; n < count; n++) {
            const type = TYPES[Math.floor(Math.random() * TYPES.length)];
            const r    = 2.5 + Math.random() * 4;
            particles.push({
                x:       12 + Math.random() * (w - 24),
                y:       h + 6,
                vx:      (Math.random() - 0.5) * 0.55,
                vy:      -(0.45 + Math.random() * 1.1),
                r,
                a:       0,
                peak:    0.38 + Math.random() * 0.48,
                life:    0,
                maxLife: 110 + Math.random() * 90,
                type,
                hue:     28 + Math.random() * 28,
                phase:   Math.random() * Math.PI * 2,
                rot:     Math.random() * Math.PI * 2,
                rotSpd:  (Math.random() - 0.5) * 0.04,
            });
        }
    }

    function frame(ts) {
        ctx.clearRect(0, 0, w, h);

        if (ts - lastSpawn > 480) {
            spawn(Math.random() < 0.35 ? 2 : 1);
            lastSpawn = ts;
        }

        for (let i = particles.length - 1; i >= 0; i--) {
            const p = particles[i];
            p.life++;
            p.rot += p.rotSpd;

            const t = p.life / p.maxLife;
            p.a = t < 0.14 ? p.peak * (t / 0.14) : p.peak * (1 - (t - 0.14) / 0.86);
            if (p.a < 0) { particles.splice(i, 1); continue; }

            p.x += p.vx + Math.sin(p.phase + p.life * 0.038) * 0.28;
            p.y += p.vy;

            if (p.y < -12) { particles.splice(i, 1); continue; }

            const col = `hsl(${p.hue}, 100%, 64%)`;
            ctx.globalAlpha = p.a;
            ctx.fillStyle   = col;
            ctx.shadowBlur  = p.type === 'flare' ? 12 : 7;
            ctx.shadowColor = col;

            if (p.type === 'dot') {
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
                ctx.fill();
            } else if (p.type === 'star4') {
                _drawStar4(p.x, p.y, p.r * 1.6, p.rot);
                ctx.fill();
            } else if (p.type === 'diamond') {
                ctx.save();
                ctx.translate(p.x, p.y);
                ctx.rotate(p.rot);
                ctx.beginPath();
                ctx.moveTo(0, -p.r * 1.5);
                ctx.lineTo(p.r, 0);
                ctx.lineTo(0, p.r * 1.5);
                ctx.lineTo(-p.r, 0);
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            } else if (p.type === 'flare') {
                ctx.save();
                ctx.translate(p.x, p.y);
                ctx.rotate(p.rot);
                ctx.fillRect(-p.r * 0.22, -p.r * 2.2, p.r * 0.44, p.r * 4.4);
                ctx.fillRect(-p.r * 2.2, -p.r * 0.22, p.r * 4.4, p.r * 0.44);
                ctx.restore();
            } else if (p.type === 'ring') {
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.r * 1.4, 0, Math.PI * 2);
                ctx.strokeStyle = col;
                ctx.lineWidth   = 1.2;
                ctx.stroke();
            }
        }

        ctx.globalAlpha = 1;
        ctx.shadowBlur  = 0;
        rafId = requestAnimationFrame(frame);
    }

    rafId = requestAnimationFrame(frame);
    canvas._stop = () => cancelAnimationFrame(rafId);
}

function _injectAdminDOM() {
    const box = document.getElementById('dds-box');
    if (!box) return;
    _clearTierFxDOM();

    const canvas = document.createElement('canvas');
    canvas.className = 'dds-tier-canvas';
    box.insertBefore(canvas, box.firstChild);

    let w, h;
    const resize = () => { w = canvas.width = box.offsetWidth; h = canvas.height = box.offsetHeight; };
    resize();

    const ctx = canvas.getContext('2d');
    let rafId;
    let scanY    = -20;
    let ts0      = 0;
    const packets = [];
    let lastPacket = 0;

    function drawHex(alpha) {
        const sz = 16;
        const dx = sz * 1.732;
        const dy = sz * 1.5;
        ctx.strokeStyle = `rgba(100,115,255,${alpha})`;
        ctx.lineWidth   = 0.6;
        for (let row = -1; row < (h / dy) + 2; row++) {
            for (let col = -1; col < (w / dx) + 2; col++) {
                const x = col * dx + (row % 2 === 0 ? 0 : dx / 2);
                const y = row * dy;
                ctx.beginPath();
                for (let k = 0; k < 6; k++) {
                    const ang = (Math.PI / 3) * k - Math.PI / 6;
                    const px  = x + sz * Math.cos(ang);
                    const py  = y + sz * Math.sin(ang);
                    k === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
                }
                ctx.closePath();
                ctx.stroke();
            }
        }
    }

    function drawCorners(alpha) {
        const L = 20;
        ctx.strokeStyle = `rgba(0,212,255,${alpha})`;
        ctx.lineWidth   = 1.8;
        ctx.lineCap     = 'square';
        ctx.shadowBlur  = 6;
        ctx.shadowColor = `rgba(0,212,255,${alpha})`;
        const P = 10;
        ctx.beginPath(); ctx.moveTo(P + L, P); ctx.lineTo(P, P); ctx.lineTo(P, P + L); ctx.stroke();
        ctx.beginPath(); ctx.moveTo(w - P - L, P); ctx.lineTo(w - P, P); ctx.lineTo(w - P, P + L); ctx.stroke();
        ctx.beginPath(); ctx.moveTo(P + L, h - P); ctx.lineTo(P, h - P); ctx.lineTo(P, h - P - L); ctx.stroke();
        ctx.beginPath(); ctx.moveTo(w - P - L, h - P); ctx.lineTo(w - P, h - P); ctx.lineTo(w - P, h - P - L); ctx.stroke();
        ctx.shadowBlur = 0;
    }

    function spawnPacket() {
        const horiz = Math.random() < 0.5;
        packets.push({
            x:       horiz ? -4 : (Math.floor(Math.random() * 14) * (w / 14)),
            y:       horiz ? (Math.floor(Math.random() * 10) * (h / 10)) : -4,
            vx:      horiz ? 1.2 + Math.random() * 0.8 : 0,
            vy:      horiz ? 0 : 1.2 + Math.random() * 0.8,
            a:       0.6 + Math.random() * 0.3,
            size:    2 + Math.random() * 2,
            color:   Math.random() < 0.5 ? '100,115,255' : '0,212,255',
        });
    }

    function frame(ts) {
        if (!ts0) ts0 = ts;
        const elapsed = ts - ts0;

        ctx.clearRect(0, 0, w, h);

        drawHex(0.022 + 0.012 * Math.sin(elapsed * 0.0015));

        if (ts - lastPacket > 700 + Math.random() * 600) {
            spawnPacket();
            lastPacket = ts;
        }
        for (let i = packets.length - 1; i >= 0; i--) {
            const p = packets[i];
            p.x += p.vx;
            p.y += p.vy;
            if (p.x > w + 8 || p.y > h + 8) { packets.splice(i, 1); continue; }
            ctx.globalAlpha = p.a;
            ctx.fillStyle   = `rgb(${p.color})`;
            ctx.shadowBlur  = 5;
            ctx.shadowColor = `rgba(${p.color},.80)`;
            ctx.fillRect(p.x - p.size / 2, p.y - p.size / 2, p.size, p.size);
        }
        ctx.globalAlpha = 1;
        ctx.shadowBlur  = 0;

        scanY += 0.9;
        if (scanY > h + 24) scanY = -24;
        const beam = ctx.createLinearGradient(0, scanY - 18, 0, scanY + 18);
        beam.addColorStop(0,   'rgba(0,212,255,0)');
        beam.addColorStop(0.5, 'rgba(0,212,255,0.07)');
        beam.addColorStop(1,   'rgba(0,212,255,0)');
        ctx.fillStyle = beam;
        ctx.fillRect(0, scanY - 18, w, 36);

        const lineG = ctx.createLinearGradient(0, 0, w, 0);
        lineG.addColorStop(0,    'rgba(0,212,255,0)');
        lineG.addColorStop(0.15, 'rgba(0,212,255,.40)');
        lineG.addColorStop(0.5,  'rgba(100,115,255,.70)');
        lineG.addColorStop(0.85, 'rgba(0,212,255,.40)');
        lineG.addColorStop(1,    'rgba(0,212,255,0)');
        ctx.beginPath();
        ctx.moveTo(0, scanY);
        ctx.lineTo(w, scanY);
        ctx.strokeStyle = lineG;
        ctx.lineWidth   = 1.2;
        ctx.stroke();

        const ca = 0.38 + 0.28 * Math.sin(elapsed * 0.003);
        drawCorners(ca);

        rafId = requestAnimationFrame(frame);
    }

    rafId = requestAnimationFrame(frame);
    canvas._stop = () => cancelAnimationFrame(rafId);

    _startAdminGlitch();
}

function _startAdminGlitch() {
    if (_glitchTimer) clearInterval(_glitchTimer);
    const CHARS = '0123456789ABCDEF◆◇▲';
    _glitchTimer = setInterval(() => {
        if (_currentType !== 'admin') { clearInterval(_glitchTimer); _glitchTimer = null; return; }
        const el = document.getElementById('dds-key-disp');
        if (!el) return;
        const orig  = el.textContent;
        let   count = 0;
        const gi = setInterval(() => {
            el.textContent = orig.split('').map(c =>
                c !== ' ' && c !== '.' && c !== '-' && Math.random() < 0.38
                    ? CHARS[Math.floor(Math.random() * CHARS.length)]
                    : c
            ).join('');
            if (++count > 5) { clearInterval(gi); el.textContent = orig; }
        }, 38);
    }, 5500 + Math.random() * 4500);
}

function _ripple(btn) {
    btn.classList.remove('rippling');
    void btn.offsetWidth;
    btn.classList.add('rippling');
    setTimeout(() => btn.classList.remove('rippling'), 560);
}

function _notify(title, body, dur = 5) {
    const box = document.getElementById('dds-ntf-box');
    document.getElementById('dds-ntf-title').textContent = title;
    document.getElementById('dds-ntf-body').textContent  = body;
    box.classList.add('show');
    clearTimeout(_ntTimer);
    _ntTimer = setTimeout(() => box.classList.remove('show'), dur * 1000);
}

function _toggleVis(hide) {
    if (_animLock) return;
    _animLock = true;
    _hidden   = hide;

    const shell = document.getElementById('dds-shell');
    const box   = document.getElementById('dds-box');
    const icoE  = document.getElementById('dds-ico-eye');
    const icoH  = document.getElementById('dds-ico-eyeoff');
    const icoW  = document.getElementById('dds-ico-wrap');
    const txt   = document.getElementById('dds-toggle-txt');
    const btn   = document.getElementById('dds-toggle');
    const h     = box.offsetHeight;

    shell.style.transition = box.style.transition = '.8s cubic-bezier(.16,1,.32,1)';

    if (hide) {
        btn.style.background = 'rgba(var(--dds-card),.95)';
        btn.style.outline    = '2px solid rgba(var(--dds-blue),.25)';
        if (icoW) icoW.style.background = 'rgba(var(--dds-blue),.16)';
        if (icoE) icoE.style.display    = 'none';
        if (icoH) icoH.style.display    = '';
        txt.textContent      = 'Show';
        txt.style.color      = 'rgb(var(--dds-blue))';
        shell.style.bottom   = `-${h - 8}px`;
        box.style.filter     = 'blur(8px)';
        box.style.opacity    = '0';
    } else {
        btn.style.background = 'rgb(var(--dds-blue))';
        btn.style.outline    = '2px solid rgba(0,0,0,.18)';
        if (icoW) icoW.style.background = 'rgba(255,255,255,.20)';
        if (icoH) icoH.style.display    = 'none';
        if (icoE) icoE.style.display    = '';
        txt.textContent      = 'Hide';
        txt.style.color      = '#fff';
        shell.style.bottom   = '16px';
        box.style.filter     = '';
        box.style.opacity    = '';
    }

    setTimeout(() => {
        shell.style.transition = '';
        box.style.transition   = '';
        _animLock = false;
    }, 800);
}

document.getElementById('dds-toggle').addEventListener('click', () => _toggleVis(!_hidden));

function _goPage(to) {
    if (_pgLock || _curPg === to) return;
    _pgLock = true;

    const box    = document.getElementById('dds-box');
    const fromEl = document.getElementById(`dds-page-${_curPg}`);
    const toEl   = document.getElementById(`dds-page-${to}`);
    if (!fromEl || !toEl) { _pgLock = false; return; }

    const oldH = box.offsetHeight;
    fromEl.style.display = 'none';
    toEl.classList.add('active');
    toEl.style.opacity = '0';
    const newH = box.offsetHeight;
    toEl.classList.remove('active');
    toEl.style.opacity = '';
    fromEl.style.display = '';

    box.style.height     = oldH + 'px';
    box.style.transition = 'height .6s cubic-bezier(.34,1.56,.64,1)';

    fromEl.style.transition = 'opacity .35s, filter .35s, transform .35s';
    fromEl.style.opacity    = '0';
    fromEl.style.filter     = 'blur(6px)';
    fromEl.style.transform  = 'scale(.96)';

    requestAnimationFrame(() => { box.style.height = newH + 'px'; });

    setTimeout(() => {
        fromEl.classList.remove('active');
        fromEl.style.cssText = '';
        toEl.classList.add('active');
        toEl.style.opacity   = '0';
        toEl.style.filter    = 'blur(6px)';
        toEl.style.transform = 'scale(1.04)';
        void toEl.offsetWidth;
        toEl.style.transition = 'opacity .4s, filter .4s, transform .5s cubic-bezier(.34,1.56,.64,1)';
        toEl.style.opacity    = '1';
        toEl.style.filter     = 'blur(0)';
        toEl.style.transform  = 'scale(1)';
        _curPg = to;
        setTimeout(() => {
            box.style.height     = '';
            box.style.transition = '';
            toEl.style.cssText   = '';
            _pgLock = false;
        }, 400);
    }, 380);
}

document.querySelectorAll('#DDS_Root .dds-tab').forEach(btn => {
    btn.addEventListener('click', () => {
        document.querySelectorAll('#DDS_Root .dds-tab').forEach(b => b.classList.remove('on'));
        btn.classList.add('on');
        _applyTabTier(btn);
        ['link', 'active', 'hist'].forEach(t => {
            const el = document.getElementById(`dds-pane-${t}`);
            if (el) el.classList.toggle('active', btn.dataset.tab === t);
        });
    });
});

function _applyTabTier(activeTab) {
    document.querySelectorAll('#DDS_Root .dds-tab').forEach(t => t.classList.remove('tab-event', 'tab-admin'));
    if (!activeTab) return;
    if (_currentType === 'event') activeTab.classList.add('tab-event');
    if (_currentType === 'admin') activeTab.classList.add('tab-admin');
}

function _log(id, msg, type = 'i') {
    const el = document.getElementById(id);
    if (!el) return;
    const ts  = _tsGMT7();
    const cls = { o: 'lo', e: 'le', i: 'li', w: 'lw' }[type] || 'li';
    el.innerHTML += `<span class="${cls}">[${ts}] ${msg}</span>\n`;
    el.scrollTop  = el.scrollHeight;
}
function _logClear(id) {
    const el = document.getElementById(id);
    if (el) el.innerHTML = '';
}

const C_BLUE  = { bg: 'rgb(var(--dds-blue))',        out: 'rgba(0,0,0,.18)',              tc: '#fff' };
const C_GREEN = { bg: 'rgba(var(--dds-green),.12)',   out: 'rgba(var(--dds-green),.28)',   tc: 'rgb(var(--dds-green))' };
const C_GRAY  = { bg: 'rgba(var(--dds-surface),.95)', out: 'rgba(var(--dds-border),.40)',  tc: 'rgba(var(--dds-text2),.80)' };

function _setLoading(btnId, icoId, on) {
    const ico = document.getElementById(icoId);
    if (!ico) return;
    if (on) {
        ico.innerHTML = `<div class="dds-spin-ring"></div>`;
    } else {
        const svgMap = {
            'dds-create-ico':   `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`,
            'dds-activate-ico': `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg>`,
            'dds-loadhist-ico': `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.68"/></svg>`
        };
        if (svgMap[icoId]) ico.innerHTML = svgMap[icoId];
    }
}

function _btnState(id, clr, text, icoId) {
    const btn = document.getElementById(id);
    if (!btn) return;
    const lbl = btn.querySelector('.dds-lbl') || btn.querySelector('.dds-sm-lbl');
    if (!lbl) return;

    const prev = lbl.textContent;
    lbl.textContent = text;
    const nw = btn.offsetWidth;
    lbl.textContent = prev;
    btn.style.width = btn.offsetWidth + 'px';

    requestAnimationFrame(() => {
        lbl.style.opacity       = '0';
        lbl.style.filter        = 'blur(4px)';
        btn.style.width         = nw + 'px';
        btn.style.background    = clr.bg;
        btn.style.outline       = `solid 2px ${clr.out}`;
        btn.style.outlineOffset = '-2px';
        if (icoId) {
            const icoEl = document.getElementById(icoId);
            if (icoEl) icoEl.style.background = clr.tc === '#fff' ? 'rgba(255,255,255,.20)' : 'rgba(0,0,0,.06)';
        }
    });

    setTimeout(() => {
        lbl.style.transition = '0s';
        lbl.style.color      = clr.tc;
        void lbl.offsetWidth;
        lbl.style.transition = '.35s';
        lbl.textContent      = text;
        requestAnimationFrame(() => { lbl.style.opacity = '1'; lbl.style.filter = 'blur(0)'; });
        setTimeout(() => { btn.style.width = ''; }, 400);
    }, 380);
}

function _refreshQuota(used, limit) {
    const pct   = limit > 0 ? Math.min((used / limit) * 100, 100) : 0;
    const fill  = document.getElementById('dds-quota-fill');
    const track = document.getElementById('dds-quota-track');
    const val   = document.getElementById('dds-quota-val');
    const wrap  = document.getElementById('dds-quota-wrap');

    if (fill) {
        fill.style.width = pct + '%';
        fill.classList.remove('warn', 'tf-event', 'tf-admin');
        if (_currentType === 'event')      fill.classList.add('tf-event');
        else if (_currentType === 'admin') fill.classList.add('tf-admin');
        else fill.classList.toggle('warn', pct > 85);
    }
    if (track) {
        track.classList.remove('tr-event', 'tr-admin');
        if (_currentType === 'event')      track.classList.add('tr-event');
        else if (_currentType === 'admin') track.classList.add('tr-admin');
    }
    if (val) {
        val.textContent = `${used} / ${limit}`;
        val.classList.remove('qv-event', 'qv-admin');
        if (_currentType === 'event')      val.classList.add('qv-event');
        else if (_currentType === 'admin') val.classList.add('qv-admin');
    }
    if (wrap) {
        wrap.classList.remove('tier-event', 'tier-admin');
        if (_currentType === 'event')      wrap.classList.add('tier-event');
        else if (_currentType === 'admin') wrap.classList.add('tier-admin');
    }
}

function _saveCD(sec) {
    if (sec > 0) _set(CD_STORE, Date.now() + sec * 1000);
}

function _loadCD() {
    const exp = _get(CD_STORE, 0);
    if (!exp) return 0;
    const rem = Math.ceil((exp - Date.now()) / 1000);
    return rem > 0 ? rem : 0;
}

function _startCD(sec, save = true) {
    if (_cdTimer) clearInterval(_cdTimer);
    let rem = Math.ceil(sec);
    if (save) _saveCD(rem);

    const cdEl   = document.getElementById('dds-cd');
    const cdTx   = document.getElementById('dds-cd-time');
    const cBtn   = document.getElementById('dds-create-btn');
    const cdInfo = document.getElementById('dds-cd-info');

    if (cdEl) cdEl.classList.add('on');
    if (cBtn) cBtn.disabled = true;
    if (cdInfo) {
        if (_currentType === 'free') cdInfo.classList.add('on');
        else cdInfo.classList.remove('on');
    }

    function tick() {
        if (rem <= 0) {
            clearInterval(_cdTimer);
            if (cdEl)   cdEl.classList.remove('on');
            if (cBtn)   cBtn.disabled = false;
            if (cdInfo) cdInfo.classList.remove('on');
            return;
        }
        const mm = String(Math.floor(rem / 60)).padStart(2, '0');
        const ss = String(rem % 60).padStart(2, '0');
        if (cdTx) cdTx.textContent = `${mm}:${ss}`;
        rem--;
    }
    tick();
    _cdTimer = setInterval(tick, 1000);
}

function _startExpireCountdown(seconds) {
    if (_expireTimer) clearInterval(_expireTimer);
    const banner = document.getElementById('dds-expiry-banner');
    const txt    = document.getElementById('dds-expiry-txt');
    if (!banner || !txt) return;

    let rem = Math.ceil(seconds);
    if (rem <= 0) { banner.classList.remove('on'); return; }
    if (rem > 3600) { banner.classList.remove('on'); return; }

    banner.classList.add('on');

    function tick() {
        if (rem <= 0) {
            clearInterval(_expireTimer);
            banner.classList.remove('on');
            _onKeyExpired();
            return;
        }
        const hh = Math.floor(rem / 3600);
        const mm = String(Math.floor((rem % 3600) / 60)).padStart(2, '0');
        const ss = String(rem % 60).padStart(2, '0');
        txt.textContent = hh > 0 ? `Key expires in ${hh}:${mm}:${ss}` : `Key expires in ${mm}:${ss}`;
        rem--;
    }
    tick();
    _expireTimer = setInterval(tick, 1000);
}

function _onKeyExpired() {
    if (_pollTimer)  { clearInterval(_pollTimer);  _pollTimer  = null; }
    if (_cdTimer)    { clearInterval(_cdTimer);    _cdTimer    = null; }
    if (_expireTimer){ clearInterval(_expireTimer); _expireTimer = null; }
    _sess        = null;
    _keyData     = null;
    _currentType = 'free';
    _set('dds_key', '');
    _clearTierFxDOM();
    _notify('Key Expired', 'Your key has expired. Switched back to free key.', 7);
    _fetchKey(FREE_KEY).then(r => {
        if (r.ok && _sess) {
            _set('dds_key', FREE_KEY);
            _applyKey(r, FREE_KEY);
            _goPage('dash');
            _startPoll(FREE_KEY);
        } else {
            _sess = null;
            _goPage('auth');
        }
    });
}

function _tierLabel(type) {
    const map = { free: 'FREE', paid: 'PAID', event: '✦', admin: '⬡' };
    return map[type] || type.toUpperCase();
}

function _applyTierFx(newType, oldType) {
    const box       = document.getElementById('dds-box');
    const badge     = document.getElementById('dds-badge');
    const tag       = document.getElementById('dds-tier-tag');
    const keyD      = document.getElementById('dds-key-disp');
    const footerD   = document.getElementById('dds-footer-discord');
    const footerV   = document.getElementById('dds-footer-ver');
    const createBtn = document.getElementById('dds-create-btn');

    if (!box || !badge || !tag) return;

    box.classList.remove('tier-event', 'tier-admin');
    badge.classList.remove('tier-event', 'tier-admin');
    tag.classList.remove('tag-free', 'tag-paid', 'tag-event', 'tag-admin');
    if (keyD)      keyD.classList.remove('key-event', 'key-admin');
    if (footerD)   footerD.classList.remove('dds-footer-event', 'dds-footer-admin');
    if (footerV)   footerV.classList.remove('dds-footer-event', 'dds-footer-admin');
    if (createBtn) createBtn.classList.remove('dds-create-btn-event', 'dds-create-btn-admin');

    tag.textContent   = _tierLabel(newType);
    tag.style.display = '';
    tag.classList.add(`tag-${newType}`);

    _clearTierFxDOM();

    if (newType === 'event') {
        box.classList.add('tier-event');
        badge.classList.add('tier-event');
        if (keyD)      keyD.classList.add('key-event');
        if (footerD)   footerD.classList.add('dds-footer-event');
        if (footerV)   footerV.classList.add('dds-footer-event');
        if (createBtn) createBtn.classList.add('dds-create-btn-event');
        _injectEventDOM();
    }
    if (newType === 'admin') {
        box.classList.add('tier-admin');
        badge.classList.add('tier-admin');
        if (keyD)      keyD.classList.add('key-admin');
        if (footerD)   footerD.classList.add('dds-footer-admin');
        if (footerV)   footerV.classList.add('dds-footer-admin');
        if (createBtn) createBtn.classList.add('dds-create-btn-admin');
        _injectAdminDOM();
    }

    const activeTab = document.querySelector('#DDS_Root .dds-tab.on');
    _applyTabTier(activeTab);

    if (!_fxActive && oldType && oldType !== newType) {
        if (newType === 'event') _fxBurst();
        if (newType === 'admin') _fxMatrix();
    }
}

function _fxBurst() {
    const canvas = document.getElementById('dds-fx-canvas');
    if (!canvas) return;
    _fxActive    = true;
    canvas.classList.add('on');
    canvas.width  = window.innerWidth;
    canvas.height = window.innerHeight;
    const ctx = canvas.getContext('2d');
    const particles = [];

    for (let i = 0; i < 110; i++) {
        const angle = Math.random() * Math.PI * 2;
        const speed = 2.5 + Math.random() * 6.5;
        particles.push({
            x:      canvas.width / 2, y: canvas.height / 2,
            vx:     Math.cos(angle) * speed, vy: Math.sin(angle) * speed,
            r:      3 + Math.random() * 5,
            a:      1,
            decay:  0.009 + Math.random() * 0.010,
            hue:    28 + Math.random() * 30,
            shape:  Math.random() < 0.5 ? 'circle' : 'star',
            rot:    Math.random() * Math.PI * 2,
            rotSpd: (Math.random() - 0.5) * 0.08,
        });
    }

    let frame;
    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        let alive = false;
        for (const p of particles) {
            if (p.a <= 0) continue;
            alive = true;
            p.rot += p.rotSpd;
            ctx.globalAlpha = p.a;
            const col = `hsl(${p.hue}, 100%, 62%)`;
            ctx.fillStyle   = col;
            ctx.shadowBlur  = 10;
            ctx.shadowColor = col;
            if (p.shape === 'circle') {
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
                ctx.fill();
            } else {
                ctx.save();
                ctx.translate(p.x, p.y);
                ctx.rotate(p.rot);
                ctx.beginPath();
                for (let i = 0; i < 8; i++) {
                    const ang = (i * Math.PI) / 4;
                    const r   = i % 2 === 0 ? p.r * 1.5 : p.r * 0.55;
                    const px  = r * Math.cos(ang);
                    const py  = r * Math.sin(ang);
                    i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
                }
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            }
            ctx.globalAlpha = 1;
            ctx.shadowBlur  = 0;
            p.x += p.vx; p.y += p.vy; p.vy += 0.07; p.a -= p.decay;
        }
        if (alive) { frame = requestAnimationFrame(draw); }
        else { ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.classList.remove('on'); _fxActive = false; }
    }
    draw();
    setTimeout(() => { cancelAnimationFrame(frame); ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.classList.remove('on'); _fxActive = false; }, 4500);
}

function _fxMatrix() {
    const canvas = document.getElementById('dds-fx-canvas');
    if (!canvas) return;
    _fxActive    = true;
    canvas.classList.add('on');
    canvas.width  = window.innerWidth;
    canvas.height = window.innerHeight;
    const ctx   = canvas.getContext('2d');
    const cols   = Math.floor(canvas.width / 16);
    const drops  = Array(cols).fill(0);
    const chars  = 'アイウエオカキクケコサシスセソタチツテトナニヌネノ0123456789ADMINROOTACCESS◆◇▲△★☆⬡⬢';
    let frames   = 0;
    let frame;
    function draw() {
        ctx.fillStyle = 'rgba(0,0,0,0.06)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        for (let i = 0; i < drops.length; i++) {
            const ch     = chars[Math.floor(Math.random() * chars.length)];
            const bright = Math.random() > 0.88;
            ctx.fillStyle = bright
                ? 'rgba(200,225,255,0.95)'
                : `rgba(100,115,255,${0.50 + Math.random() * 0.40})`;
            ctx.font      = bright ? 'bold 14px monospace' : '13px monospace';
            ctx.fillText(ch, i * 16, drops[i] * 16);
            if (drops[i] * 16 > canvas.height && Math.random() > 0.975) drops[i] = 0;
            drops[i]++;
        }
        frames++;
        if (frames < 210) { frame = requestAnimationFrame(draw); }
        else { ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.classList.remove('on'); _fxActive = false; }
    }
    draw();
    setTimeout(() => { cancelAnimationFrame(frame); ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.classList.remove('on'); _fxActive = false; }, 5000);
}

function _applyKey(data, key) {
    const oldType = _currentType;
    _keyData      = data;
    _currentType  = data.key_type || 'paid';

    const disp   = document.getElementById('dds-key-disp');
    const meta   = document.getElementById('dds-key-meta');
    const batchN = document.getElementById('dds-batch-n');

    if (disp) disp.textContent = key.slice(0, 16) + '...';

    let expStr = '';
    if (data.expires_in_seconds != null) {
        const h = Math.floor(data.expires_in_seconds / 3600);
        const m = Math.floor((data.expires_in_seconds % 3600) / 60);
        expStr  = ` · Exp: ${h}h${m}m`;
        _startExpireCountdown(data.expires_in_seconds);
    } else {
        const banner = document.getElementById('dds-expiry-banner');
        if (banner) banner.classList.remove('on');
        if (_expireTimer) { clearInterval(_expireTimer); _expireTimer = null; }
    }

    if (meta)   meta.textContent   = `Batch: ${data.batch_size} · CD: ${data.cd_seconds}s · Uses: ${data.used_total}/${data.total_limit}${expStr}`;
    if (batchN) batchN.textContent = data.batch_size;

    _refreshQuota(data.used_today || 0, data.daily_limit);
    _applyTierFx(_currentType, oldType);

    const cdRemain = data.cooldown_remain && data.cooldown_remain > 0
        ? data.cooldown_remain : _loadCD();
    if (cdRemain > 0) _startCD(cdRemain, false);
}

function _startPoll(key) {
    if (_pollTimer) clearInterval(_pollTimer);
    _pollTimer = setInterval(async () => {
        if (!_sess) return;
        const r = await _fetchKey(key);
        if (!r.ok) return;

        if (r.in_use) {
            clearInterval(_pollTimer); _pollTimer = null;
            _sess = null;
            _goPage('blocked');
            _notify('Key In Use', 'This key is being used by another session.', 8);
            return;
        }

        if (r.expires_in_seconds != null && r.expires_in_seconds <= 0) {
            clearInterval(_pollTimer); _pollTimer = null;
            _onKeyExpired();
            return;
        }

        const savedKey = _get('dds_key', '');

        if (savedKey === FREE_KEY && r.key_type === 'event' && r.event_key) {
            _set('dds_key', r.event_key);
            _sess = null;
            const ev = await _fetchKey(r.event_key);
            if (ev.ok && _sess) {
                _applyKey(ev, r.event_key);
                _notify('Key Upgraded to EVENT', 'Your free key has been upgraded to EVENT tier!', 6);
            }
            return;
        }

        if (r.key_type !== _currentType) {
            _applyKey(r, savedKey || key);
            _notify('Key Updated', `New tier: ${_tierLabel(r.key_type)}`, 5);
        } else {
            if (r.expires_in_seconds != null) _startExpireCountdown(r.expires_in_seconds);
        }
    }, POLL_INTERVAL);
}

async function _unlock(key, errId, spinId, btnId, lblId) {
    const errEl = document.getElementById(errId);
    const spin  = document.getElementById(spinId);
    const btn   = document.getElementById(btnId);
    const lbl   = lblId ? document.getElementById(lblId) : null;

    if (!key) return;

    _sess = null;

    if (btn) { btn.disabled = true; if (btn.classList.contains('dds-ripple-btn')) _ripple(btn); }
    if (errEl) errEl.textContent = '';
    if (spin)  spin.style.display = 'flex';
    if (lbl)  { lbl.style.opacity = '0'; lbl.style.filter = 'blur(3px)'; }

    const r = await _fetchKey(key);

    if (btn)  btn.disabled = false;
    if (spin) spin.style.display = 'none';
    if (lbl) {
        setTimeout(() => { lbl.style.transition = '.35s'; lbl.style.opacity = '1'; lbl.style.filter = 'blur(0)'; }, 80);
    }

    if (r.in_use) {
        _sess = null;
        if (errEl) errEl.textContent = 'Key in use by another session. Please use a different key.';
        return;
    }

    if (r.ok && _sess) {
        if (_pollTimer) { clearInterval(_pollTimer); _pollTimer = null; }
        _set('dds_key', key);
        _applyKey(r, key);
        _goPage('dash');
        _startPoll(key);
        _notify('Unlocked', `Welcome, ${r.label || 'user'}!`);
    } else {
        _sess = null;
        if (errEl) errEl.textContent = 'Invalid key: ' + (r.error || 'Unknown error');
    }
}

document.getElementById('dds-unlock-btn').addEventListener('click', () => {
    _unlock(document.getElementById('dds-key-in').value.trim(), 'dds-auth-err', 'dds-auth-spin', 'dds-unlock-btn', 'dds-unlock-lbl');
});
document.getElementById('dds-key-in').addEventListener('keydown', e => {
    if (e.key === 'Enter') _unlock(document.getElementById('dds-key-in').value.trim(), 'dds-auth-err', 'dds-auth-spin', 'dds-unlock-btn', 'dds-unlock-lbl');
});
document.getElementById('dds-free-btn').addEventListener('click', () => {
    _unlock(FREE_KEY, 'dds-auth-err', 'dds-auth-spin', 'dds-free-btn', null);
});
document.getElementById('dds-chkey-btn').addEventListener('click', () => {
    document.getElementById('dds-newkey-in').value   = '';
    document.getElementById('dds-chkey-err').textContent = '';
    _goPage('chkey');
});
document.getElementById('dds-back-btn').addEventListener('click', () => { _goPage('dash'); });
document.getElementById('dds-newkey-btn').addEventListener('click', () => {
    _unlock(document.getElementById('dds-newkey-in').value.trim(), 'dds-chkey-err', 'dds-chkey-spin', 'dds-newkey-btn', 'dds-newkey-lbl');
});
document.getElementById('dds-newkey-in').addEventListener('keydown', e => {
    if (e.key === 'Enter') _unlock(document.getElementById('dds-newkey-in').value.trim(), 'dds-chkey-err', 'dds-chkey-spin', 'dds-newkey-btn', 'dds-newkey-lbl');
});
document.getElementById('dds-activefree-btn').addEventListener('click', async () => {
    _sess = null;
    const cdSaved = _loadCD();
    if (_pollTimer) { clearInterval(_pollTimer); _pollTimer = null; }
    const r = await _fetchKey(FREE_KEY);
    if (r.ok && _sess) {
        _set('dds_key', FREE_KEY);
        _applyKey(r, FREE_KEY);
        if (cdSaved > 0) _startCD(cdSaved, false);
        _goPage('dash');
        _startPoll(FREE_KEY);
        _notify('Free Key Active', 'Now using the free public key.');
    } else {
        _sess = null;
        document.getElementById('dds-chkey-err').textContent = 'Could not activate free key. Try again.';
    }
});
document.getElementById('dds-blocked-chkey-btn').addEventListener('click', () => {
    _set('dds_key', '');
    _goPage('chkey');
});

document.getElementById('dds-create-btn').addEventListener('click', async () => {
    if (!_sess) return;
    const key = _get('dds_key', '');
    if (!key) return;

    const btn  = document.getElementById('dds-create-btn');
    const prog = document.getElementById('dds-create-prog');
    const fill = document.getElementById('dds-create-fill');

    _ripple(btn);
    btn.disabled = true;
    _setLoading('dds-create-btn', 'dds-create-ico', true);
    _btnState('dds-create-btn', C_GRAY, 'Working...', null);
    prog.classList.add('on');
    fill.style.width = '15%';
    _logClear('dds-log-link');
    _log('dds-log-link', `Creating ${_keyData?.batch_size || '?'} links in parallel...`, 'i');
    fill.style.width = '50%';

    const r = await _req('/api/link/create', 'POST', { key });
    fill.style.width = '100%';
    setTimeout(() => { prog.classList.remove('on'); }, 600);
    btn.disabled = false;
    _setLoading('dds-create-btn', 'dds-create-ico', false);

    const C_EVENT = { bg: 'linear-gradient(135deg,#ff8c00,#ffd700)', out: 'rgba(255,193,7,.45)', tc: '#fff' };
    const C_ADMIN = { bg: 'linear-gradient(135deg,#5555ee,#a020f0)', out: 'rgba(100,115,255,.45)', tc: '#fff' };
    const tierClr = _currentType === 'event' ? C_EVENT : _currentType === 'admin' ? C_ADMIN : null;

    if (r.ok && r.urls && r.urls.length > 0) {
        const doneClr = tierClr ? { bg: tierClr.bg, out: tierClr.out, tc: '#fff' } : C_GREEN;
        _btnState('dds-create-btn', doneClr, `Done (${r.count})`, 'dds-create-ico');
        _log('dds-log-link', `Created ${r.count} link${r.failed > 0 ? ` (${r.failed} failed)` : ''}`, 'o');
        r.urls.forEach((url, i) => { _log('dds-log-link', `#${i + 1}  ${url}`, 'o'); _hist.unshift(url); });
        if (_keyData) { _keyData.used_today = (_keyData.used_today || 0) + r.count; _refreshQuota(_keyData.used_today, _keyData.daily_limit); }
        if (_keyData?.cd_seconds) _startCD(_keyData.cd_seconds);
        setTimeout(() => _btnState('dds-create-btn', tierClr || C_BLUE, 'Create Link Batch', 'dds-create-ico'), 3000);
    } else {
        _btnState('dds-create-btn', tierClr || C_BLUE, 'Create Link Batch', 'dds-create-ico');
        const msg = r.error || 'Unknown error';
        _log('dds-log-link', `Error: ${msg}`, 'e');
        const cdM = msg.match(/Cooldown.*?(\d+):(\d+)/);
        if (cdM)                      _startCD(parseInt(cdM[1]) * 60 + parseInt(cdM[2]));
        else if (r.cooldown_remain > 0) _startCD(r.cooldown_remain);
    }
});

document.getElementById('dds-activate-btn').addEventListener('click', async () => {
    if (!_sess) return;

    const jwt = document.getElementById('dds-jwt-in').value.trim();
    if (!jwt) return _log('dds-log-active', 'Enter your JWT token!', 'e');
    if (!_hist.length) return _log('dds-log-active', 'No links in history! Create or load links first.', 'e');

    const code = _hist[0].split('/').pop();
    let uid = '';
    try {
        const seg = jwt.split('.')[1];
        const pad = seg + '='.repeat((4 - seg.length % 4) % 4);
        uid = String(JSON.parse(atob(pad)).sub || '');
    } catch { return _log('dds-log-active', 'Invalid JWT format!', 'e'); }
    if (!uid) return _log('dds-log-active', 'Could not extract UID from JWT.', 'e');

    const btn = document.getElementById('dds-activate-btn');
    _ripple(btn);
    btn.disabled = true;
    _setLoading('dds-activate-btn', 'dds-activate-ico', true);
    _btnState('dds-activate-btn', C_GRAY, 'Activating...', null);
    _log('dds-log-active', `UID: ${uid} · Code: ${code}`, 'i');

    const r = await _req('/api/active', 'POST', { jwt, duo_uid: uid, invite_code: code });
    btn.disabled = false;
    _setLoading('dds-activate-btn', 'dds-activate-ico', false);
    _btnState('dds-activate-btn', C_BLUE, 'Activate Super', 'dds-activate-ico');

    if (r.ok) {
        _log('dds-log-active', r.already_member ? 'Account already has Super Duolingo.' : 'Activated successfully! Open the app to verify.', 'o');
        _notify('Super Activated', 'Free Super Duolingo activated!');
    } else {
        _log('dds-log-active', `Error: ${r.error || 'Failed'}`, 'e');
    }
});

document.getElementById('dds-loadhist-btn').addEventListener('click', async () => {
    if (!_sess) return;
    const key = _get('dds_key', '');
    if (!key) return;

    const btn = document.getElementById('dds-loadhist-btn');
    _ripple(btn);
    btn.disabled = true;
    _setLoading('dds-loadhist-btn', 'dds-loadhist-ico', true);
    _btnState('dds-loadhist-btn', C_GRAY, 'Loading...', null);

    const r = await _req(`/api/link/list?key=${encodeURIComponent(key)}`, 'GET');
    btn.disabled = false;
    _setLoading('dds-loadhist-btn', 'dds-loadhist-ico', false);
    _btnState('dds-loadhist-btn', C_BLUE, 'Load history', 'dds-loadhist-ico');

    if (r.ok && r.links) {
        _hist = r.links;
        _renderHist();
        _notify('Loaded', `${r.links.length} links in history.`, 3);
    } else {
        document.getElementById('dds-hist-log').innerHTML = `<span class="le">Error: ${r.error || 'Unknown'}</span>`;
    }
});

function _renderHist() {
    const el = document.getElementById('dds-hist-log');
    el.innerHTML = '';
    if (!_hist.length) { el.innerHTML = '<span class="lw">No links yet.</span>'; return; }
    _hist.forEach((url, i) => {
        const code = url.split('/').pop();
        el.innerHTML +=
            `<span class="lo">#${String(i + 1).padStart(3, '0')} ${url}</span>` +
            `<span class="dds-copy-tag" data-url="${url}" data-code="${code}">copy</span>\n`;
    });
    el.querySelectorAll('.dds-copy-tag').forEach(tag => {
        tag.addEventListener('click', e => {
            e.stopPropagation();
            navigator.clipboard?.writeText(tag.dataset.url).catch(() => {});
            tag.textContent = 'ok ✓';
            setTimeout(() => { tag.textContent = 'copy'; }, 1200);
        });
    });
}

document.getElementById('dds-copyall-btn').addEventListener('click', () => {
    if (!_hist.length) return;
    navigator.clipboard?.writeText(_hist.join('\n')).catch(() => {});
    const lbl = document.getElementById('dds-copyall-btn').querySelector('.dds-sm-lbl');
    lbl.textContent = 'Copied!';
    setTimeout(() => { lbl.textContent = 'Copy all'; }, 1500);
});

(async function _boot() {
    const vr = await _checkVersion();
    if (vr && vr.ok && vr.current_version && vr.current_version !== SCRIPT_VERSION) {
        const msg = document.getElementById('dds-update-msg');
        if (msg) msg.textContent = `v${SCRIPT_VERSION} is outdated. Latest is v${vr.current_version}. Please update to continue.`;
        const btn = document.getElementById('dds-update-btn');
        if (btn && vr.update_url) btn.href = vr.update_url;

        const shell = document.getElementById('dds-shell');
        const box   = document.getElementById('dds-box');
        shell.style.bottom = `-${box.offsetHeight - 8}px`;
        box.style.opacity  = '0';
        box.style.filter   = 'blur(8px)';

        const fromEl = document.getElementById('dds-page-auth');
        if (fromEl) fromEl.classList.remove('active');
        const toEl = document.getElementById('dds-page-update');
        if (toEl) toEl.classList.add('active');
        _curPg = 'update';

        _toggleVis(false);
        setTimeout(() => {
            shell.style.transition = box.style.transition = '.8s cubic-bezier(.16,1,.32,1)';
            shell.style.bottom = '16px';
            box.style.opacity  = '';
            box.style.filter   = '';
            setTimeout(() => { shell.style.transition = ''; box.style.transition = ''; }, 800);
        }, 600);
        return;
    }

    const saved = _get('dds_key', '');
    const key   = saved || FREE_KEY;

    const shell = document.getElementById('dds-shell');
    const box   = document.getElementById('dds-box');
    shell.style.bottom = `-${box.offsetHeight - 8}px`;
    box.style.opacity  = '0';
    box.style.filter   = 'blur(8px)';

    _fetchKey(key).then(r => {
        if (r.in_use) {
            _set('dds_key', '');
            _goPage('blocked');
        } else if (r.ok && _sess) {
            if (r.expires_in_seconds != null && r.expires_in_seconds <= 0) {
                _set('dds_key', '');
                _fetchKey(FREE_KEY).then(fr => {
                    if (fr.ok && _sess) {
                        _set('dds_key', FREE_KEY);
                        _applyKey(fr, FREE_KEY);
                        _goPage('dash');
                        _startPoll(FREE_KEY);
                    } else {
                        _sess = null;
                        _goPage('auth');
                    }
                });
                return;
            }
            if (!saved) _set('dds_key', FREE_KEY);
            _applyKey(r, key);
            _goPage('dash');
            _startPoll(key);
        } else {
            _sess = null;
            if (key !== FREE_KEY) _set('dds_key', '');
            document.getElementById('dds-key-in').value = saved || '';
        }
    });

    _toggleVis(false);
    setTimeout(() => {
        shell.style.transition = box.style.transition = '.8s cubic-bezier(.16,1,.32,1)';
        shell.style.bottom = '16px';
        box.style.opacity  = '';
        box.style.filter   = '';
        setTimeout(() => { shell.style.transition = ''; box.style.transition = ''; }, 800);
    }, 600);
})();

})();