HAVEN OS - Browser Operating System

12-in-1 - Notes, Pomodoro, Currency, Clock, Matrix, Drawing, Calculator, Light, Space, Sound, Aquarium, Settings (EN/TR)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         HAVEN OS - Browser Operating System
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  12-in-1 - Notes, Pomodoro, Currency, Clock, Matrix, Drawing, Calculator, Light, Space, Sound, Aquarium, Settings (EN/TR)
// @author       Mustafa Hakan 
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_notification
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    const LANG = GM_getValue('h_lang', 'en'); // Default English
    const T = GM_getValue('h_theme','midnight');
    const U = GM_getValue('h_user','User');
    
    const TR_TEXT = {
        notes: '📝 Not Defteri',
        notesPlaceholder: 'Notunuzu yazın...',
        save: '💾 Kaydet',
        saved: 'Kaydedildi!',
        pomodoro: '🍅 Pomodoro',
        start: '▶ Başlat',
        pause: '⏸ Duraklat',
        reset: '↺ Sıfırla',
        workInfo: 'Çalışma: 25dk | Mola: 5dk',
        timeUp: 'Süre doldu!',
        currency: '💹 Canlı Döviz',
        currencyNote: '🔄 Canlı güncelleme simülasyonu',
        clock: '🕐 Saat & Hava',
        istanbul: 'İstanbul',
        partlyCloudy: 'Parçalı Bulutlu',
        matrix: '💚 Matrix',
        drawing: '🎨 Çizim Tahtası',
        calculator: '🔢 Hesap Makinesi',
        light: '💡 Işık Halkası',
        lightActive: '✨ İmleç ışık halkası aktif!\nPencereyi kapatınca söner.',
        space: '🌌 Uzay',
        sound: '🎧 Ses Manzarası',
        soundActive: 'Ortam sesi aktif',
        aquarium: '🐠 Akvaryum',
        settings: '⚙️ Ayarlar',
        theme: 'Tema',
        user: 'Kullanıcı',
        saveSettings: '💾 Kaydet',
        dollar: 'Dolar',
        euro: 'Euro',
        gold: 'Altın',
        bist: 'BIST',
        bitcoin: 'Bitcoin',
        error: 'Hata'
    };

    const EN_TEXT = {
        notes: '📝 Notes',
        notesPlaceholder: 'Write your note...',
        save: '💾 Save',
        saved: 'Saved!',
        pomodoro: '🍅 Pomodoro',
        start: '▶ Start',
        pause: '⏸ Pause',
        reset: '↺ Reset',
        workInfo: 'Work: 25min | Break: 5min',
        timeUp: 'Time is up!',
        currency: '💹 Live Currency',
        currencyNote: '🔄 Live update simulation',
        clock: '🕐 Clock & Weather',
        istanbul: 'Istanbul',
        partlyCloudy: 'Partly Cloudy',
        matrix: '💚 Matrix',
        drawing: '🎨 Drawing Board',
        calculator: '🔢 Calculator',
        light: '💡 Cursor Glow',
        lightActive: '✨ Cursor glow active!\nClose window to turn off.',
        space: '🌌 Space',
        sound: '🎧 Soundscape',
        soundActive: 'Ambient sound active',
        aquarium: '🐠 Aquarium',
        settings: '⚙️ Settings',
        theme: 'Theme',
        user: 'User',
        saveSettings: '💾 Save',
        dollar: 'Dollar',
        euro: 'Euro',
        gold: 'Gold',
        bist: 'BIST',
        bitcoin: 'Bitcoin',
        error: 'Error'
    };

    const TXT = LANG === 'tr' ? TR_TEXT : EN_TEXT;

    const TH = {
        midnight:{b:'#0a0a14',s:'#141428',a:'#6366f1',t:'#e0e0f0',g:'0 0 20px #6366f1'},
        aurora:{b:'#0a1a1a',s:'#142828',a:'#34d399',t:'#d1fae5',g:'0 0 20px #34d399'},
        sunset:{b:'#1a0f0a',s:'#281414',a:'#f97316',t:'#fed7aa',g:'0 0 20px #f97316'},
        ocean:{b:'#0a141a',s:'#142028',a:'#0ea5e9',t:'#e0f2fe',g:'0 0 20px #0ea5e9'},
        forest:{b:'#0a140a',s:'#142014',a:'#4ade80',t:'#dcfce7',g:'0 0 20px #4ade80'},
        cyber:{b:'#0d0221',s:'#1a0533',a:'#ff006e',t:'#ffccf9',g:'0 0 30px #ff006e'}
    };
    const th = TH[T]||TH.midnight;
    let W = [], Z = 2147483000;

    GM_addStyle(`
        @keyframes hf{from{opacity:0;transform:scale(.9) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}
        @keyframes swim{0%{transform:translateX(0) scaleX(1)}49%{transform:translateX(100%) scaleX(1)}50%{transform:translateX(100%) scaleX(-1)}99%{transform:translateX(0) scaleX(-1)}100%{transform:translateX(0) scaleX(1)}}
        .hw{position:fixed!important;background:${th.s}ee!important;backdrop-filter:blur(30px)!important;border:1px solid ${th.a}33!important;border-radius:16px!important;box-shadow:0 25px 80px #000b,${th.g}!important;animation:hf .3s!important;overflow:hidden!important;min-width:300px!important;font-family:system-ui!important}
        .ht{display:flex!important;align-items:center!important;padding:10px 15px!important;background:${th.s}!important;border-bottom:1px solid rgba(255,255,255,.05)!important;cursor:move!important;user-select:none!important}
        .hb{padding:8px 16px!important;border-radius:10px!important;border:1px solid ${th.a}44!important;background:rgba(255,255,255,.03)!important;color:${th.t}!important;cursor:pointer!important;transition:.3s!important;font-size:13px!important}
        .hb:hover{background:${th.a}22!important;border-color:${th.a}!important;box-shadow:${th.g}!important;transform:translateY(-2px)!important}
        .hb:active{transform:scale(.95)!important;transition:.1s!important}
        .hi{padding:10px 14px!important;border-radius:10px!important;border:1px solid rgba(255,255,255,.1)!important;background:rgba(255,255,255,.03)!important;color:${th.t}!important;outline:none!important;font-size:13px!important;width:100%!important;box-sizing:border-box!important}
        .hi:focus{border-color:${th.a}!important;box-shadow:0 0 15px ${th.a}44!important}
        .hbar{position:fixed!important;bottom:15px!important;left:50%!important;transform:translateX(-50%)!important;background:${th.s}dd!important;backdrop-filter:blur(30px)!important;border:1px solid ${th.a}33!important;border-radius:20px!important;padding:8px 20px!important;display:flex!important;gap:8px!important;z-index:2147483640!important;box-shadow:0 15px 50px #0009!important;flex-wrap:wrap!important;justify-content:center!important}
        .hbi{width:42px!important;height:42px!important;border-radius:14px!important;display:flex!important;align-items:center!important;justify-content:center!important;font-size:18px!important;cursor:pointer!important;transition:.3s!important;background:rgba(255,255,255,.03)!important;border:1px solid transparent!important;flex-shrink:0!important}
        .hbi:hover{background:${th.a}22!important;border-color:${th.a}!important;box-shadow:${th.g}!important;transform:translateY(-3px)!important}
        ::-webkit-scrollbar{width:8px!important}::-webkit-scrollbar-track{background:transparent!important}::-webkit-scrollbar-thumb{background:${th.a}44!important;border-radius:10px!important}
    `);

    function mkWin(t,c,w=350,h=450){
        let x=Math.min(100+W.length*40, window.innerWidth-400);
        let y=Math.min(80+W.length*30, window.innerHeight-500);
        let z=++Z;
        let d=document.createElement('div');d.className='hw';
        d.style.cssText=`width:${w}px;height:${h}px;left:${x}px;top:${y}px;z-index:${z}`;
        d.innerHTML=`<div class="ht" id="t${z}"><span style="color:${th.t};font-weight:600;font-size:13px">${t}</span><div style="margin-left:auto;display:flex;gap:8px"><button class="min-btn" style="background:none;border:none;color:#fbbf24;font-size:16px;cursor:pointer">─</button><button class="close-btn" style="background:none;border:none;color:#ef4444;font-size:16px;cursor:pointer">✕</button></div></div><div style="padding:20px;overflow-y:auto;height:calc(100% - 45px);color:${th.t};font-size:13px">${c}</div>`;
        document.body.appendChild(d);
        
        // Drag functionality
        let tb=d.querySelector('.ht'),dr=false,sx,sy,ix,iy;
        tb.onmousedown=function(e){
            if(e.target.tagName==='BUTTON')return;
            dr=true;sx=e.clientX;sy=e.clientY;
            ix=parseInt(d.style.left);iy=parseInt(d.style.top);
            d.style.zIndex=++Z;
        };
        document.addEventListener('mousemove',function(e){
            if(!dr)return;
            d.style.left=Math.max(0, Math.min(window.innerWidth-w, ix+e.clientX-sx))+'px';
            d.style.top=Math.max(0, Math.min(window.innerHeight-h, iy+e.clientY-sy))+'px';
        });
        document.addEventListener('mouseup',function(){dr=false;});
        
        // Min/Max button
        d.querySelector('.min-btn').onclick=function(){
            if(d._minimized){
                d.style.display='block';
                d._minimized=false;
            } else {
                d.style.display='none';
                d._minimized=true;
            }
        };
        
        // Close button
        d.querySelector('.close-btn').onclick=function(){
            d.remove();
            W=W.filter(win=>win!==d);
        };
        
        W.push(d);
        return d;
    }

    function notes(){
        let n=[];
        try { n=JSON.parse(GM_getValue('h_notes','[]')); } catch(e) { n=[]; }
        let win=mkWin(TXT.notes,`
            <textarea id="ni_${Date.now()}" class="hi" placeholder="${TXT.notesPlaceholder}" style="height:80px;resize:none;margin-bottom:10px"></textarea>
            <button class="hb" style="width:100%;margin-bottom:10px" id="save_note_btn">${TXT.save}</button>
            <div style="max-height:200px;overflow-y:auto" id="notes_list"></div>
        `,380,420);
        
        setTimeout(() => {
            let saveBtn = win.querySelector('#save_note_btn');
            let textarea = win.querySelector('textarea');
            let notesList = win.querySelector('#notes_list');
            
            function renderNotes(){
                let n=[];
                try { n=JSON.parse(GM_getValue('h_notes','[]')); } catch(e) { n=[]; }
                notesList.innerHTML = n.map((x,i)=>`<div style="background:rgba(255,255,255,.03);padding:10px;border-radius:8px;margin:3px 0;display:flex;justify-content:space-between"><span>${x.substring(0,40)}${x.length>40?'...':''}</span><button class="del-note" data-idx="${i}" style="background:none;border:none;color:#ef4444;cursor:pointer">🗑️</button></div>`).join('');
                notesList.querySelectorAll('.del-note').forEach(btn => {
                    btn.onclick = function(){
                        let idx = parseInt(this.getAttribute('data-idx'));
                        let n=[];
                        try { n=JSON.parse(GM_getValue('h_notes','[]')); } catch(e) { n=[]; }
                        n.splice(idx,1);
                        GM_setValue('h_notes',JSON.stringify(n));
                        renderNotes();
                    };
                });
            }
            
            saveBtn.onclick = function(){
                let v=textarea.value.trim();
                if(v){
                    let n=[];
                    try { n=JSON.parse(GM_getValue('h_notes','[]')); } catch(e) { n=[]; }
                    n.push(v);
                    GM_setValue('h_notes',JSON.stringify(n));
                    textarea.value='';
                    renderNotes();
                    alert(TXT.saved);
                }
            };
            
            renderNotes();
        }, 100);
    }

    function pomodoro(){
        let t=1500,rt=false;
        let win=mkWin(TXT.pomodoro,`
            <div style="text-align:center">
                <div id="pd_${Date.now()}" style="font-size:60px;font-weight:900;color:${th.a};text-shadow:${th.g};margin:20px 0">25:00</div>
                <div style="display:flex;gap:10px;justify-content:center;margin:15px 0">
                    <button class="hb" id="ps_btn">${TXT.start}</button>
                    <button class="hb" id="pp_btn">${TXT.pause}</button>
                    <button class="hb" id="pr_btn">${TXT.reset}</button>
                </div>
                <div style="color:#888;font-size:11px">${TXT.workInfo}</div>
            </div>
        `,320,300);
        
        let iv;
        setTimeout(() => {
            let pd = win.querySelector('[id^="pd_"]');
            win.querySelector('#ps_btn').onclick = () => {
                if(iv) clearInterval(iv);
                iv = setInterval(() => {
                    t--;
                    let m=Math.floor(t/60),s=t%60;
                    pd.textContent = m+':'+(s<10?'0':'')+s;
                    if(t<=0){ clearInterval(iv); alert(TXT.timeUp); }
                }, 1000);
            };
            win.querySelector('#pp_btn').onclick = () => { if(iv) clearInterval(iv); };
            win.querySelector('#pr_btn').onclick = () => { if(iv) clearInterval(iv); t=1500; pd.textContent='25:00'; };
        }, 100);
    }

    function stocks(){
        let data = [
            {n:TXT.dollar,s:'$',v:'32.45',c:'#4ade80'},
            {n:TXT.euro,s:'€',v:'35.12',c:'#60a5fa'},
            {n:TXT.gold,s:'🟡',v:'2450',c:'#fbbf24'},
            {n:TXT.bist,s:'📈',v:'9850',c:'#f472b6'},
            {n:TXT.bitcoin,s:'₿',v:'1450000',c:'#f97316'}
        ];
        mkWin(TXT.currency,`
            ${data.map(d=>`<div style="display:flex;justify-content:space-between;align-items:center;padding:12px;background:rgba(255,255,255,.03);border-radius:10px;margin:5px 0"><span>${d.s} ${d.n}</span><span style="color:${d.c};font-weight:700">${d.v} ₺</span></div>`).join('')}
            <div style="text-align:center;color:#888;font-size:10px;margin-top:10px">${TXT.currencyNote}</div>
        `,320,380);
    }

    function clock(){
        let win=mkWin(TXT.clock,`
            <div style="text-align:center">
                <div id="hc_${Date.now()}" style="font-size:50px;font-weight:900;color:${th.t};text-shadow:${th.g};margin:15px 0"></div>
                <div id="hd_${Date.now()}" style="color:#888;font-size:14px;margin-bottom:15px"></div>
                <div style="display:flex;gap:10px;padding:15px;background:rgba(255,255,255,.03);border-radius:12px"><span style="font-size:40px">🌤️</span><div style="text-align:left"><div style="font-weight:700">${TXT.istanbul}</div><div style="font-size:24px">22°C</div><div style="color:#888;font-size:11px">${TXT.partlyCloudy}</div></div></div>
            </div>
        `,320,320);
        
        let iv = setInterval(() => {
            let hc = win.querySelector('[id^="hc_"]');
            let hd = win.querySelector('[id^="hd_"]');
            if(!hc || !hd) { clearInterval(iv); return; }
            let n=new Date();
            let locale = LANG==='tr'?'tr-TR':'en-US';
            hc.textContent = n.toLocaleTimeString(locale);
            hd.textContent = n.toLocaleDateString(locale,{weekday:'long',year:'numeric',month:'long',day:'numeric'});
        }, 1000);
    }

    function matrix(){
        let win=mkWin(TXT.matrix,`
            <canvas id="mc_${Date.now()}" style="width:100%;height:250px;border-radius:10px;background:#000"></canvas>
        `,450,340);
        
        setTimeout(() => {
            let c=win.querySelector('canvas');
            let x=c.getContext('2d');
            c.width=c.offsetWidth;c.height=250;
            let ch='アイウエオカキクケコサシスセソタチツテトナニヌネノ0123456789';
            let dr=[];
            for(let i=0;i<80;i++){
                dr.push({
                    x:Math.random()*c.width,
                    y:Math.random()*c.height,
                    s:1+Math.random()*3,
                    v:ch[Math.floor(Math.random()*ch.length)]
                });
            }
            let iv = setInterval(() => {
                if(!win.parentNode) { clearInterval(iv); return; }
                if(c.width !== c.offsetWidth) c.width = c.offsetWidth;
                x.fillStyle='rgba(0,0,0,.05)';
                x.fillRect(0,0,c.width,250);
                x.fillStyle='#0f0';
                x.font='14px monospace';
                dr.forEach(d=>{
                    x.fillText(d.v,d.x,d.y);
                    d.y+=d.s;
                    if(d.y>250){d.y=0;d.x=Math.random()*c.width;d.v=ch[Math.floor(Math.random()*ch.length)];}
                });
            }, 50);
        }, 100);
    }

    function drawing(){
        let win=mkWin(TXT.drawing,`
            <canvas id="dc_${Date.now()}" style="width:100%;height:200px;border-radius:10px;background:#fff;cursor:crosshair"></canvas>
            <div style="display:flex;gap:5px;margin-top:10px;align-items:center">
                <input type="color" id="dcl_${Date.now()}" value="#ff0000" style="width:35px;height:35px;border-radius:8px;border:none;cursor:pointer">
                <input type="range" id="dcs_${Date.now()}" min="1" max="15" value="3" style="flex:1">
                <button class="hb" id="clear_draw">🧹</button>
            </div>
        `,400,320);
        
        setTimeout(() => {
            let c=win.querySelector('canvas');
            let x=c.getContext('2d');
            c.width=c.offsetWidth;c.height=200;
            x.fillStyle='#fff';
            x.fillRect(0,0,c.width,c.height);
            
            let dr=false;
            let colorInput = win.querySelector('[id^="dcl_"]');
            let sizeInput = win.querySelector('[id^="dcs_"]');
            
            c.onmousedown = function(e){
                dr=true;
                x.beginPath();
                x.moveTo(e.offsetX,e.offsetY);
                x.strokeStyle=colorInput.value;
                x.lineWidth=sizeInput.value;
            };
            c.onmousemove = function(e){
                if(!dr)return;
                x.strokeStyle=colorInput.value;
                x.lineWidth=sizeInput.value;
                x.lineTo(e.offsetX,e.offsetY);
                x.stroke();
            };
            c.onmouseup = function(){ dr=false; };
            c.onmouseleave = function(){ dr=false; };
            
            win.querySelector('#clear_draw').onclick = function(){
                x.fillStyle='#fff';
                x.fillRect(0,0,c.width,c.height);
            };
        }, 100);
    }

    function calculator(){
        let win=mkWin(TXT.calculator,`
            <div id="cd_${Date.now()}" style="background:rgba(0,0,0,.3);padding:20px;border-radius:12px;text-align:right;font-size:28px;font-weight:700;margin-bottom:15px;word-break:break-all">0</div>
            <div style="display:grid;grid-template-columns:repeat(4,1fr);gap:6px" id="calc_btns"></div>
        `,320,380);
        
        setTimeout(() => {
            let cd = win.querySelector('[id^="cd_"]');
            let btns = win.querySelector('#calc_btns');
            let buttons = ['C','⌫','%','÷','7','8','9','×','4','5','6','-','1','2','3','+','0','00','.','='];
            
            buttons.forEach(b => {
                let btn = document.createElement('button');
                btn.className = 'hb';
                btn.style.cssText = 'padding:14px;text-align:center;font-size:15px';
                btn.textContent = b;
                btn.onclick = function(){
                    let v = cd.textContent;
                    if(b==='C') v='0';
                    else if(b==='⌫') v=v.length>1?v.slice(0,-1):'0';
                    else if(b==='='){
                        try {
                            let expr = v.replace(/×/g,'*').replace(/÷/g,'/');
                            v = eval(expr);
                            if(!isFinite(v)) v = TXT.error;
                        } catch(e) { v = TXT.error; }
                    }
                    else if(v==='0' && b!=='.') v=b;
                    else v+=b;
                    cd.textContent = v;
                };
                btns.appendChild(btn);
            });
        }, 100);
    }

    function cursorGlow(){
        let existing = document.getElementById('cursor_glow');
        if(existing) { existing.remove(); return; }
        
        let g=document.createElement('div');
        g.id = 'cursor_glow';
        g.style.cssText=`position:fixed;pointer-events:none;z-index:2147483630;width:200px;height:200px;border-radius:50%;background:radial-gradient(circle,${th.a}33 0%,transparent 70%);transform:translate(-50%,-50%);transition:.05s linear`;
        document.body.appendChild(g);
        document.addEventListener('mousemove', function(e){ g.style.left=e.clientX+'px'; g.style.top=e.clientY+'px'; });
        mkWin(TXT.light,`<div style="text-align:center;color:#888">${TXT.lightActive}</div>`,300,150);
    }

    function space(){
        let existing = document.getElementById('space_canvas');
        if(existing) { existing.remove(); return; }
        
        let c=document.createElement('canvas');c.id='space_canvas';
        c.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;z-index:2147483620;pointer-events:none;background:linear-gradient(180deg,#000011,#0a0a2e 30%,#0d0d1a 60%,#000011)';
        document.body.appendChild(c);
        let x=c.getContext('2d');c.width=window.innerWidth;c.height=window.innerHeight;
        let s=[];
        for(let i=0;i<150;i++){
            s.push({x:Math.random()*c.width,y:Math.random()*c.height,z:Math.random()*2+0.5,a:Math.random()});
        }
        function anim(){
            if(!document.getElementById('space_canvas')) return;
            if(c.width !== window.innerWidth) c.width = window.innerWidth;
            if(c.height !== window.innerHeight) c.height = window.innerHeight;
            x.clearRect(0,0,c.width,c.height);
            s.forEach(star=>{
                x.fillStyle='#fff';
                x.globalAlpha=star.a;
                x.beginPath();
                x.arc(star.x,star.y,star.z,0,Math.PI*2);
                x.fill();
                star.y+=0.2;
                if(star.y>c.height){star.y=0;star.x=Math.random()*c.width;}
                star.a=0.3+Math.sin(Date.now()*0.003+star.x)*0.3;
            });
            x.globalAlpha=1;
            requestAnimationFrame(anim);
        }
        anim();
    }

    function soundscape(){
        let existing = document.getElementById('sound_osc');
        if(existing) return;
        
        try {
            let ac=new(window.AudioContext||window.webkitAudioContext);
            let mg=ac.createGain();mg.gain.value=0.3;mg.connect(ac.destination);
            let o=ac.createOscillator();o.id='sound_osc';
            let g=ac.createGain();
            o.type='sine';o.frequency.value=200;
            g.gain.value=0.01;
            o.connect(g);g.connect(mg);o.start();
            document.body._soundOsc = o;
        } catch(e) {
            console.log('Audio not supported');
        }
        mkWin(TXT.sound,`<div style="text-align:center"><div style="font-size:40px;margin:15px 0">🎧</div><div style="color:#888">${TXT.soundActive}</div></div>`,300,200);
    }

    function aquarium(){
        let existing = document.getElementById('aquarium_container');
        if(existing) { existing.remove(); return; }
        
        let t=document.createElement('div');t.id='aquarium_container';
        t.style.cssText='position:fixed;bottom:0;left:0;right:0;height:120px;z-index:2147483620;background:linear-gradient(180deg,rgba(10,61,98,0.87),#0a3d62);border-top:2px solid rgba(255,255,255,.2);pointer-events:none;overflow:hidden';
        document.body.appendChild(t);
        
        // Add decorative elements
        let sand = document.createElement('div');
        sand.style.cssText = 'position:absolute;bottom:0;left:0;right:0;height:20px;background:#c2a24b;border-radius:50% 50% 0 0';
        t.appendChild(sand);
        
        let bubbles = document.createElement('div');
        bubbles.style.cssText = 'position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:none';
        t.appendChild(bubbles);
        
        // Spawn fish
        let fishInterval = setInterval(() => {
            if(!document.getElementById('aquarium_container')) { clearInterval(fishInterval); return; }
            let f=document.createElement('span');
            f.textContent=['🐠','🐟','🐡','🐙','🦀','🐚'][Math.floor(Math.random()*6)];
            let startY = 5 + Math.random() * 80;
            f.style.cssText=`position:absolute;font-size:${18+Math.random()*20}px;left:-50px;top:${startY}px;animation:swim ${4+Math.random()*6}s linear infinite`;
            t.appendChild(f);
            setTimeout(() => { if(f.parentNode) f.remove(); }, 10000);
        }, 2000);
        
        // Spawn bubbles
        let bubbleInterval = setInterval(() => {
            if(!document.getElementById('aquarium_container')) { clearInterval(bubbleInterval); return; }
            let b = document.createElement('div');
            b.style.cssText = `position:absolute;bottom:0;left:${Math.random()*100}%;width:${3+Math.random()*8}px;height:${3+Math.random()*8}px;background:rgba(255,255,255,0.3);border-radius:50%;animation:bubbleUp ${1+Math.random()*2}s linear`;
            bubbles.appendChild(b);
            setTimeout(() => { if(b.parentNode) b.remove(); }, 3000);
        }, 500);
        
        // Add bubble animation
        if(!document.getElementById('aquarium_style')){
            let style = document.createElement('style');
            style.id = 'aquarium_style';
            style.textContent = '@keyframes bubbleUp{from{bottom:0;opacity:0.5}to{bottom:120px;opacity:0}}@keyframes swim{0%{left:-50px}100%{left:calc(100% + 50px)}}';
            document.head.appendChild(style);
        }
        
        mkWin(TXT.aquarium,`<div style="text-align:center"><div style="font-size:50px;margin:15px 0">🐠</div><div style="color:#888">${TXT.aquarium} 🐟</div><div style="color:#666;font-size:10px;margin-top:10px">Sayfa altında akvaryum aktif</div></div>`,300,200);
    }

    function settings(){
        let win=mkWin(TXT.settings,`
            <div><label style="color:#888;font-size:11px">${TXT.theme}</label><select id="st_${Date.now()}" class="hi" style="margin-top:5px">${Object.keys(TH).map(t=>`<option ${T===t?'selected':''}>${t}</option>`).join('')}</select></div>
            <div style="margin-top:10px"><label style="color:#888;font-size:11px">🌐 Language / Dil</label><select id="sl_${Date.now()}" class="hi" style="margin-top:5px"><option value="en" ${LANG==='en'?'selected':''}>English</option><option value="tr" ${LANG==='tr'?'selected':''}>Türkçe</option></select></div>
            <div style="margin-top:10px"><label style="color:#888;font-size:11px">${TXT.user}</label><input id="su_${Date.now()}" class="hi" value="${U}" style="margin-top:5px"></div>
            <button class="hb" style="width:100%;margin-top:15px;background:${th.a}33;font-weight:700" id="save_settings">${TXT.saveSettings}</button>
        `,340,320);
        
        setTimeout(() => {
            win.querySelector('#save_settings').onclick = function(){
                let theme = win.querySelector('[id^="st_"]').value;
                let lang = win.querySelector('[id^="sl_"]').value;
                let user = win.querySelector('[id^="su_"]').value;
                GM_setValue('h_theme', theme);
                GM_setValue('h_lang', lang);
                GM_setValue('h_user', user);
                location.reload();
            };
        }, 100);
    }

    function boot(){
        // Remove existing bar if any
        let existingBar = document.querySelector('.hbar');
        if(existingBar) existingBar.remove();
        
        let b=document.createElement('div');b.className='hbar';
        let apps = [
            {i:'📝',f:notes},{i:'🍅',f:pomodoro},{i:'💹',f:stocks},{i:'🕐',f:clock},
            {i:'💚',f:matrix},{i:'🎨',f:drawing},{i:'🔢',f:calculator},{i:'💡',f:cursorGlow},
            {i:'🌌',f:space},{i:'🎧',f:soundscape},{i:'🐠',f:aquarium},{i:'⚙️',f:settings}
        ];
        apps.forEach(a=>{
            let d=document.createElement('div');d.className='hbi';
            d.textContent=a.i;d.onclick=a.f;
            d.title = a.i;
            b.appendChild(d);
        });
        document.body.appendChild(b);
    }

    // Wait for body
    function init(){
        if(!document.body) { setTimeout(init, 100); return; }
        boot();
    }
    
    init();
})();