/* === custom mario font === */
@font-face {
    font-family: "NDS BIOS";
    src: url("https://db.onlinewebfonts.com/t/1888b71aa651100801cb2e473433f5ec.woff") format("woff");
    font-weight: normal;
    font-style: normal;
}

/* apply to title logo */
#titleScreen h1 {
    font-family: "NDS BIOS", sans-serif;
}

/* base body styling */
body {
    margin:0;
    background:white;
    overflow:hidden;
    font-family:sans-serif;
}

html, body {
    cursor: url(https://files.catbox.moe/5uebbf.cur), auto;
}

/* ---------- DS ENTRY ---------- */  
#dsEntry{  
    position:fixed;  
    inset:0;  
    background:white;  
    display:flex;  
    justify-content:center;  
    align-items:center;  
    z-index:30;  
}  
  
#dsEntry img{  
    width:400px;  
    cursor: inherit;  
    transition:transform 1s ease;  
}  
  
.zoomIn{  
    transform:scale(3);  
}  
  
/* ---------- STARTUP ---------- */  
#startupScreen{  
    position:fixed;  
    inset:0;  
    background:white;  
    display:none;  
    justify-content:center;  
    align-items:center;  
    font-family:'NDS BIOS';  
    font-size:18px;  
}  
  
/* ---------- CRT ---------- */  
.crt{  
    background:black !important;  
    color:white;  
}  
  
body.crt::after{  
    content:"";  
    position:fixed;  
    inset:0;  
    background:linear-gradient(rgba(255,255,255,0.05) 50%, transparent 50%);  
    background-size:100% 4px;  
    pointer-events:none;  
}  
  
/* ---------- TITLE ---------- */  
#titleScreen{  
    position:fixed;  
    inset:0;  
    display:none;  
    flex-direction:column;  
    justify-content:center;  
    align-items:center;  
    gap:20px;  
}  
  
.logo{  
    font-family:'NDS BIOS';  
    font-size:28px;  
}  
  
.menuBtn{  
    font-family:'NDS BIOS';  
    font-size:10px;  
    padding:10px 18px;  
    background:#111;  
    border:2px solid white;  
    color:white;  
    cursor:inherit;  
}  
  
/* ---------- MAIN ---------- */  
#mainSite{  
    display:none;  
    padding:40px;  
}  
  
textarea{  
    width:100%;  
    min-height:120px;  
    font-family:'Patrick Hand';  
    font-size:22px;  
    border-radius:20px;  
    padding:15px;  
    background:#111;  
    color:white;  
    border:2px solid #444;  
}  
  
.preview{  
    margin-top:20px;  
    min-height:60px;  
    padding:15px;  
    background:#111;  
    border-radius:20px;  
}  
  
/* ---------- ACHIEVEMENT BUBBLE ---------- */  
#achievementBubble{  
    position:fixed;  
    top:20px;  
    left:-300px;  
    background:#111;  
    border:2px solid white;  
    padding:10px;  
    font-family:'NDS BIOS';  
    font-size:8px;  
    transition:left 0.5s ease;  
}  
  
/* ---------- ACHIEVEMENT HUD ---------- */  
#achievementHUD{  
    position:fixed;  
    top:20px;  
    right:20px;  
    width:260px;  
    background:#111;  
    border:2px solid white;  
    padding:15px;  
    display:none;  
    font-family:'NDS BIOS';  
    font-size:8px;  
}  
  
.achievementBox{  
    border:1px solid white;  
    padding:6px;  
    margin-bottom:6px;  
}  
  
/* ---------- BOWSER HEAD ---------- */  
#bowserHead{  
    position:fixed;  
    width:200px;  
    cursor:inherit;  
    z-index:100;  
    transition: all 2s ease;  
}  
  
#bowserHP{  
    position:fixed;  
    bottom:20px;  
    left:50%;  
    transform:translateX(-50%);  
    color:white;  
    font-family:'NDS BIOS';  
    font-size:16px;  
    z-index:101;  
}  
  
#starman{  
    position:fixed;  
    width:80px;  
    left:50%;  
    top:50%;  
    transform:translate(-50%, -50%);  
    cursor:pointer;  
    z-index:102;  
}  
</style>  </head>  
<body>  <!-- DS ENTRY -->  <div id="dsEntry">  
<img id="dsImage" src="https://upload.wikimedia.org/wikipedia/commons/5/56/Nintendo-DS-Lite-Black-Open.png">  
</div>  <!-- STARTUP -->  <div id="startupScreen">Starting...</div>  <!-- TITLE -->  <div id="titleScreen">  
<div class="logo">RACCOON SCRIPT</div>  
<button class="menuBtn" onclick="startApp(true)">START</button>  
<button class="menuBtn" onclick="toggleHUD()">ACHIEVEMENTS</button>  
</div>  <!-- MAIN -->  <div id="mainSite">  
<h2>Translator</h2>  
<textarea id="input"></textarea>  
<button class="menuBtn" onclick="toggleAtbash()">TOGGLE ATBASH</button>  
<div class="preview" id="preview"></div>  
<button class="menuBtn" onclick="returnToTitle()">RETURN</button>  
</div>  <div id="achievementBubble"></div>  <div id="achievementHUD">  
<div>ACHIEVEMENTS</div>  
<div id="achievementList"></div>  
<button class="menuBtn" onclick="eraseAchievements()">ERASE DATA</button>  
</div>  <!-- AUDIO -->  <audio id="startupSfx">  
<source src="https://nu.vgmtreasurechest.com/soundtracks/nintendo-zone-3ds-sound-effects-3ds-gamerip-2011/ntfvluqv/114.%20Startup.mp3">  
</audio>  <audio id="typeSfx">  
<source src="https://nu.vgmtreasurechest.com/soundtracks/nintendo-dsi-sound-effects-ds-gamerip-2008/eqpearfd/1-15.%20Menu%20Sound%20Effects%20-%20Twl%20Kbd%20Se%20Key%20Input.mp3">  
</audio>  <audio id="bgMusic" loop>  
<source src="https://jetta.vgmtreasurechest.com/soundtracks/super-mario-world-snes-gamerip/znrspueo/25.%20Swimming%20%28Yoshi%29.mp3">  
</audio>  <audio id="bowserMusic" loop>  
<source src="https://jetta.vgmtreasurechest.com/soundtracks/mario-and-luigi-bowser-s-inside-story-ost/otyoxvmv/50.%20The%20Grand%20Finale.mp3">  
</audio>  <audio id="achieveSfx">  
<source src="https://nu.vgmtreasurechest.com/soundtracks/nintendo-3ds-bios-sounds-3ds-gamerip-2011/proufuhc/27.%20Home%20Banner%20Bashotorya.mp3">  
</audio>  <script>  
/* ---------- DS ENTRY FLOW ---------- */  
const ds=document.getElementById("dsImage");  
const dsEntry=document.getElementById("dsEntry");  
const startup=document.getElementById("startupScreen");  
const startupSfx=document.getElementById("startupSfx");  
const bowserMusic=document.getElementById("bowserMusic");  
const bgMusic=document.getElementById("bgMusic");  
const achieveSfx=document.getElementById("achieveSfx");  
  
ds.onclick=()=>{  
    ds.classList.add("zoomIn");  
    document.getElementById("typeSfx").play();  
    setTimeout(()=>{  
        dsEntry.style.display="none";  
        startup.style.display="flex";  
        startupSfx.play();  
        setTimeout(()=>{  
            document.body.classList.add("crt");  
            startup.style.display="none";  
            document.getElementById("titleScreen").style.display="flex";  
        },2500);  
    },1000);  
};  
  
/* ---------- TRANSLATOR ---------- */  
let atbashEnabled=false;  
  
const upperMap={A:"Λ",B:"ზ",C:"ᑕ",D:"𝔻",E:"ꗍ",F:"Г",G:"Ꮆ",H:"ⵍ",I:"ꕯ",J:"ਹ",  
K:"₭",L:"ᒫ",M:"ꔟ",N:"И",O:"Ѻ",P:"Ꮅ",Q:"Ꝗ",R:"Ʀ",S:"ꕶ",T:"Ⲧ",  
U:"Ʋ",V:"ᗄ",W:"Ꙍ",X:"ⴴ",Y:"Ҹ",Z:"ሯ"};  
  
const lowerMap={a:"ә",b:"ս",c:"𝚌",d:"ᑰ",e:"ɐ",f:"г",g:"ɞ",h:"ћ",i:"ェ",j:"テ",  
k:"𐌊",l:"𝜆",m:"൬",n:"ﬨ",o:"σ",p:"𝜑",q:"ϙ",r:"л",s:"ꙅ",t:"ɫ",  
u:"υ",v:"⍱",w:"ω",x:"𝜒",y:"𝜸",z:"ੲ"};  
  
function atbash(t){  
    const abc="abcdefghijklmnopqrstuvwxyz";  
    const rev="zyxwvutsrqponmlkjihgfedcba";  
    return t.split("").map(c=>{  
        let l=c.toLowerCase();  
        if(abc.includes(l)){  
            let r=rev[abc.indexOf(l)];  
            return c===c.toUpperCase()?r.toUpperCase():r;  
        }  
        return c;  
    }).join("");  
}  
  
function encode(t){  
    let r="";  
    for(let c of t){  
        if(upperMap[c]) r+=upperMap[c];  
        else if(lowerMap[c]) r+=lowerMap[c];  
        else r+=c;  
    }  
    return r;  
}  
  
function updatePreview(){  
    let text=document.getElementById("input").value;  
    if(atbashEnabled) text=atbash(text);  
    document.getElementById("preview").innerText=encode(text);  
}  
  
function toggleAtbash(){  
    atbashEnabled=!atbashEnabled;  
    document.getElementById("typeSfx").play();  
    updatePreview();  
}  
  
document.getElementById("input").addEventListener("input",e=>{  
    document.getElementById("typeSfx").currentTime=0;  
    document.getElementById("typeSfx").play();  
    updatePreview();  
    checkAchievements(e.target.value);  
});  
  
/* ---------- ACHIEVEMENTS ---------- */  
let achievements=JSON.parse(localStorage.getItem("achievements"))||[];  
  
function saveA(){localStorage.setItem("achievements",JSON.stringify(achievements));}  
  
function unlock(name){  
    if(!achievements.includes(name)){  
        achievements.push(name);  
        saveA();  
        renderAchievements();  
        const bubble=document.getElementById("achievementBubble");  
        bubble.innerText="Achievement Unlocked! "+name;  
        bubble.style.left="20px";  
        achieveSfx.currentTime=0;  
        achieveSfx.play(); 
        if(name === "Dino Whisperer"){
    const yoshiSfx = new Audio("https://www.mariowiki.com/images/9/93/NSMBW_Yoshi_Ride.oga?49c96");
    yoshiSfx.volume = 0.8;
    yoshiSfx.play();
}
        setTimeout(()=>bubble.style.left="-300px",3000);  
    }  
}  
  
function renderAchievements(){  
    let list=document.getElementById("achievementList");  
    list.innerHTML="";  
    achievements.forEach(a=>{  
        let style=a.includes("Golden")?"style='border:2px solid gold;color:gold;'":"";  
        list.innerHTML+=`<div class="achievementBox" ${style}>${a}</div>`;  
    });  
}  
  
function eraseAchievements(){  
    document.getElementById("typeSfx").play();  
    achievements=[];  
    localStorage.removeItem("achievements");  
    renderAchievements();  
}  
  
/* ---------- BOWSER MODE ---------- */
let bowserHP = 100;
let hits = 0;
let bowserActive = false;
let bowserMoveInterval;
let starmanActive = false;

const starmanSfx = new Audio("https://jetta.vgmtreasurechest.com/soundtracks/super-mario-world-live/eaosyped/2-60%20-%20Invincible%20BGM.mp3");

function activateBowserMode(){
    // hide everything else
    document.getElementById("mainSite").style.display = "none";
    document.getElementById("titleScreen").style.display = "none";

    // set battle background
    document.body.style.background = "url('https://motionarray.imgix.net/motion-array-1830518-qTgBqduoKB-high_0003.jpg?w=660&q=60&fit=max&auto=format') center/cover no-repeat";

    // stop yoshi theme
    bgMusic.pause();
    bgMusic.currentTime = 0;

    // pre-unlock achievements
    ["Curious Creature","Dino Whisperer","You Found It","Glyph Touched","Wall Of Text","Golden Devotion 👑"].forEach(a=>{
        if(!achievements.includes(a)) unlock(a);
    });

    // create bowser head
    let head = document.getElementById("bowserHead");
    if(!head){
        head = document.createElement("img");
        head.src = "https://www.pngkey.com/png/full/20-203449_bowser-emblem-transparent.png";
        head.id = "bowserHead";
        head.style.position = "fixed";
        head.style.top = "50%";
        head.style.left = "50%";
        head.style.transform = "translate(-50%, -50%) scale(0.5)";
        head.style.cursor = "pointer";
        head.style.zIndex = "100";
        document.body.appendChild(head);
    }

    // bowser HP
    let hpDiv = document.getElementById("bowserHP");
    if(!hpDiv){
        hpDiv = document.createElement("div");
        hpDiv.id = "bowserHP";
        document.body.appendChild(hpDiv);
    }
    updateBowserHP();

    // bowser moves slower
    bowserMoveInterval = setInterval(moveBowser, 1500);

    // play bowser music
    bowserMusic.volume = 0.3;
    bowserMusic.currentTime = 0;
    bowserMusic.play();

    bowserActive = true;

    head.onclick = () => {
        if(!bowserActive) return;
        hits++;
        bowserHP--;
        playPunchSfx();
        updateBowserHP();

        if(hits === 50 && !starmanActive) createStarman();

        if(bowserHP <= 0) defeatBowser();
    };
}

function moveBowser(){
    if(!bowserActive) return;
    const head = document.getElementById("bowserHead");
    const x = Math.random() * (window.innerWidth - 200) + 100;
    const y = Math.random() * (window.innerHeight - 200) + 100;
    head.style.transition = "all 2s ease";
    head.style.left = `${x}px`;
    head.style.top = `${y}px`;
}

function updateBowserHP(){
    document.getElementById("bowserHP").innerText = `Bowser HP: ${bowserHP}`;
}

function playPunchSfx(){
    const punch = new Audio("https://nu.vgmtreasurechest.com/soundtracks/super-mario-bros-sfx-gamerip-1985/gntgaght/05.%20Break.mp3");
    punch.volume = 1.0;
    punch.currentTime = 0;
    punch.play();
}

function createStarman(){
    starmanActive = true;
    bowserMusic.pause();

    const star = document.createElement("img");
    star.src = "https://www.nicepng.com/png/full/169-1691779_related-wallpapers-super-mario-star-pixel.png";
    star.id = "starman";
    star.style.position = "fixed";
    star.style.left = "50%";
    star.style.top = "-100px";
    star.style.transform = "translateX(-50%)";
    star.style.width = "80px";
    star.style.zIndex = "102";
    star.style.cursor = "pointer";
    document.body.appendChild(star);

    // star drops and bounces
    let velocity = 0;
    let pos = -100;
    const gravity = 0.8;
    const bounce = 0.7;
    const floor = window.innerHeight / 2 + 50;

    const dropInterval = setInterval(()=>{
        velocity += gravity;
        pos += velocity;
        if(pos >= floor){
            pos = floor;
            velocity *= -bounce;
        }
        star.style.top = pos + "px";
    }, 16);

    star.onclick = () => {
        starmanSfx.currentTime = 0;
        starmanSfx.play();

        // flickering rainbow effect
        document.body.style.animation = "starmanFlicker 0.1s infinite";
        document.body.style.transition = "none";

        const rapidDamage = setInterval(()=>{
            if(bowserHP > 0){
                bowserHP -= 2; // reduce faster
                if(bowserHP < 0) bowserHP = 0;
                updateBowserHP();
            }
        }, 50);

        starmanSfx.onended = () => {
            clearInterval(rapidDamage);
            star.remove();
            starmanActive = false;
            document.body.style.animation = "";
            document.body.style.transition = "";
            if(bowserHP > 0) bowserMusic.play();
            else defeatBowser();
        };
    };
}

// add rainbow flicker keyframes
const style = document.createElement('style');
style.innerHTML = `
@keyframes starmanFlicker{
    0% {filter: hue-rotate(0deg);}
    25% {filter: hue-rotate(90deg);}
    50% {filter: hue-rotate(180deg);}
    75% {filter: hue-rotate(270deg);}
    100% {filter: hue-rotate(360deg);}
}`;
document.head.appendChild(style);

function defeatBowser(){
    bowserActive = false;
    clearInterval(bowserMoveInterval);

    const head = document.getElementById("bowserHead");
    const hpDiv = document.getElementById("bowserHP");

    // if starman is active, fade it out
    if(starmanActive){
        starmanActive = false;
        const star = document.getElementById("starman");
        if(star) star.remove();
        document.body.style.transition = "filter 2s ease";
        document.body.style.filter = "hue-rotate(0deg)";
        starmanSfx.pause();
        const fadeInterval = setInterval(()=>{
            if(starmanSfx.volume > 0){
                starmanSfx.volume -= 0.02;
            } else {
                starmanSfx.volume = 0;
                starmanSfx.currentTime = 0;
                clearInterval(fadeInterval);
            }
        }, 50);
        document.body.style.animation = "";
    }

    // fly up + spin + shrink animation
    head.style.transition = "all 2s cubic-bezier(.6,-0.28,.735,.045)";
    head.style.transform = "translate(-50%, -200%) scale(0) rotate(720deg)";

    setTimeout(()=>{
        head.remove();
        hpDiv.remove();
    }, 2000);

    bowserMusic.pause();
    bowserMusic.currentTime = 0;

    const defeatSfx = new Audio("https://jetta.vgmtreasurechest.com/soundtracks/super-mario-world-snes-gamerip/mpmolnej/60.%20Bowser%20Defeated.mp3");
    defeatSfx.play();

    defeatSfx.onended = () => {
        unlock("Bowser Defeated!");
        const winSfx1 = new Audio("https://jetta.vgmtreasurechest.com/soundtracks/super-mario-world-snes-gamerip/gtxiyuat/47.%20Course%20Clear.mp3");
        winSfx1.play();
        winSfx1.onended = () => {
            const winSfx2 = new Audio("https://jetta.vgmtreasurechest.com/soundtracks/super-mario-world-snes-gamerip/rewtfvmv/48.%20Fade%20Out%21.mp3");
            winSfx2.play();
            winSfx2.onended = () => {
                bgMusic.play(); // resume yoshi theme
                document.body.style.background = "white"; // reset background
                document.body.style.filter = ""; // remove any filter left from starman
                document.body.style.transition = "";
            };
        };
    };

    // restore main UI
    document.getElementById("mainSite").style.display = "block";
}
  
/* ---------- NAV ---------- */  
function startApp(playMusic){  
    document.getElementById("typeSfx").play();  
    if(playMusic){  
        bgMusic.currentTime=0;  
        bgMusic.play();  
    }  
    document.getElementById("titleScreen").style.display="none";  
    document.getElementById("mainSite").style.display="block";  
}  
  
function returnToTitle(){  
    document.getElementById("typeSfx").play();  
    document.getElementById("mainSite").style.display="none";  
    document.getElementById("titleScreen").style.display="flex";  
    bowserMusic.pause();  
    bowserMusic.currentTime=0;  
    document.body.style.boxShadow="none";  
    bgMusic.currentTime=0;  
    bgMusic.play();  
}  

/* ---------- AUDIO HELPER ---------- */
function playAchievementMusic(sfxUrl, musicUrl){
    const fadeTime = 500; // fade in/out in ms
    const step = 0.05; // volume change per interval
    const intervalTime = fadeTime * step; // ms per step
    
    // fade out current bg music
    let fadeOutInterval = setInterval(()=>{
        if(bgMusic.volume > step){
            bgMusic.volume -= step;
        } else {
            bgMusic.volume = 0;
            bgMusic.pause();
            clearInterval(fadeOutInterval);

            // play achievement sfx
            const sfx = new Audio(sfxUrl);
            sfx.volume = 0.8;
            sfx.play();

            // after sfx ends + 0.5s delay, fade in new music
            sfx.onended = ()=>{
                setTimeout(()=>{
                    playAchievementMusic(data.sfx, data.music);

                    let fadeInInterval = setInterval(()=>{
                        if(bgMusic.volume < 1-step){
                            bgMusic.volume += step;
                        } else {
                            bgMusic.volume = 1;
                            clearInterval(fadeInInterval);
                        }
                    }, intervalTime);
                }, 500); // 0.5s wait
            };
        }
    }, intervalTime);
}
  
/* ---------- CHECK ACHIEVEMENTS ---------- */  
function checkAchievements(t){  
    t=t.toLowerCase();  
    if(t.includes("raccoon")) unlock("Curious Creature");  
    if(t.includes("yoshi")) unlock("Dino Whisperer");  
    if(t.includes("secret")) unlock("You Found It");  
    if(t.includes("glyph")) unlock("Glyph Touched");  
    if(t.length>80) unlock("Wall Of Text");  
    if(t.includes("i love king bowser")){  
        unlock("Golden Devotion 👑");  
        activateBowserMode();  
    }  
}  
  
function toggleHUD(){  
    document.getElementById("typeSfx").play();  
let hud=document.getElementById("achievementHUD");  
    hud.style.display=hud.style.display==="block"?"none":"block";  
    renderAchievements();  
}  

/* ---------- POST-BOWSER MARIO GAME ACHIEVEMENTS ---------- */
const marioGames = {
    "super mario bros 1": { sfx: "https://nu.vgmtreasurechest.com/soundtracks/super-mario-bros-sfx-gamerip-1985/tuquavcx/01.%201up.mp3", music: "https://jetta.vgmtreasurechest.com/soundtracks/vs.-super-mario-bros.-arcade-switch-gamerip-1986/mygjbfxx/06.%20Underwater.mp3", alt: ["smb1"] },
    "super mario bros 2": { sfx: "https://nu.vgmtreasurechest.com/soundtracks/super