Lua os english
Key RequiredUniversal

Lua os english

Universal Scriptchillingchilling 4.7K views 2.7K executesUpdated Feb 23, 2026
5.0/ 5(3 votes)
30100% Positive
Lua Script•2019 lines (77391 chars)
-- ██╗     ██╗   ██╗ █████╗  ██████╗ ███████╗
-- ██║     ██║   ██║██╔══██╗██╔═══██╗██╔════╝
-- ██║     ██║   ██║███████║██║   ██║███████╗
-- ██║     ██║   ██║██╔══██║██║   ██║╚════██║
-- ███████╗╚██████╔╝██║  ██║╚██████╔╝███████║
-- ╚══════╝ ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝
--           v3.0 — Enhanced Edition
-- Paste into executor (Synapse, KRNL, Fluxus, Delta)

local Players        = game:GetService("Players")
local UIS            = game:GetService("UserInputService")
local TweenService   = game:GetService("TweenService")
local RunService     = game:GetService("RunService")

local player = Players.LocalPlayer

-- ── CONTAINER ──────────────────────────────────────────────────
local guiParent = (gethui and gethui()) or game:GetService("CoreGui")

-- Remove old copy
local old = guiParent:FindFirstChild("LuaOS_v3")
if old then old:Destroy() end
task.wait()

local gui = Instance.new("ScreenGui")
gui.Name            = "LuaOS_v3"
gui.ResetOnSpawn    = false
gui.ZIndexBehavior  = Enum.ZIndexBehavior.Global
gui.IgnoreGuiInset  = true
gui.Parent          = guiParent

-- ── THEMES ──────────────────────────────────────────────────────
local Themes = {
    Dark = {
        name     = "Dark",
        bg1      = Color3.fromRGB(8,  10, 22),
        bg2      = Color3.fromRGB(12, 16, 35),
        surface  = Color3.fromRGB(16, 21, 45),
        surface2 = Color3.fromRGB(22, 28, 58),
        border   = Color3.fromRGB(50, 65, 120),
        accent   = Color3.fromRGB(88, 130, 255),
        accent2  = Color3.fromRGB(110,160, 255),
        accentDk = Color3.fromRGB(55,  90, 200),
        text     = Color3.fromRGB(220, 228, 255),
        textDim  = Color3.fromRGB(110, 125, 175),
        textMut  = Color3.fromRGB(65,  78, 130),
        green    = Color3.fromRGB(50,  220, 110),
        red      = Color3.fromRGB(255,  70,  70),
        yellow   = Color3.fromRGB(255, 200,  50),
        term     = Color3.fromRGB(5,   7,  16),
        termTxt  = Color3.fromRGB(70,  240, 120),
        close    = Color3.fromRGB(220,  60,  60),
        minimize = Color3.fromRGB(240, 185,  35),
        maximize = Color3.fromRGB(50,  200, 80),
        winTitle = Color3.fromRGB(20,  26,  55),
        gradA    = Color3.fromRGB(8,10,25),
        gradB    = Color3.fromRGB(14,20,45),
        dotCol   = Color3.fromRGB(40,55,100),
    },
    Hacker = {
        name     = "Hacker",
        bg1      = Color3.fromRGB(2, 4, 2),
        bg2      = Color3.fromRGB(5, 12, 5),
        surface  = Color3.fromRGB(8, 18, 8),
        surface2 = Color3.fromRGB(12, 25, 12),
        border   = Color3.fromRGB(20, 80, 20),
        accent   = Color3.fromRGB(0, 255, 65),
        accent2  = Color3.fromRGB(50, 255, 100),
        accentDk = Color3.fromRGB(0, 150, 40),
        text     = Color3.fromRGB(180, 255, 190),
        textDim  = Color3.fromRGB(60, 140, 70),
        textMut  = Color3.fromRGB(30, 80, 35),
        green    = Color3.fromRGB(0, 255, 65),
        red      = Color3.fromRGB(255, 50, 50),
        yellow   = Color3.fromRGB(200, 255, 50),
        term     = Color3.fromRGB(0, 2, 0),
        termTxt  = Color3.fromRGB(0, 255, 65),
        close    = Color3.fromRGB(200, 40, 40),
        minimize = Color3.fromRGB(200, 200, 30),
        maximize = Color3.fromRGB(0, 200, 50),
        winTitle = Color3.fromRGB(5, 15, 5),
        gradA    = Color3.fromRGB(0,2,0),
        gradB    = Color3.fromRGB(5,15,5),
        dotCol   = Color3.fromRGB(0,60,10),
    },
    Sakura = {
        name     = "Sakura",
        bg1      = Color3.fromRGB(25, 10, 18),
        bg2      = Color3.fromRGB(35, 14, 28),
        surface  = Color3.fromRGB(42, 18, 35),
        surface2 = Color3.fromRGB(55, 24, 45),
        border   = Color3.fromRGB(120, 50, 90),
        accent   = Color3.fromRGB(255, 100, 160),
        accent2  = Color3.fromRGB(255, 140, 190),
        accentDk = Color3.fromRGB(180, 60, 110),
        text     = Color3.fromRGB(255, 220, 240),
        textDim  = Color3.fromRGB(170, 110, 145),
        textMut  = Color3.fromRGB(110, 60, 85),
        green    = Color3.fromRGB(100, 220, 150),
        red      = Color3.fromRGB(255, 70, 70),
        yellow   = Color3.fromRGB(255, 210, 100),
        term     = Color3.fromRGB(15, 5, 10),
        termTxt  = Color3.fromRGB(255, 130, 180),
        close    = Color3.fromRGB(220, 60, 60),
        minimize = Color3.fromRGB(240, 185, 35),
        maximize = Color3.fromRGB(100, 200, 120),
        winTitle = Color3.fromRGB(35, 14, 28),
        gradA    = Color3.fromRGB(20,8,15),
        gradB    = Color3.fromRGB(35,14,30),
        dotCol   = Color3.fromRGB(80,30,60),
    },
}

local T = Themes.Dark -- current theme
local ActiveTheme = "Dark"

-- ── HELPERS ────────────────────────────────────────────────────
local function tw(obj, props, t, style)
    TweenService:Create(obj,
        TweenInfo.new(t or .18, style or Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
        props):Play()
end

local function c(cls, props, parent)
    local o = Instance.new(cls)
    for k,v in pairs(props) do
        pcall(function() o[k] = v end)
    end
    if parent then o.Parent = parent end
    return o
end

local function corner(p, r)
    return c("UICorner", {CornerRadius = UDim.new(0, r or 8)}, p)
end

local function stroke(p, col, thick, trans)
    return c("UIStroke", {Color = col or T.border, Thickness = thick or 1, Transparency = trans or .4}, p)
end

local function pad(p, px)
    local u = Instance.new("UIPadding")
    u.PaddingLeft   = UDim.new(0, px)
    u.PaddingRight  = UDim.new(0, px)
    u.PaddingTop    = UDim.new(0, px)
    u.PaddingBottom = UDim.new(0, px)
    u.Parent = p
end

local function gradient(p, a, b, rot)
    local g = Instance.new("UIGradient")
    g.Color = ColorSequence.new(a, b)
    g.Rotation = rot or 0
    g.Parent = p
    return g
end

local function hover(btn, norm, hov, prop)
    prop = prop or "BackgroundColor3"
    btn.MouseEnter:Connect(function() tw(btn, {[prop]=hov})  end)
    btn.MouseLeave:Connect(function() tw(btn, {[prop]=norm}) end)
end

local function shadow(parent, zIdx)
    local s = c("Frame", {
        Size = UDim2.new(1, 20, 1, 20),
        Position = UDim2.new(0, -10, 0, -10),
        BackgroundColor3 = Color3.new(0,0,0),
        BackgroundTransparency = .65,
        ZIndex = zIdx - 1,
        BorderSizePixel = 0,
    }, parent)
    corner(s, 14)
    return s
end

-- ── NOTIFICATION SYSTEM ───────────────────────────────────────
local notifContainer = c("Frame", {
    Size = UDim2.new(0, 320, 1, 0),
    Position = UDim2.new(1, -330, 0, 10),
    BackgroundTransparency = 1,
    ZIndex = 8000,
}, gui)
c("UIListLayout", {
    Padding = UDim.new(0, 8),
    VerticalAlignment = Enum.VerticalAlignment.Top,
    SortOrder = Enum.SortOrder.LayoutOrder,
}, notifContainer)

local function notify(title, text, duration, icon)
    local nf = c("Frame", {
        Size = UDim2.new(1, 0, 0, 70),
        BackgroundColor3 = T.bg2,
        BorderSizePixel = 0,
        ZIndex = 8001,
        BackgroundTransparency = 1,
    }, notifContainer)
    corner(nf, 10)
    stroke(nf, T.accent, 1, .3)

    -- Accent bar on left
    local bar = c("Frame", {
        Size = UDim2.new(0, 4, 1, -8),
        Position = UDim2.new(0, 4, 0, 4),
        BackgroundColor3 = T.accent,
        BorderSizePixel = 0,
        ZIndex = 8002,
    }, nf)
    corner(bar, 2)

    c("TextLabel", {
        Size = UDim2.new(0, 30, 0, 30),
        Position = UDim2.new(0, 14, 0, 8),
        BackgroundTransparency = 1,
        Text = icon or "🔔",
        TextSize = 20,
        ZIndex = 8002,
    }, nf)

    c("TextLabel", {
        Size = UDim2.new(1, -60, 0, 22),
        Position = UDim2.new(0, 48, 0, 6),
        BackgroundTransparency = 1,
        Text = title,
        Font = Enum.Font.GothamBold,
        TextSize = 14,
        TextColor3 = T.text,
        TextXAlignment = Enum.TextXAlignment.Left,
        ZIndex = 8002,
    }, nf)

    c("TextLabel", {
        Size = UDim2.new(1, -60, 0, 30),
        Position = UDim2.new(0, 48, 0, 28),
        BackgroundTransparency = 1,
        Text = text,
        Font = Enum.Font.Gotham,
        TextSize = 12,
        TextColor3 = T.textDim,
        TextXAlignment = Enum.TextXAlignment.Left,
        TextWrapped = true,
        ZIndex = 8002,
    }, nf)

    -- Appear animation
    tw(nf, {BackgroundTransparency = 0}, .3)

    task.delay(duration or 4, function()
        tw(nf, {BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 0)}, .3)
        task.delay(.35, function() nf:Destroy() end)
    end)
end

-- ── FILE SYSTEM ───────────────────────────────────────────────
local FS = {}
local CWD = "/home/player"

local function fsNew(t, content)
    return {t=t, content=content or "", children={}, time=os.time()}
end

FS["/"]              = fsNew("dir")
FS["/bin"]           = fsNew("dir")
FS["/etc"]           = fsNew("dir")
FS["/home"]          = fsNew("dir")
FS["/home/player"]   = fsNew("dir")
FS["/home/player/Documents"] = fsNew("dir")
FS["/home/player/Music"]     = fsNew("dir")
FS["/tmp"]           = fsNew("dir")
FS["/var"]           = fsNew("dir")
FS["/var/log"]       = fsNew("dir")

local function regChild(parent, child)
    if FS[parent] then
        table.insert(FS[parent].children, child)
    end
end

regChild("/",           "/bin")
regChild("/",           "/etc")
regChild("/",           "/home")
regChild("/",           "/tmp")
regChild("/",           "/var")
regChild("/home",       "/home/player")
regChild("/home/player","/home/player/Documents")
regChild("/home/player","/home/player/Music")
regChild("/var",        "/var/log")

local function mkf(path, content, parent)
    FS[path] = fsNew("file", content)
    if parent then regChild(parent, path) end
end

mkf("/etc/hostname",              "luaos-roblox",                          "/etc")
mkf("/etc/motd",                  "Welcome to LuaOS v3.0!\nType 'help' for assistance.\nNew: neofetch, tree, grep, mkdir, mv, cp, fortune\n", "/etc")
mkf("/etc/os-release",            "NAME=LuaOS\nVERSION=3.0.0\nBUILD=Enhanced-Edition\nCODENAME=Aurora\n", "/etc")
mkf("/etc/passwd",                "root:x:0:0:root:/root\nplayer:x:1000:1000:"..player.Name..":/home/player\n", "/etc")
mkf("/home/player/readme.txt",    "Hello! This is LuaOS v3.0 — Enhanced Edition!\n\nNew features:\n  • 3 themes\n  • Calculator\n  • Music player\n  • System monitor\n  • Notifications\n  • Lock screen\n  • 12+ new terminal commands\n\nType 'neofetch' in terminal!\n", "/home/player")
mkf("/home/player/todo.txt",      "1. Try 'neofetch' in terminal\n2. Open settings and change theme\n3. Launch calculator\n4. ???\n5. PROFIT\n", "/home/player")
mkf("/home/player/Documents/notes.txt", "My notes:\n- LuaOS works great\n- Need to try all themes\n", "/home/player/Documents")
mkf("/tmp/session.log",           "Session started: "..os.date("%H:%M:%S").."\n", "/tmp")
mkf("/var/log/kernel.log",        "[OK] Kernel v3.0 loaded\n[OK] FS mounted\n[OK] Daemons started\n[OK] Window manager initialized\n[OK] Notification system started\n[OK] Theme: Dark applied\n", "/var/log")
mkf("/var/log/auth.log",          "[INFO] User "..player.Name.." authorized\n", "/var/log")

local function fsResolve(path)
    if path == "~" then return "/home/player" end
    if path:sub(1,2) == "~/" then
        path = "/home/player/" .. path:sub(3)
    end
    if path:sub(1,1) ~= "/" then
        path = (CWD == "/" and "/"..path) or (CWD.."/"..path)
    end
    local parts = {}
    for seg in path:gmatch("[^/]+") do
        if seg == ".." then table.remove(parts)
        elseif seg ~= "." then table.insert(parts, seg) end
    end
    return (#parts == 0 and "/") or ("/"..table.concat(parts,"/"))
end

local function fsRead(path)
    local nd = FS[fsResolve(path)]
    return nd and nd.t == "file" and nd.content or nil
end

local function fsWrite(path, content)
    local abs = fsResolve(path)
    if FS[abs] then
        FS[abs].content = content
        FS[abs].time = os.time()
    else
        FS[abs] = fsNew("file", content)
        local parentPath = abs:match("(.+)/[^/]+$") or "/"
        if FS[parentPath] and FS[parentPath].t == "dir" then
            table.insert(FS[parentPath].children, abs)
        end
    end
end

local function fsList(path)
    local node = FS[fsResolve(path)]
    return node and node.t == "dir" and node.children or nil
end

local function fsMkdir(path)
    local abs = fsResolve(path)
    if FS[abs] then return false, "already exists" end
    FS[abs] = fsNew("dir")
    local parentPath = abs:match("(.+)/[^/]+$") or "/"
    if FS[parentPath] and FS[parentPath].t == "dir" then
        table.insert(FS[parentPath].children, abs)
    end
    return true
end

-- ── KERNEL ───────────────────────────────────────────────────────
local Kernel = { procs={}, pid=1, boot=os.clock() }

local function kspawn(name, mem, sys)
    local id = Kernel.pid; Kernel.pid+=1
    Kernel.procs[id] = {
        pid=id, name=name, state="running",
        mem=mem or math.random(2,18), cpu=0,
        start=os.clock(), sys=sys or false
    }
    return id
end

local function kkill(pid)
    if not Kernel.procs[pid] then return false, "no process" end
    if Kernel.procs[pid].sys  then return false, "system process" end
    Kernel.procs[pid] = nil
    return true
end

kspawn("init",         0, true)
kspawn("kscheduler",   1, true)
kspawn("syslogd",      2, true)
kspawn("luaos-wm",     5, true)
kspawn("notifyd",      1, true)

RunService.Heartbeat:Connect(function(dt)
    for _, p in pairs(Kernel.procs) do
        p.cpu += dt * math.random(1,12)/100
    end
end)

-- ── DESKTOP ───────────────────────────────────────────────────
local desktop = c("Frame", {
    Size=UDim2.new(1,0,1,0),
    BackgroundColor3=T.bg1,
    BorderSizePixel=0,
    ZIndex=1,
}, gui)
local desktopGrad = gradient(desktop, T.gradA, T.gradB, 135)

-- Dot grid
local dots = c("Frame", {
    Size=UDim2.new(1,0,1,0),
    BackgroundTransparency=1,
    ZIndex=1,
}, desktop)

do
    local rows, cols = 20, 35
    for r=0, rows do
        for cc=0, cols do
            c("Frame", {
                Size=UDim2.new(0,2,0,2),
                Position=UDim2.new(cc/cols, 0, r/rows, 0),
                BackgroundColor3=T.dotCol,
                BackgroundTransparency=0.6,
                BorderSizePixel=0,
                ZIndex=1,
            }, dots)
        end
    end
end

-- ── WINDOWS SYSTEM ─────────────────────────────────────────────
local Z = 10
local WINS = {}
local OpenWinNames = {} -- for taskbar

local function makeDrag(handle, win)
    local drag, dstart, dpos = false, nil, nil
    handle.InputBegan:Connect(function(i)
        if i.UserInputType == Enum.UserInputType.MouseButton1 then
            drag=true; dstart=i.Position; dpos=win.Position
            i.Changed:Connect(function()
                if i.UserInputState==Enum.UserInputState.End then drag=false end
            end)
        end
    end)
    UIS.InputChanged:Connect(function(i)
        if drag and i.UserInputType==Enum.UserInputType.MouseMovement then
            local d=i.Position-dstart
            win.Position=UDim2.new(dpos.X.Scale, dpos.X.Offset+d.X,
                                   dpos.Y.Scale, dpos.Y.Offset+d.Y)
        end
    end)
end

local refreshTaskbar -- forward declare

local function newWindow(title, w, h, x, y)
    Z+=1
    local z = Z

    local win = c("Frame", {
        Size=UDim2.new(0,w,0,h),
        Position=UDim2.new(0,x or 200,0,y or 100),
        BackgroundColor3=T.surface,
        BorderSizePixel=0, ZIndex=z,
        ClipsDescendants=true,
    }, gui)
    corner(win, 10)
    stroke(win, T.accent, 1, .5)
    shadow(win, z)

    win.InputBegan:Connect(function(i)
        if i.UserInputType==Enum.UserInputType.MouseButton1 then
            Z+=1; win.ZIndex=Z
        end
    end)

    -- Title bar
    local bar = c("Frame", {
        Size=UDim2.new(1,0,0,38),
        BackgroundColor3=T.winTitle,
        BorderSizePixel=0, ZIndex=z+1,
    }, win)

    c("Frame", {
        Size=UDim2.new(1,0,0,1),
        Position=UDim2.new(0,0,1,-1),
        BackgroundColor3=T.accent,
        BackgroundTransparency=0.7,
        BorderSizePixel=0, ZIndex=z+2,
    }, bar)

    corner(bar, 10)
    c("Frame", {
        Size=UDim2.new(1,0,0.5,0),
        Position=UDim2.new(0,0,0.5,0),
        BackgroundColor3=T.winTitle,
        BorderSizePixel=0, ZIndex=z+1,
    }, bar)

    -- Control buttons (●●●)
    local function wbtn(col, xoff, sym, cb)
        local b = c("TextButton", {
            Size=UDim2.new(0,14,0,14),
            Position=UDim2.new(1,xoff,0.5,-7),
            BackgroundColor3=col,
            Text="", ZIndex=z+3, BorderSizePixel=0,
        }, bar)
        corner(b,7)
        local lbl=c("TextLabel", {
            Size=UDim2.new(1,0,1,0),
            BackgroundTransparency=1,
            Text=sym, TextColor3=Color3.new(0,0,0),
            Font=Enum.Font.GothamBold, TextSize=9,
            Visible=false, ZIndex=z+4,
        },b)
        b.MouseEnter:Connect(function() lbl.Visible=true  end)
        b.MouseLeave:Connect(function() lbl.Visible=false end)
        b.MouseButton1Click:Connect(cb)
        return b
    end

    local mini=false
    local maxi=false
    local orig=UDim2.new(0,w,0,h)
    local origPos=UDim2.new(0,x or 200,0,y or 100)
    local body

    -- Close
    wbtn(T.close, -22, "✕", function()
        tw(win,{Size=UDim2.new(0,w,0,0),BackgroundTransparency=1},.2)
        task.delay(.25, function()
            win:Destroy()
            WINS[title]=nil
            OpenWinNames[title]=nil
            if refreshTaskbar then refreshTaskbar() end
        end)
    end)

    -- Minimize
    wbtn(T.minimize, -40, "─", function()
        if mini then
            tw(win,{Size=orig},.2)
            if body then body.Visible=true end
            mini=false
        else
            tw(win,{Size=UDim2.new(0,w,0,38)},.2)
            task.delay(.15,function()
                if body then body.Visible=false end
            end)
            mini=true
        end
    end)

    -- Maximize (NEW)
    wbtn(T.maximize, -58, "□", function()
        if maxi then
            tw(win,{Size=orig, Position=origPos},.25)
            maxi=false
        else
            origPos=win.Position
            orig=win.Size
            tw(win,{Size=UDim2.new(1,0,1,-44), Position=UDim2.new(0,0,0,0)},.25)
            maxi=true
        end
        if mini then
            mini=false
            if body then body.Visible=true end
        end
    end)

    -- Title text
    c("TextLabel", {
        Size=UDim2.new(1,-120,1,0),
        Position=UDim2.new(0,14,0,0),
        BackgroundTransparency=1,
        Text=title, Font=Enum.Font.GothamBold,
        TextSize=13, TextColor3=T.text,
        TextXAlignment=Enum.TextXAlignment.Left,
        ZIndex=z+2,
    }, bar)

    body = c("Frame", {
        Size=UDim2.new(1,0,1,-38),
        Position=UDim2.new(0,0,0,38),
        BackgroundTransparency=1,
        ZIndex=z+1, ClipsDescendants=true,
    }, win)

    makeDrag(bar, win)

    -- Appear animation
    win.Size=UDim2.new(0,w,0,0)
    win.BackgroundTransparency=1
    tw(win,{Size=UDim2.new(0,w,0,h), BackgroundTransparency=0},.25,Enum.EasingStyle.Back)

    WINS[title]=win
    OpenWinNames[title]=true
    if refreshTaskbar then refreshTaskbar() end

    return win, body, z
end

-- ── TERMINAL COMMANDS ────────────────────────────────────────
local cmdHistory = {}

local Fortunes = {
    "Luck will smile on you today... or not.",
    "In the world of Lua, everything is possible, even the impossible.",
    "Error 404: luck not found. Try again later.",
    "Today is a good day for programming!",
    "It's not a bug, it's a feature. Remember that.",
    "The early bird gets to debug until noon.",
    "print('Hello World') — the beginning of great things.",
    "The best antivirus is common sense.",
    "Code is written once, but read a thousand times.",
    "Recursion: see Recursion.",
    "There are 10 types of people: those who understand binary and those who don't.",
    "Segfault? In Lua? Impossible!",
    "Patience and hard work will overcome everything... except an infinite loop.",
    "sudo make me a sandwich",
    "while true do sleep() end — the philosophy of life.",
}

local function runCmd(cmd, out)
    local args={}
    for a in cmd:gmatch("%S+") do table.insert(args,a) end
    local cc=args[1]
    if not cc or cc=="" then return end

    table.insert(cmdHistory, cmd)

    if cc=="help" then
        out("╔═══════════════════════════════════════════╗", T.accent)
        out("║       LuaOS Shell v3.0 — Help            ║", T.accent)
        out("╠═══════════════════════════════════════════╣", T.accent)
        out("║  File System:                             ║", T.accent2)
        out("║  ls [path]    — list files                ║", T.text)
        out("║  cd [path]    — change directory          ║", T.text)
        out("║  cat [file]   — read file                 ║", T.text)
        out("║  head [file]  — first 5 lines             ║", T.text)
        out("║  tail [file]  — last 5 lines              ║", T.text)
        out("║  echo [text]  — output / write > file     ║", T.text)
        out("║  touch [file] — create file               ║", T.text)
        out("║  mkdir [dir]  — create directory          ║", T.text)
        out("║  rm [file]    — delete file               ║", T.text)
        out("║  mv [a] [b]   — move                      ║", T.text)
        out("║  cp [a] [b]   — copy                      ║", T.text)
        out("║  wc [file]    — count lines/words         ║", T.text)
        out("║  grep [word] [file] — search              ║", T.text)
        out("║  tree [path]  — file tree                 ║", T.text)
        out("║  pwd          — current directory         ║", T.text)
        out("╠═══════════════════════════════════════════╣", T.accent2)
        out("║  System:                                  ║", T.accent2)
        out("║  ps           — processes                 ║", T.text)
        out("║  kill [pid]   — terminate process         ║", T.text)
        out("║  top          — CPU/RAM load              ║", T.text)
        out("║  mem          — RAM usage                 ║", T.text)
        out("║  uptime       — uptime                    ║", T.text)
        out("║  date         — date and time             ║", T.text)
        out("║  whoami       — username                  ║", T.text)
        out("║  hostname     — hostname                  ║", T.text)
        out("║  uname        — OS version                ║", T.text)
        out("║  neofetch     — system info               ║", T.text)
        out("║  history      — command history           ║", T.text)
        out("║  fortune      — random quote              ║", T.text)
        out("║  clear        — clear screen              ║", T.text)
        out("║  exit         — close terminal            ║", T.text)
        out("╚═══════════════════════════════════════════╝", T.accent)

    elseif cc=="neofetch" then
        local up=os.clock()-Kernel.boot
        local h=math.floor(up/3600)
        local m=math.floor(up%3600/60)
        local cnt=0; local mem=0
        for _,p in pairs(Kernel.procs) do cnt+=1; mem+=p.mem end

        out("", T.text)
        out("        ██╗     ██╗   ██╗ █████╗      "..player.Name.."@luaos", T.accent)
        out("        ██║     ██║   ██║██╔══██╗     ─────────────────", T.accent)
        out("        ██║     ██║   ██║███████║     OS:      LuaOS v3.0 Aurora", T.text)
        out("        ██║     ██║   ██║██╔══██║     Kernel:  Luau (Roblox)", T.text)
        out("        ███████╗╚██████╔╝██║  ██║     Uptime:  "..string.format("%02d:%02d", h, m), T.text)
        out("        ╚══════╝ ╚═════╝ ╚═╝  ╚═╝     Shell:   lsh 3.0", T.text)
        out("                                       Theme:   "..ActiveTheme, T.text)
        out("                                       Procs:   "..cnt, T.text)
        out("                                       RAM:     "..mem.."MB / 512MB", T.text)
        out("                                       Player:  "..player.DisplayName, T.text)
        out("                                       Game:    "..game.PlaceId, T.text)
        out("", T.text)
        -- Color palette
        local colors = "        "
        out(colors.."███ ███ ███ ███ ███ ███ ███ ███", T.accent)
        out("", T.text)

    elseif cc=="fortune" then
        out("🔮  "..Fortunes[math.random(#Fortunes)], T.yellow)

    elseif cc=="history" then
        out("  Command history:", T.accent)
        for i, cmd2 in ipairs(cmdHistory) do
            out(string.format("  %4d  %s", i, cmd2), T.text)
        end

    elseif cc=="tree" then
        local path = args[2] and fsResolve(args[2]) or CWD
        local function printTree(p, prefix)
            local nd = FS[p]
            if not nd or nd.t ~= "dir" then return end
            local ch = nd.children
            for i, cp in ipairs(ch) do
                local child = FS[cp]
                if not child then continue end
                local segs = cp:split("/")
                local nm = segs[#segs]
                local isLast = (i == #ch)
                local connector = isLast and "└── " or "├── "
                local icon = child.t == "dir" and "📁 " or "📄 "
                out(prefix .. connector .. icon .. nm, child.t == "dir" and T.accent2 or T.text)
                if child.t == "dir" then
                    local newPrefix = prefix .. (isLast and "    " or "│   ")
                    printTree(cp, newPrefix)
                end
            end
        end
        local segs = path:split("/")
        out("📂 " .. (segs[#segs] ~= "" and segs[#segs] or "/"), T.accent)
        printTree(path, "")

    elseif cc=="mkdir" then
        if not args[2] then out("mkdir: specify directory name", T.yellow); return end
        local ok, err = fsMkdir(args[2])
        if ok then
            out("Created directory: "..fsResolve(args[2]), T.textDim)
        else
            out("mkdir: "..tostring(err), T.red)
        end

    elseif cc=="mv" then
        if not args[2] or not args[3] then out("mv: specify source and destination", T.yellow); return end
        local src = fsResolve(args[2])
        local dst = fsResolve(args[3])
        if not FS[src] then out("mv: "..args[2]..": not found", T.red); return end
        FS[dst] = FS[src]
        FS[dst].time = os.time()
        FS[src] = nil
        -- Update parents
        for _, nd in pairs(FS) do
            if nd.t == "dir" then
                for i, ch in ipairs(nd.children) do
                    if ch == src then nd.children[i] = dst; break end
                end
            end
        end
        out("Moved: "..src.." → "..dst, T.textDim)

    elseif cc=="cp" then
        if not args[2] or not args[3] then out("cp: specify source and destination", T.yellow); return end
        local src = fsResolve(args[2])
        local dst = fsResolve(args[3])
        if not FS[src] or FS[src].t ~= "file" then out("cp: "..args[2]..": file not found", T.red); return end
        fsWrite(dst, FS[src].content)
        out("Copied: "..src.." → "..dst, T.textDim)

    elseif cc=="grep" then
        if not args[2] or not args[3] then out("grep: usage: grep [word] [file]", T.yellow); return end
        local pattern = args[2]
        local content = fsRead(fsResolve(args[3]))
        if not content then out("grep: "..args[3]..": file not found", T.red); return end
        local found = 0
        for _, ln in ipairs(content:split("\n")) do
            if ln:lower():find(pattern:lower()) then
                out(ln, T.green)
                found += 1
            end
        end
        if found == 0 then out("(no matches found)", T.textDim) end

    elseif cc=="head" then
        if not args[2] then out("head: specify file", T.yellow); return end
        local content = fsRead(fsResolve(args[2]))
        if not content then out("head: file not found", T.red); return end
        local lines = content:split("\n")
        local count = tonumber(args[3]) or 5
        for i = 1, math.min(count, #lines) do
            out(lines[i], T.text)
        end

    elseif cc=="tail" then
        if not args[2] then out("tail: specify file", T.yellow); return end
        local content = fsRead(fsResolve(args[2]))
        if not content then out("tail: file not found", T.red); return end
        local lines = content:split("\n")
        local count = tonumber(args[3]) or 5
        for i = math.max(1, #lines - count + 1), #lines do
            out(lines[i], T.text)
        end

    elseif cc=="wc" then
        if not args[2] then out("wc: specify file", T.yellow); return end
        local content = fsRead(fsResolve(args[2]))
        if not content then out("wc: file not found", T.red); return end
        local lines = #content:split("\n")
        local words = 0
        for _ in content:gmatch("%S+") do words += 1 end
        local bytes = #content
        out(string.format("  %d lines  %d words  %d bytes  %s", lines, words, bytes, args[2]), T.text)

    elseif cc=="ls" then
        local path = args[2] and fsResolve(args[2]) or CWD
        local ch = fsList(path)
        if not ch then out("ls: "..path..": no such path", T.red); return end
        if #ch==0 then out("(empty)", T.textDim); return end
        out("  " .. path .. ":", T.accent)
        for _, cp in ipairs(ch) do
            local nd=FS[cp]
            if nd then
                local segs=cp:split("/")
                local nm=segs[#segs]
                if nd.t=="dir" then
                    out("  📁  "..nm.."/", T.accent2)
                else
                    out(string.format("  📄  %-26s %dB", nm, #nd.content), T.text)
                end
            end
        end

    elseif cc=="cd" then
        local p = args[2] and fsResolve(args[2]) or "/home/player"
        if FS[p] and FS[p].t=="dir" then
            CWD=p; out("→ "..CWD, T.textDim)
        else
            out("cd: "..tostring(args[2])..": no such directory", T.red)
        end

    elseif cc=="pwd" then
        out(CWD, T.text)

    elseif cc=="cat" then
        if not args[2] then out("cat: specify file", T.yellow); return end
        local content=fsRead(fsResolve(args[2]))
        if content then
            for _,ln in ipairs(content:split("\n")) do out(ln, T.text) end
        else
            out("cat: "..args[2]..": file not found", T.red)
        end

    elseif cc=="echo" then
        local full=table.concat(args," ",2)
        local lpart, rpart=full:match("^(.-)%s*>%s*(.+)$")
        if lpart and rpart then
            fsWrite(fsResolve(rpart), lpart.."\n")
            out("Written → "..rpart, T.textDim)
        else
            out(full, T.text)
        end

    elseif cc=="touch" then
        if not args[2] then out("touch: specify filename", T.yellow); return end
        local abs=fsResolve(args[2])
        if not FS[abs] then
            fsWrite(abs,""); out("Created: "..abs, T.textDim)
        else
            out("File already exists", T.textDim)
        end

    elseif cc=="rm" then
        if not args[2] then out("rm: specify file", T.yellow); return end
        local abs=fsResolve(args[2])
        if not FS[abs] then out("rm: file not found", T.red); return end
        if FS[abs].t=="dir" then out("rm: this is a directory (use rm -r)", T.red); return end
        FS[abs]=nil
        for _, nd in pairs(FS) do
            if nd.t=="dir" then
                for i,ch in ipairs(nd.children) do
                    if ch==abs then table.remove(nd.children,i); break end
                end
            end
        end
        out("Deleted: "..abs, T.textDim)

    elseif cc=="ps" then
        out(string.format("  %-5s  %-22s  %-10s  %s","PID","NAME","STATUS","RAM"), T.accent)
        out("  "..("─"):rep(52), T.textMut)
        local sorted={}
        for _,p in pairs(Kernel.procs) do table.insert(sorted,p) end
        table.sort(sorted,function(a,b) return a.pid<b.pid end)
        for _,p in ipairs(sorted) do
            out(string.format("  %-5s  %-22s  %-10s  %dMB",
                p.pid, p.name, p.state, p.mem), p.state=="running" and T.green or T.textDim)
        end

    elseif cc=="kill" then
        local pid=tonumber(args[2])
        if not pid then out("kill: specify PID", T.yellow); return end
        local ok, err=kkill(pid)
        if ok then out("Process "..pid.." terminated ✓", T.green)
        else out("kill: "..tostring(err), T.red) end

    elseif cc=="top" then
        local total=512; local used=0; local cnt=0
        for _,p in pairs(Kernel.procs) do used+=p.mem; cnt+=1 end
        local pct=math.floor(used/total*100)
        local up=os.clock()-Kernel.boot
        out("── System Load ────────────────────────────", T.accent)
        out(string.format("  Uptime:    %.0f sec", up), T.text)
        out(string.format("  Processes: %d", cnt), T.text)
        out(string.format("  RAM:       %d / %d MB (%d%%)", used, total, pct), T.text)
        local bar=("█"):rep(math.floor(pct/5))..("░"):rep(20-math.floor(pct/5))
        out("  ["..bar.."]", pct>80 and T.red or pct>50 and T.yellow or T.green)

    elseif cc=="mem" then
        local total=512; local used=0
        for _,p in pairs(Kernel.procs) do used+=p.mem end
        local pct=math.floor(used/total*100)
        out(string.format("RAM: %dMB / %dMB  (%d%% used)", used, total, pct), T.text)
        out("["..("█"):rep(math.floor(pct/5))..("░"):rep(20-math.floor(pct/5)).."]", pct>80 and T.red or T.accent)

    elseif cc=="uptime" then
        local up=os.clock()-Kernel.boot
        out(string.format("Uptime: %02d:%02d:%02d", math.floor(up/3600), math.floor(up%3600/60), math.floor(up%60)), T.text)

    elseif cc=="date" then
        out(os.date("Date: %m/%d/%Y   Time: %H:%M:%S"), T.text)

    elseif cc=="whoami" then out(player.Name, T.text)
    elseif cc=="hostname" then out(fsRead("/etc/hostname") or "luaos", T.text)
    elseif cc=="uname" then out("LuaOS 3.0.0 Aurora (Luau/"..os.date("%Y")..") enhanced-edition", T.text)
    elseif cc=="clear" then return "clear"
    elseif cc=="exit" then return "exit"
    else
        out("lsh: "..cc..": command not found. Type 'help'", T.red)
    end
end

-- ── FORWARD DECLARATIONS ──────────────────────────────────────
local openTerminal, openNotepad, openTaskManager, openBrowser, openFiles
local openCalc, openSettings, openSysMonitor

-- ── TERMINAL ───────────────────────────────────────────────────
openTerminal = function()
    if WINS["Terminal"] and WINS["Terminal"].Parent then
        WINS["Terminal"].Visible=true; return
    end

    local win,body,z = newWindow("  ⌨  Terminal", 650, 460, 100, 60)

    local tbg = c("Frame", {
        Size=UDim2.new(1,0,1,0),
        BackgroundColor3=T.term,
        BorderSizePixel=0, ZIndex=z+1,
    }, body)

    local outScroll = c("ScrollingFrame", {
        Size=UDim2.new(1,0,1,-44),
        BackgroundTransparency=1, BorderSizePixel=0,
        ScrollBarThickness=3, ScrollBarImageColor3=T.accent,
        AutomaticCanvasSize=Enum.AutomaticSize.Y,
        CanvasSize=UDim2.new(0,0,0,0), ZIndex=z+2,
    }, tbg)
    c("UIListLayout", {Padding=UDim.new(0,1)}, outScroll)
    pad(outScroll, 10)

    local function addOut(txt, col)
        local lbl = c("TextLabel", {
            Size=UDim2.new(1,0,0,0),
            AutomaticSize=Enum.AutomaticSize.Y,
            BackgroundTransparency=1, Text=txt,
            Font=Enum.Font.Code, TextSize=13,
            TextColor3=col or T.termTxt,
            TextXAlignment=Enum.TextXAlignment.Left,
            TextWrapped=true, ZIndex=z+3,
        }, outScroll)
        task.defer(function()
            outScroll.CanvasPosition=Vector2.new(0,outScroll.AbsoluteCanvasSize.Y)
        end)
        return lbl
    end

    local inputRow = c("Frame", {
        Size=UDim2.new(1,0,0,40), Position=UDim2.new(0,0,1,-40),
        BackgroundColor3=Color3.fromRGB(10,12,24),
        BorderSizePixel=0, ZIndex=z+2,
    }, tbg)

    c("Frame", {
        Size=UDim2.new(1,0,0,1),
        BackgroundColor3=T.accent, BackgroundTransparency=0.7,
        BorderSizePixel=0, ZIndex=z+3,
    }, inputRow)

    local promptLbl = c("TextLabel", {
        Size=UDim2.new(0,0,1,0), AutomaticSize=Enum.AutomaticSize.X,
        Position=UDim2.new(0,10,0,0), BackgroundTransparency=1,
        Text=player.Name.."@luaos:"..CWD.."$ ",
        Font=Enum.Font.Code, TextSize=13, TextColor3=T.accent2, ZIndex=z+3,
    }, inputRow)

    local inputBox = c("TextBox", {
        Size=UDim2.new(1,-200,1,-8), Position=UDim2.new(0,180,0,4),
        BackgroundTransparency=1, Text="", PlaceholderText="enter command...",
        PlaceholderColor3=T.textMut, Font=Enum.Font.Code, TextSize=13,
        TextColor3=T.termTxt, TextXAlignment=Enum.TextXAlignment.Left,
        ClearTextOnFocus=false, ZIndex=z+3,
    }, inputRow)

    addOut("╔══════════════════════════════════════════════╗", T.accent)
    addOut("║        LuaOS Terminal v3.0 Aurora            ║", T.accent)
    addOut("║   Kernel: Luau   Platform: Roblox           ║", T.textDim)
    addOut("║   New: neofetch, tree, grep, mkdir, fortune ║", T.textDim)
    addOut("╚══════════════════════════════════════════════╝", T.accent)
    addOut("", T.text)
    addOut(fsRead("/etc/motd") or "", T.text)

    local hist={}; local hidx=0

    inputBox.FocusLost:Connect(function(enter)
        if not enter then return end
        local cmd2=inputBox.Text; inputBox.Text=""
        if cmd2=="" then return end
        table.insert(hist,cmd2); hidx=#hist+1
        addOut(player.Name.."@luaos:"..CWD.."$ "..cmd2, T.textDim)
        local r=runCmd(cmd2, addOut)
        if r=="clear" then
            for _,ch in ipairs(outScroll:GetChildren()) do
                if ch:IsA("TextLabel") then ch:Destroy() end
            end
        elseif r=="exit" then
            win:Destroy(); WINS["Terminal"]=nil; OpenWinNames["Terminal"]=nil
            if refreshTaskbar then refreshTaskbar() end
        end
        promptLbl.Text=player.Name.."@luaos:"..CWD.."$ "
        task.defer(function() inputBox:CaptureFocus() end)
    end)

    UIS.InputBegan:Connect(function(i,gp)
        if gp or not inputBox:IsFocused() then return end
        if i.KeyCode==Enum.KeyCode.Up then
            hidx=math.max(1,hidx-1); inputBox.Text=hist[hidx] or ""
        elseif i.KeyCode==Enum.KeyCode.Down then
            hidx=math.min(#hist+1,hidx+1); inputBox.Text=hist[hidx] or ""
        end
    end)

    task.defer(function() inputBox:CaptureFocus() end)
    kspawn("lsh", 3)
end

-- ── NOTEPAD ────────────────────────────────────────────────────
openNotepad = function()
    if WINS["Notepad"] and WINS["Notepad"].Parent then WINS["Notepad"].Visible=true; return end

    local win,body,z = newWindow("  📝  Notepad", 540, 420, 160, 90)
    local curFile = "/home/player/readme.txt"

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.surface,
        BorderSizePixel=0,ZIndex=z+1},body)

    local tb=c("Frame",{Size=UDim2.new(1,0,0,36),
        BackgroundColor3=T.surface2,BorderSizePixel=0,ZIndex=z+2},bg)

    local fileLbl=c("TextLabel",{
        Size=UDim2.new(1,-200,1,0),Position=UDim2.new(0,8,0,0),
        BackgroundTransparency=1,Text="📄 "..curFile,
        Font=Enum.Font.Gotham,TextSize=11,TextColor3=T.textDim,
        TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+3},tb)

    local saveBtn=c("TextButton",{
        Size=UDim2.new(0,90,0,26), Position=UDim2.new(1,-100,0.5,-13),
        BackgroundColor3=T.surface, Text="💾 Save",TextColor3=T.text,
        Font=Enum.Font.Gotham,TextSize=12, ZIndex=z+3,BorderSizePixel=0},tb)
    corner(saveBtn,5); stroke(saveBtn,T.border,1,.5)
    hover(saveBtn,T.surface,T.surface2)

    local ta=c("TextBox",{
        Size=UDim2.new(1,-16,1,-52), Position=UDim2.new(0,8,0,44),
        BackgroundColor3=T.bg1, Text=fsRead(curFile) or "",
        TextColor3=T.text, Font=Enum.Font.Code,TextSize=13,
        TextXAlignment=Enum.TextXAlignment.Left,
        TextYAlignment=Enum.TextYAlignment.Top,
        MultiLine=true,ClearTextOnFocus=false,
        TextWrapped=true,ZIndex=z+2,BorderSizePixel=0},bg)
    corner(ta,6); pad(ta,8); stroke(ta,T.border,1,.5)

    saveBtn.MouseButton1Click:Connect(function()
        fsWrite(curFile, ta.Text)
        fileLbl.Text="📄 "..curFile.."  ✓ Saved"
        notify("Notepad", "File saved: "..curFile, 3, "💾")
        task.delay(2,function() fileLbl.Text="📄 "..curFile end)
    end)
end

-- ── TASK MANAGER ─────────────────────────────────────────────
openTaskManager = function()
    if WINS["Task Manager"] and WINS["Task Manager"].Parent then
        WINS["Task Manager"].Visible=true; return
    end

    local win,body,z = newWindow("  📊  Task Manager", 520, 400, 200, 110)

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.surface,
        BorderSizePixel=0,ZIndex=z+1},body)

    local hdr=c("Frame",{Size=UDim2.new(1,0,0,30),
        BackgroundColor3=T.winTitle,BorderSizePixel=0,ZIndex=z+2},bg)
    stroke(hdr, T.border, 1, .5)

    local cols={
        {t="PID", w=.10, x=0},
        {t="Process",w=.38,x=.10},
        {t="Status",w=.22, x=.48},
        {t="RAM", w=.15, x=.70},
        {t="",   w=.15, x=.85},
    }
    for _,col in ipairs(cols) do
        c("TextLabel",{
            Size=UDim2.new(col.w,0,1,0), Position=UDim2.new(col.x,8,0,0),
            BackgroundTransparency=1, Text=col.t,Font=Enum.Font.GothamBold,TextSize=12,
            TextColor3=T.accent2,TextXAlignment=Enum.TextXAlignment.Left,
            ZIndex=z+3},hdr)
    end

    local list=c("ScrollingFrame",{
        Size=UDim2.new(1,0,1,-80), Position=UDim2.new(0,0,0,30),
        BackgroundTransparency=1,BorderSizePixel=0,
        ScrollBarThickness=3,ScrollBarImageColor3=T.accent,
        AutomaticCanvasSize=Enum.AutomaticSize.Y,
        CanvasSize=UDim2.new(0,0,0,0),ZIndex=z+2},bg)
    c("UIListLayout",{Padding=UDim.new(0,2)},list)
    pad(list,4)

    local rows={}

    local function refresh()
        for _,r in ipairs(rows) do r:Destroy() end; rows={}
        local sorted={}
        for _,p in pairs(Kernel.procs) do table.insert(sorted,p) end
        table.sort(sorted,function(a,b) return a.pid<b.pid end)

        for i,p in ipairs(sorted) do
            local row=c("Frame",{
                Size=UDim2.new(1,0,0,30),
                BackgroundColor3=i%2==0 and T.surface2 or T.surface,
                BorderSizePixel=0,ZIndex=z+3},list)
            corner(row,5)

            local datas={tostring(p.pid), p.name, p.state, p.mem.."MB"}
            for ci,col in ipairs(cols) do
                if ci <= 4 then
                    c("TextLabel",{
                        Size=UDim2.new(col.w,0,1,0), Position=UDim2.new(col.x,8,0,0),
                        BackgroundTransparency=1, Text=datas[ci],
                        Font=Enum.Font.Code,TextSize=12,
                        TextColor3=ci==3 and (p.state=="running" and T.green or T.textDim) or T.text,
                        TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+4},row)
                end
            end

            -- Kill button
            if not p.sys then
                local kb=c("TextButton",{
                    Size=UDim2.new(0,44,0,20), Position=UDim2.new(.85,4,0.5,-10),
                    BackgroundColor3=T.red, Text="Kill",
                    TextColor3=Color3.new(1,1,1), Font=Enum.Font.GothamBold,
                    TextSize=10, ZIndex=z+4, BorderSizePixel=0},row)
                corner(kb,4)
                kb.MouseButton1Click:Connect(function()
                    kkill(p.pid)
                    notify("Task Manager", "Process "..p.name.." terminated", 3, "📊")
                end)
            end

            table.insert(rows,row)
        end
    end

    local statBar=c("Frame",{
        Size=UDim2.new(1,0,0,46), Position=UDim2.new(0,0,1,-46),
        BackgroundColor3=T.winTitle, BorderSizePixel=0,ZIndex=z+2},bg)

    local statLbl=c("TextLabel",{
        Size=UDim2.new(1,-16,1,0),Position=UDim2.new(0,8,0,0),
        BackgroundTransparency=1,Text="",
        Font=Enum.Font.Code,TextSize=11,TextColor3=T.textDim,
        TextXAlignment=Enum.TextXAlignment.Left, RichText=true,ZIndex=z+3},statBar)

    local ramBg=c("Frame",{
        Size=UDim2.new(1,-16,0,4),Position=UDim2.new(0,8,0,38),
        BackgroundColor3=T.surface,BorderSizePixel=0,ZIndex=z+2},statBar)
    corner(ramBg,2)
    local ramBar=c("Frame",{
        Size=UDim2.new(0,0,0,4),Position=UDim2.new(0,8,0,38),
        BackgroundColor3=T.accent,BorderSizePixel=0,ZIndex=z+3},statBar)
    corner(ramBar,2)

    local conn=RunService.Heartbeat:Connect(function()
        local total=512; local used=0; local cnt=0
        for _,p in pairs(Kernel.procs) do used+=p.mem; cnt+=1 end
        local pct=math.floor(used/total*100)
        statLbl.Text=string.format("Processes: %d  │  RAM: %dMB/%dMB (%d%%)  │  ▲ %ds",
            cnt, used, total, pct, math.floor(os.clock()-Kernel.boot))
        tw(ramBar,{Size=UDim2.new(used/total,0,0,4)},.3)
        ramBar.BackgroundColor3=pct>80 and T.red or pct>50 and T.yellow or T.accent
    end)

    task.spawn(function()
        while win and win.Parent do refresh(); task.wait(0.5) end
        conn:Disconnect()
    end)
    refresh()
end

-- ── BROWSER ────────────────────────────────────────────────────
openBrowser = function()
    if WINS["Browser"] and WINS["Browser"].Parent then WINS["Browser"].Visible=true; return end

    local win,body,z = newWindow("  🌐  LuaSearch Browser", 600, 440, 180, 80)

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),
        BackgroundColor3=Color3.fromRGB(235,238,255),
        BorderSizePixel=0,ZIndex=z+1},body)

    local addrRow=c("Frame",{
        Size=UDim2.new(1,-16,0,36), Position=UDim2.new(0,8,0,6),
        BackgroundColor3=Color3.new(1,1,1),
        BorderSizePixel=0,ZIndex=z+2},bg)
    corner(addrRow,18); stroke(addrRow,T.accent,1,.3)

    local addrBox=c("TextBox",{
        Size=UDim2.new(1,-24,1,0),Position=UDim2.new(0,12,0,0),
        BackgroundTransparency=1, Text="luaos://home",
        Font=Enum.Font.Gotham,TextSize=13,
        TextColor3=Color3.fromRGB(30,40,80),
        ClearTextOnFocus=false,ZIndex=z+3},addrRow)

    local page=c("ScrollingFrame",{
        Size=UDim2.new(1,-16,1,-54), Position=UDim2.new(0,8,0,48),
        BackgroundColor3=Color3.new(1,1,1), BorderSizePixel=0,
        ScrollBarThickness=4, AutomaticCanvasSize=Enum.AutomaticSize.Y,
        CanvasSize=UDim2.new(0,0,0,0),ZIndex=z+2},bg)
    corner(page,8); stroke(page,T.border,1,.5)
    c("UIListLayout",{Padding=UDim.new(0,6)},page)
    pad(page,14)

    local pages={
        ["luaos://home"]={
            {h=1, t="🏠 LuaOS Browser v3.0"},
            {h=0, t="Welcome to the built-in LuaOS Browser!"},
            {h=2, t="Pages:"},
            {lnk="luaos://about"}, {lnk="luaos://docs"},
            {lnk="luaos://filesystem"}, {lnk="luaos://changelog"},
            {lnk="luaos://games"},
        },
        ["luaos://about"]={
            {h=1, t="ℹ️ About LuaOS"},
            {h=0, t="Version:    LuaOS 3.0.0 Aurora"},
            {h=0, t="Kernel:     Luau (Roblox Runtime)"},
            {h=0, t="Build:      Enhanced Edition"},
            {h=0, t="Codename:   Aurora"},
            {h=0, t="Started:    "..os.date("%H:%M:%S %m/%d/%Y")},
            {h=0, t="Player:     "..player.Name.." ("..player.DisplayName..")"},
            {h=0, t="UserID:     "..player.UserId},
            {lnk="luaos://home"},
        },
        ["luaos://docs"]={
            {h=1, t="📚 Documentation"},
            {h=2, t="Terminal — all commands:"},
            {h=0, t="  help, ls, cd, cat, head, tail, echo, touch, mkdir"},
            {h=0, t="  rm, mv, cp, wc, grep, tree, pwd"},
            {h=0, t="  ps, kill, top, mem, uptime, date"},
            {h=0, t="  whoami, hostname, uname, neofetch"},
            {h=0, t="  history, fortune, clear, exit"},
            {h=2, t="Applications:"},
            {h=0, t="  Terminal, Notepad, Task Manager"},
            {h=0, t="  Browser, Files, Calculator"},
            {h=0, t="  Settings, System Monitor"},
            {lnk="luaos://home"},
        },
        ["luaos://filesystem"]={
            {h=1, t="📁 File System"},
            {h=0, t="  /bin            — system utilities"},
            {h=0, t="  /etc            — configuration"},
            {h=0, t="  /home/player    — your folder"},
            {h=0, t="  /home/player/Documents — documents"},
            {h=0, t="  /home/player/Music     — music"},
            {h=0, t="  /tmp            — temporary files"},
            {h=0, t="  /var/log        — logs"},
            {lnk="luaos://home"},
        },
        ["luaos://changelog"]={
            {h=1, t="📋 Changelog"},
            {h=2, t="v3.0.0 Aurora:"},
            {h=0, t="  + 3 themes: Dark, Hacker, Sakura"},
            {h=0, t="  + Calculator"},
            {h=0, t="  + System monitor"},
            {h=0, t="  + Notification system (toasts)"},
            {h=0, t="  + Maximize window button"},
            {h=0, t="  + Taskbar shows open windows"},
            {h=0, t="  + 12 new terminal commands"},
            {h=0, t="  + neofetch with ASCII art"},
            {h=0, t="  + tree — file tree"},
            {h=0, t="  + grep, head, tail, wc, mkdir, mv, cp"},
            {h=0, t="  + fortune — random quotes"},
            {h=0, t="  + history — command history"},
            {h=0, t="  + Kill buttons in task manager"},
            {h=2, t="v2.0.0:"},
            {h=0, t="  + First release"},
            {lnk="luaos://home"},
        },
        ["luaos://games"]={
            {h=1, t="🎮 Mini-games"},
            {h=0, t="Coming soon! In the next version:"},
            {h=0, t="  • Guess the number"},
            {h=0, t="  • Tic-tac-toe"},
            {h=0, t="  • Snake"},
            {lnk="luaos://home"},
        },
    }

    local function render(url)
        for _,ch in ipairs(page:GetChildren()) do
            if ch:IsA("GuiObject") then ch:Destroy() end
        end
        local pg=pages[url]
        if not pg then
            c("TextLabel",{Size=UDim2.new(1,0,0,40),BackgroundTransparency=1,
                Text="404 — Page not found",
                Font=Enum.Font.GothamBold,TextSize=16,
                TextColor3=Color3.fromRGB(200,40,40),
                TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+3},page)
            return
        end
        for _,item in ipairs(pg) do
            if item.lnk then
                local b=c("TextButton",{
                    Size=UDim2.new(1,0,0,28),
                    BackgroundColor3=Color3.fromRGB(230,238,255),
                    Text="🔗  "..item.lnk,
                    Font=Enum.Font.Gotham,TextSize=13,
                    TextColor3=Color3.fromRGB(20,80,220),
                    TextXAlignment=Enum.TextXAlignment.Left,
                    BorderSizePixel=0,ZIndex=z+3},page)
                corner(b,5); pad(b,6)
                b.MouseButton1Click:Connect(function() addrBox.Text=item.lnk; render(item.lnk) end)
            elseif item.h==1 then
                c("TextLabel",{Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,
                    BackgroundTransparency=1,Text=item.t,
                    Font=Enum.Font.GothamBold,TextSize=22,
                    TextColor3=Color3.fromRGB(20,60,180),
                    TextXAlignment=Enum.TextXAlignment.Left,TextWrapped=true,ZIndex=z+3},page)
            elseif item.h==2 then
                c("TextLabel",{Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,
                    BackgroundTransparency=1,Text=item.t,
                    Font=Enum.Font.GothamBold,TextSize=15,
                    TextColor3=Color3.fromRGB(50,100,200),
                    TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+3},page)
            else
                c("TextLabel",{Size=UDim2.new(1,0,0,0),AutomaticSize=Enum.AutomaticSize.Y,
                    BackgroundTransparency=1,Text=item.t,
                    Font=Enum.Font.Code,TextSize=13,
                    TextColor3=Color3.fromRGB(30,40,70),
                    TextXAlignment=Enum.TextXAlignment.Left,TextWrapped=true,ZIndex=z+3},page)
            end
        end
    end
    render("luaos://home")
    addrBox.FocusLost:Connect(function(e) if e then render(addrBox.Text) end end)
end

-- ── FILE MANAGER ──────────────────────────────────────────────
openFiles = function()
    if WINS["Files"] and WINS["Files"].Parent then WINS["Files"].Visible=true; return end

    local win,body,z = newWindow("  📁  File Manager", 500, 420, 220, 100)
    local viewPath="/"

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.surface,
        BorderSizePixel=0,ZIndex=z+1},body)

    local bread=c("Frame",{Size=UDim2.new(1,0,0,34),
        BackgroundColor3=T.surface2,BorderSizePixel=0,ZIndex=z+2},bg)

    local pathLbl=c("TextLabel",{
        Size=UDim2.new(1,-8,1,0),Position=UDim2.new(0,8,0,0),
        BackgroundTransparency=1, Text="📂 /",
        Font=Enum.Font.Gotham,TextSize=12,TextColor3=T.text,
        TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+3},bread)

    local flist=c("ScrollingFrame",{
        Size=UDim2.new(1,-16,1,-50), Position=UDim2.new(0,8,0,40),
        BackgroundTransparency=1,BorderSizePixel=0,
        ScrollBarThickness=3,ScrollBarImageColor3=T.accent,
        AutomaticCanvasSize=Enum.AutomaticSize.Y,
        CanvasSize=UDim2.new(0,0,0,0),ZIndex=z+2},bg)
    c("UIListLayout",{Padding=UDim.new(0,3)},flist)

    local function renderDir(path)
        viewPath=path; pathLbl.Text="📂 "..path
        for _,ch in ipairs(flist:GetChildren()) do
            if ch:IsA("GuiObject") then ch:Destroy() end
        end

        if path~="/" then
            local segs=path:split("/"); table.remove(segs)
            local par=table.concat(segs,"/"); if par=="" then par="/" end
            local upb=c("TextButton",{Size=UDim2.new(1,0,0,34),
                BackgroundColor3=T.surface2, Text="",BorderSizePixel=0,ZIndex=z+3},flist)
            corner(upb,6)
            c("TextLabel",{Size=UDim2.new(1,-10,1,0),Position=UDim2.new(0,10,0,0),
                BackgroundTransparency=1, Text="⬆   ..",
                Font=Enum.Font.Gotham,TextSize=13,TextColor3=T.accent2,
                TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+4},upb)
            hover(upb,T.surface2,T.surface)
            upb.MouseButton1Click:Connect(function() renderDir(par) end)
        end

        local nd=FS[path]
        if not nd then return end
        for _,cp in ipairs(nd.children) do
            local child=FS[cp]
            if not child then continue end
            local segs=cp:split("/"); local nm=segs[#segs]
            local isDir=child.t=="dir"

            local row=c("TextButton",{Size=UDim2.new(1,0,0,34),
                BackgroundColor3=T.surface, Text="",BorderSizePixel=0,ZIndex=z+3},flist)
            corner(row,6); stroke(row,T.border,1,.6)
            hover(row,T.surface,T.surface2)

            c("TextLabel",{Size=UDim2.new(1,-10,1,0),Position=UDim2.new(0,10,0,0),
                BackgroundTransparency=1,
                Text=(isDir and "📁  " or "📄  ")..nm,
                Font=Enum.Font.Gotham,TextSize=13,
                TextColor3=isDir and T.accent2 or T.text,
                TextXAlignment=Enum.TextXAlignment.Left,ZIndex=z+4},row)

            if not isDir then
                c("TextLabel",{Size=UDim2.new(0,60,1,0),Position=UDim2.new(1,-65,0,0),
                    BackgroundTransparency=1, Text=#child.content.."B",
                    Font=Enum.Font.Code,TextSize=11,TextColor3=T.textMut, ZIndex=z+4},row)
            end

            row.MouseButton1Click:Connect(function()
                if isDir then renderDir(cp) end
            end)
        end
    end
    renderDir("/")
end

-- ── CALCULATOR (NEW) ───────────────────────────────────────────
openCalc = function()
    if WINS["Calculator"] and WINS["Calculator"].Parent then
        WINS["Calculator"].Visible=true; return
    end

    local win,body,z = newWindow("  🧮  Calculator", 280, 400, 300, 100)

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.bg1,
        BorderSizePixel=0,ZIndex=z+1},body)

    -- Display
    local display=c("TextLabel",{
        Size=UDim2.new(1,-16,0,70), Position=UDim2.new(0,8,0,8),
        BackgroundColor3=T.surface, Text="0",
        Font=Enum.Font.Code, TextSize=32, TextColor3=T.text,
        TextXAlignment=Enum.TextXAlignment.Right,
        ZIndex=z+2, BorderSizePixel=0},bg)
    corner(display,8); pad(display,12)

    local expr = ""
    local lastResult = ""

    local function updateDisplay()
        display.Text = (expr == "" and "0") or expr
    end

    local buttons = {
        {"C", "⌫", "%", "÷"},
        {"7", "8", "9", "×"},
        {"4", "5", "6", "-"},
        {"1", "2", "3", "+"},
        {"±", "0", ".", "="},
    }

    local grid = c("Frame",{
        Size=UDim2.new(1,-16,1,-96), Position=UDim2.new(0,8,0,86),
        BackgroundTransparency=1, ZIndex=z+1},bg)

    for ri, row in ipairs(buttons) do
        for ci, label in ipairs(row) do
            local isOp = (label == "÷" or label == "×" or label == "-" or label == "+" or label == "=")
            local isSpecial = (label == "C" or label == "⌫" or label == "%" or label == "±")

            local btnColor = isOp and T.accent or isSpecial and T.surface2 or T.surface
            local txtColor = isOp and Color3.new(1,1,1) or T.text

            local btn = c("TextButton",{
                Size = UDim2.new(0.25, -6, 0.2, -6),
                Position = UDim2.new((ci-1)*0.25, 3, (ri-1)*0.2, 3),
                BackgroundColor3 = btnColor,
                Text = label,
                Font = Enum.Font.GothamBold,
                TextSize = 20,
                TextColor3 = txtColor,
                ZIndex = z+2,
                BorderSizePixel = 0,
            }, grid)
            corner(btn, 8)

            btn.MouseButton1Click:Connect(function()
                if label == "C" then
                    expr = ""; updateDisplay()
                elseif label == "⌫" then
                    expr = expr:sub(1, -2); updateDisplay()
                elseif label == "±" then
                    if expr:sub(1,1) == "-" then
                        expr = expr:sub(2)
                    else
                        expr = "-" .. expr
                    end
                    updateDisplay()
                elseif label == "=" then
                    local eval = expr:gsub("×","*"):gsub("÷","/")
                    local fn = loadstring("return " .. eval)
                    if fn then
                        local ok, result = pcall(fn)
                        if ok then
                            lastResult = tostring(result)
                            display.Text = lastResult
                            expr = lastResult
                        else
                            display.Text = "Error"
                            expr = ""
                        end
                    else
                        display.Text = "Error"
                        expr = ""
                    end
                else
                    expr = expr .. label
                    updateDisplay()
                end
            end)
        end
    end
    kspawn("calc", 2)
end

-- ── SETTINGS (NEW) ─────────────────────────────────────────────
openSettings = function()
    if WINS["Settings"] and WINS["Settings"].Parent then
        WINS["Settings"].Visible=true; return
    end

    local win,body,z = newWindow("  ⚙  Settings", 420, 380, 250, 100)

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.surface,
        BorderSizePixel=0,ZIndex=z+1},body)

    c("TextLabel",{
        Size=UDim2.new(1,-16,0,30), Position=UDim2.new(0,8,0,10),
        BackgroundTransparency=1, Text="🎨 Choose a theme",
        Font=Enum.Font.GothamBold, TextSize=16, TextColor3=T.text,
        TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+2},bg)

    local themeList = c("Frame",{
        Size=UDim2.new(1,-16,0,280), Position=UDim2.new(0,8,0,48),
        BackgroundTransparency=1, ZIndex=z+1},bg)
    c("UIListLayout",{Padding=UDim.new(0,8)},themeList)

    local themeData = {
        {name="Dark", desc="Classic dark theme", icon="🌙", preview={Color3.fromRGB(8,10,22), Color3.fromRGB(88,130,255)}},
        {name="Hacker", desc="Matrix. Green code.", icon="💻", preview={Color3.fromRGB(2,4,2), Color3.fromRGB(0,255,65)}},
        {name="Sakura", desc="Soft pink theme", icon="🌸", preview={Color3.fromRGB(25,10,18), Color3.fromRGB(255,100,160)}},
    }

    for _, td in ipairs(themeData) do
        local row = c("Frame",{
            Size=UDim2.new(1,0,0,75),
            BackgroundColor3=T.surface2,
            BorderSizePixel=0, ZIndex=z+2},themeList)
        corner(row,10); stroke(row, T.border, 1, .4)

        -- Color preview
        local preview = c("Frame",{
            Size=UDim2.new(0,50,0,50), Position=UDim2.new(0,12,0.5,-25),
            BackgroundColor3=td.preview[1], BorderSizePixel=0, ZIndex=z+3},row)
        corner(preview,8); stroke(preview, td.preview[2], 2, 0)

        c("TextLabel",{
            Size=UDim2.new(0,30,0,30), Position=UDim2.new(0,10,0,10),
            BackgroundTransparency=1, Text=td.icon,
            TextSize=24, ZIndex=z+4},preview)

        c("TextLabel",{
            Size=UDim2.new(1,-160,0,22), Position=UDim2.new(0,74,0,12),
            BackgroundTransparency=1, Text=td.name,
            Font=Enum.Font.GothamBold, TextSize=16, TextColor3=T.text,
            TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+3},row)

        c("TextLabel",{
            Size=UDim2.new(1,-160,0,18), Position=UDim2.new(0,74,0,36),
            BackgroundTransparency=1, Text=td.desc,
            Font=Enum.Font.Gotham, TextSize=12, TextColor3=T.textDim,
            TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+3},row)

        local active = (ActiveTheme == td.name)
        local applyBtn = c("TextButton",{
            Size=UDim2.new(0,80,0,30), Position=UDim2.new(1,-92,0.5,-15),
            BackgroundColor3=active and T.green or T.accentDk,
            Text=active and "✓ Active" or "Apply",
            TextColor3=Color3.new(1,1,1),
            Font=Enum.Font.GothamBold, TextSize=12,
            ZIndex=z+3, BorderSizePixel=0},row)
        corner(applyBtn,6)

        applyBtn.MouseButton1Click:Connect(function()
            if Themes[td.name] then
                ActiveTheme = td.name
                T = Themes[td.name]
                notify("Settings", "Theme '"..td.name.."' applied!\nRestart script for full effect.", 5, "🎨")
            end
        end)
    end
end

-- ── SYSTEM MONITOR (NEW) ─────────────────────────────────────
openSysMonitor = function()
    if WINS["Monitor"] and WINS["Monitor"].Parent then
        WINS["Monitor"].Visible=true; return
    end

    local win,body,z = newWindow("  📈  System Monitor", 380, 340, 280, 120)

    local bg=c("Frame",{Size=UDim2.new(1,0,1,0),BackgroundColor3=T.surface,
        BorderSizePixel=0,ZIndex=z+1},body)

    local labels = {}
    local info = {
        {lbl="OS:", key="os"},
        {lbl="Version:", key="ver"},
        {lbl="Kernel:", key="kern"},
        {lbl="Uptime:", key="up"},
        {lbl="Processes:", key="procs"},
        {lbl="RAM:", key="ram"},
        {lbl="Player:", key="player"},
        {lbl="Display:", key="display"},
        {lbl="Game ID:", key="game"},
        {lbl="FPS:", key="fps"},
    }

    for i, item in ipairs(info) do
        c("TextLabel",{
            Size=UDim2.new(0,100,0,24), Position=UDim2.new(0,12,0,10+(i-1)*28),
            BackgroundTransparency=1, Text=item.lbl,
            Font=Enum.Font.GothamBold, TextSize=13, TextColor3=T.accent2,
            TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+2},bg)

        labels[item.key] = c("TextLabel",{
            Size=UDim2.new(1,-130,0,24), Position=UDim2.new(0,115,0,10+(i-1)*28),
            BackgroundTransparency=1, Text="...",
            Font=Enum.Font.Code, TextSize=13, TextColor3=T.text,
            TextXAlignment=Enum.TextXAlignment.Left, ZIndex=z+2},bg)
    end

    local lastTick = os.clock()
    local fps = 60

    local conn = RunService.Heartbeat:Connect(function(dt)
        fps = math.floor(1/dt)
    end)

    task.spawn(function()
        while win and win.Parent do
            local up = os.clock()-Kernel.boot
            local cnt=0; local mem=0
            for _,p in pairs(Kernel.procs) do cnt+=1; mem+=p.mem end

            labels.os.Text = "LuaOS 3.0.0 Aurora"
            labels.ver.Text = "3.0.0 Enhanced"
            labels.kern.Text = "Luau (Roblox Runtime)"
            labels.up.Text = string.format("%02d:%02d:%02d", math.floor(up/3600), math.floor(up%3600/60), math.floor(up%60))
            labels.procs.Text = tostring(cnt)
            labels.ram.Text = string.format("%dMB / 512MB (%d%%)", mem, math.floor(mem/512*100))
            labels.player.Text = player.DisplayName.." (@"..player.Name..")"
            labels.display.Text = player.DisplayName
            labels.game.Text = tostring(game.PlaceId)
            labels.fps.Text = tostring(fps).." FPS"

            task.wait(0.5)
        end
        conn:Disconnect()
    end)
end

-- ── DESKTOP ICONS ──────────────────────────────────────────────
local ICONS={
    {lbl="Terminal",  ico="⌨",  fn=openTerminal,    pos=UDim2.new(0,18,0,18)},
    {lbl="Notepad",   ico="📝", fn=openNotepad,     pos=UDim2.new(0,18,0,112)},
    {lbl="Tasks",     ico="📊", fn=openTaskManager,  pos=UDim2.new(0,18,0,206)},
    {lbl="Browser",   ico="🌐", fn=openBrowser,      pos=UDim2.new(0,18,0,300)},
    {lbl="Files",     ico="📁", fn=openFiles,        pos=UDim2.new(0,18,0,394)},
    {lbl="Calculator",ico="🧮",fn=openCalc,         pos=UDim2.new(0,110,0,18)},
    {lbl="Settings",  ico="⚙",  fn=openSettings,     pos=UDim2.new(0,110,0,112)},
    {lbl="Monitor",   ico="📈", fn=openSysMonitor,   pos=UDim2.new(0,110,0,206)},
}

for _,ic in ipairs(ICONS) do
    local fr=c("Frame",{
        Size=UDim2.new(0,76,0,82), Position=ic.pos,
        BackgroundColor3=T.surface, BackgroundTransparency=0.3,
        BorderSizePixel=0,ZIndex=2},desktop)
    corner(fr,10); stroke(fr,T.border,1,.4)

    c("TextLabel",{Size=UDim2.new(1,0,0,48),Position=UDim2.new(0,0,0,4),
        BackgroundTransparency=1,Text=ic.ico,
        Font=Enum.Font.GothamBold,TextSize=30,ZIndex=3},fr)

    c("TextLabel",{Size=UDim2.new(1,-4,0,26),Position=UDim2.new(0,2,0,50),
        BackgroundTransparency=1,Text=ic.lbl,
        Font=Enum.Font.Gotham,TextSize=10,TextColor3=T.text,
        TextWrapped=true,ZIndex=3},fr)

    local btn=c("TextButton",{Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,
        Text="",ZIndex=4},fr)

    btn.MouseEnter:Connect(function()
        tw(fr,{BackgroundTransparency=0.1, BackgroundColor3=T.surface2})
    end)
    btn.MouseLeave:Connect(function()
        tw(fr,{BackgroundTransparency=0.3, BackgroundColor3=T.surface})
    end)
    btn.MouseButton1Click:Connect(ic.fn)
end

-- ── TASKBAR ───────────────────────────────────────────────────
local taskbar=c("Frame",{
    Size=UDim2.new(1,0,0,44), Position=UDim2.new(0,0,1,-44),
    BackgroundColor3=T.bg1, BorderSizePixel=0,ZIndex=50},gui)

c("Frame",{Size=UDim2.new(1,0,0,1),
    BackgroundColor3=T.accent,BackgroundTransparency=0.6,
    BorderSizePixel=0,ZIndex=51},taskbar)

-- Start button
local startBtn=c("TextButton",{
    Size=UDim2.new(0,90,0,32), Position=UDim2.new(0,6,0.5,-16),
    BackgroundColor3=T.accentDk, Text="⊞  START",
    TextColor3=Color3.new(1,1,1), Font=Enum.Font.GothamBold,TextSize=14,
    ZIndex=51,BorderSizePixel=0},taskbar)
corner(startBtn,6)

-- Open windows on taskbar
local taskWinArea = c("Frame",{
    Size=UDim2.new(0,500,0,32), Position=UDim2.new(0,106,0.5,-16),
    BackgroundTransparency=1, ZIndex=51},taskbar)
c("UIListLayout",{
    FillDirection=Enum.FillDirection.Horizontal,
    Padding=UDim.new(0,4),
},taskWinArea)

refreshTaskbar = function()
    for _,ch in ipairs(taskWinArea:GetChildren()) do
        if ch:IsA("TextButton") then ch:Destroy() end
    end
    for title, _ in pairs(OpenWinNames) do
        if WINS[title] and WINS[title].Parent then
            local short = title:gsub("^%s+",""):sub(1,12)
            local tb = c("TextButton",{
                Size=UDim2.new(0,90,1,0),
                BackgroundColor3=T.surface2,
                Text=short, TextColor3=T.text,
                Font=Enum.Font.Gotham, TextSize=11,
                ZIndex=52, BorderSizePixel=0,
            },taskWinArea)
            corner(tb,5)
            hover(tb, T.surface2, T.surface)
            tb.MouseButton1Click:Connect(function()
                local w = WINS[title]
                if w then w.Visible=true; Z+=1; w.ZIndex=Z end
            end)
        end
    end
end

-- Clock
local clockFrame=c("Frame",{
    Size=UDim2.new(0,90,1,0), Position=UDim2.new(1,-96,0,0),
    BackgroundTransparency=1,ZIndex=51},taskbar)

local clockMain=c("TextLabel",{
    Size=UDim2.new(1,0,0,22),Position=UDim2.new(0,0,0,4),
    BackgroundTransparency=1, Text=os.date("%H:%M"),
    Font=Enum.Font.GothamBold,TextSize=16,TextColor3=T.text,
    ZIndex=52},clockFrame)

local clockDate=c("TextLabel",{
    Size=UDim2.new(1,0,0,14),Position=UDim2.new(0,0,0,24),
    BackgroundTransparency=1, Text=os.date("%m/%d/%Y"),
    Font=Enum.Font.Gotham,TextSize=11,TextColor3=T.textDim,
    ZIndex=52},clockFrame)

task.spawn(function()
    while gui and gui.Parent do
        task.wait(1)
        clockMain.Text=os.date("%H:%M")
        clockDate.Text=os.date("%m/%d/%Y")
    end
end)

-- Logo
c("TextLabel",{
    Size=UDim2.new(0,80,1,0), Position=UDim2.new(0.5,-40,0,0),
    BackgroundTransparency=1, Text="LuaOS",
    Font=Enum.Font.GothamBold,TextSize=13,TextColor3=T.textMut,
    ZIndex=51},taskbar)

-- ── START MENU ─────────────────────────────────────────────────
local smOpen=false
local sm=c("Frame",{
    Size=UDim2.new(0,280,0,460),
    Position=UDim2.new(0,-290,1,-44),
    BackgroundColor3=T.bg2,
    BorderSizePixel=0,ZIndex=60, Visible=false},gui)
corner(sm,12); stroke(sm,T.accent,1,.4)

local smHead=c("Frame",{
    Size=UDim2.new(1,0,0,70),
    BackgroundColor3=T.accentDk,
    BorderSizePixel=0,ZIndex=61},sm)
corner(smHead,12)
c("Frame",{Size=UDim2.new(1,0,0.5,0),Position=UDim2.new(0,0,0.5,0),
    BackgroundColor3=T.accentDk,BorderSizePixel=0,ZIndex=61},smHead)

c("TextLabel",{
    Size=UDim2.new(1,-12,0,28),Position=UDim2.new(0,12,0,10),
    BackgroundTransparency=1, Text="👤  "..player.Name,
    Font=Enum.Font.GothamBold,TextSize=16,TextColor3=T.text,
    TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62},smHead)

c("TextLabel",{
    Size=UDim2.new(1,-12,0,16),Position=UDim2.new(0,12,0,40),
    BackgroundTransparency=1, Text="LuaOS 3.0.0 Aurora — Enhanced Edition",
    Font=Enum.Font.Gotham,TextSize=11,TextColor3=Color3.fromRGB(160,190,255),
    TextXAlignment=Enum.TextXAlignment.Left,ZIndex=62},smHead)

local smApps={
    {ico="⌨",  lbl="Terminal",          fn=openTerminal},
    {ico="📝", lbl="Notepad",            fn=openNotepad},
    {ico="📊", lbl="Task Manager",       fn=openTaskManager},
    {ico="🌐", lbl="Browser",            fn=openBrowser},
    {ico="📁", lbl="File Manager",       fn=openFiles},
    {ico="🧮", lbl="Calculator",         fn=openCalc},
    {ico="⚙",  lbl="Settings",           fn=openSettings},
    {ico="📈", lbl="System Monitor",     fn=openSysMonitor},
}

local smList=c("Frame",{
    Size=UDim2.new(1,-12,0,300),
    Position=UDim2.new(0,6,0,76),
    BackgroundTransparency=1,ZIndex=61},sm)
c("UIListLayout",{Padding=UDim.new(0,3)},smList)

for _,app in ipairs(smApps) do
    local row=c("TextButton",{
        Size=UDim2.new(1,0,0,34),
        BackgroundColor3=T.bg2,
        Text="",BorderSizePixel=0,ZIndex=62},smList)
    corner(row,7); hover(row,T.bg2,T.surface)

    c("TextLabel",{Size=UDim2.new(0,36,1,0),Position=UDim2.new(0,8,0,0),
        BackgroundTransparency=1,Text=app.ico,
        Font=Enum.Font.GothamBold,TextSize=18,ZIndex=63},row)

    c("TextLabel",{Size=UDim2.new(1,-50,1,0),Position=UDim2.new(0,46,0,0),
        BackgroundTransparency=1,Text=app.lbl,
        Font=Enum.Font.Gotham,TextSize=13,TextColor3=T.text,
        TextXAlignment=Enum.TextXAlignment.Left,ZIndex=63},row)

    row.MouseButton1Click:Connect(function()
        smOpen=false
        tw(sm,{Position=UDim2.new(0,-290,1,-44)},.2)
        task.delay(.21,function() sm.Visible=false end)
        app.fn()
    end)
end

-- Separator
c("Frame",{Size=UDim2.new(1,-12,0,1),Position=UDim2.new(0,6,0,385),
    BackgroundColor3=T.border,BackgroundTransparency=.4,
    BorderSizePixel=0,ZIndex=61},sm)

-- Shutdown button
local shutBtn=c("TextButton",{
    Size=UDim2.new(1,-12,0,40), Position=UDim2.new(0,6,0,394),
    BackgroundColor3=Color3.fromRGB(160,30,30),
    Text="⏻   Shutdown LuaOS",
    TextColor3=Color3.new(1,1,1),
    Font=Enum.Font.GothamBold,TextSize=13,
    ZIndex=62,BorderSizePixel=0},sm)
corner(shutBtn,7)
hover(shutBtn,Color3.fromRGB(160,30,30),Color3.fromRGB(210,45,45))

shutBtn.MouseButton1Click:Connect(function()
    smOpen=false; sm.Visible=false
    local ov=c("Frame",{
        Size=UDim2.new(1,0,1,0),
        BackgroundColor3=Color3.new(0,0,0),
        BackgroundTransparency=1, ZIndex=9999},gui)
    tw(ov,{BackgroundTransparency=0},1)
    task.delay(1,function()
        c("TextLabel",{
            Size=UDim2.new(1,0,0,60),Position=UDim2.new(0,0,0.42,0),
            BackgroundTransparency=1, Text="LuaOS has shut down",
            Font=Enum.Font.GothamBold,TextSize=22,
            TextColor3=T.accent,ZIndex=10000},ov)
        c("TextLabel",{
            Size=UDim2.new(1,0,0,30),Position=UDim2.new(0,0,0.52,0),
            BackgroundTransparency=1, Text="v3.0.0 Aurora — Thanks for using!",
            Font=Enum.Font.Gotham,TextSize=14,
            TextColor3=T.textDim,ZIndex=10000},ov)
    end)
    task.delay(4,function() gui:Destroy() end)
end)

-- Start menu logic
local function toggleSM()
    smOpen=not smOpen
    if smOpen then
        sm.Visible=true
        sm.Position=UDim2.new(0,-290,1,-44)
        tw(sm,{Position=UDim2.new(0,6,1,-sm.Size.Y.Offset-44)},.22,Enum.EasingStyle.Back)
    else
        tw(sm,{Position=UDim2.new(0,-290,1,-44)},.18)
        task.delay(.2,function() sm.Visible=false end)
    end
end

startBtn.MouseButton1Click:Connect(toggleSM)
hover(startBtn, T.accentDk, T.accent)

desktop.InputBegan:Connect(function(i)
    if smOpen and i.UserInputType==Enum.UserInputType.MouseButton1 then
        smOpen=false
        tw(sm,{Position=UDim2.new(0,-290,1,-44)},.18)
        task.delay(.2,function() sm.Visible=false end)
    end
end)

-- ── BOOT SCREEN ─────────────────────────────────────────────
local boot=c("Frame",{
    Size=UDim2.new(1,0,1,0),
    BackgroundColor3=Color3.fromRGB(3,4,10),
    ZIndex=9000},gui)

local bootLogo=c("TextLabel",{
    Size=UDim2.new(1,0,0,90), Position=UDim2.new(0,0,0.35,0),
    BackgroundTransparency=1, Text="LuaOS",
    Font=Enum.Font.GothamBold,TextSize=72,
    TextColor3=T.accent,ZIndex=9001},boot)

local bootSub=c("TextLabel",{
    Size=UDim2.new(1,0,0,24), Position=UDim2.new(0,0,0.35,90),
    BackgroundTransparency=1, Text="v3.0.0 Aurora  ·  Enhanced Edition",
    Font=Enum.Font.Gotham,TextSize=16,
    TextColor3=T.textDim,ZIndex=9001},boot)

local bootVer=c("TextLabel",{
    Size=UDim2.new(1,0,0,20), Position=UDim2.new(0,0,0.35,115),
    BackgroundTransparency=1, Text="Powered by Luau Runtime",
    Font=Enum.Font.Gotham,TextSize=12,
    TextColor3=T.textMut,ZIndex=9001},boot)

local pbBg=c("Frame",{
    Size=UDim2.new(0,360,0,4), Position=UDim2.new(0.5,-180,0.72,0),
    BackgroundColor3=T.surface2, BorderSizePixel=0,ZIndex=9001},boot)
corner(pbBg,2)

local pbFill=c("Frame",{
    Size=UDim2.new(0,0,1,0),
    BackgroundColor3=T.accent,
    BorderSizePixel=0,ZIndex=9002},pbBg)
corner(pbFill,2)

local pbStatus=c("TextLabel",{
    Size=UDim2.new(0,360,0,20), Position=UDim2.new(0.5,-180,0.72,10),
    BackgroundTransparency=1, Text="Initializing...",
    Font=Enum.Font.Code,TextSize=12,
    TextColor3=T.textMut,ZIndex=9001},boot)

local steps={
    {t="Initializing kernel v3.0...",      p=0.12},
    {t="Mounting file system...",          p=0.26},
    {t="Loading theme: "..ActiveTheme.."...", p=0.38},
    {t="Starting system services...",      p=0.52},
    {t="Initializing window manager...",   p=0.64},
    {t="Starting notification system...",  p=0.76},
    {t="Authenticating "..player.Name.."...", p=0.90},
    {t="Ready! Welcome.",                  p=1.00},
}

task.spawn(function()
    for _,s in ipairs(steps) do
        pbStatus.Text=s.t
        tw(pbFill,{Size=UDim2.new(s.p,0,1,0)},.4)
        task.wait(.38)
    end
    task.wait(.3)

    local function fadeOut(obj)
        if obj:IsA("TextLabel") then tw(obj,{TextTransparency=1},.5) end
        if obj:IsA("Frame") or obj:IsA("TextLabel") then
            tw(obj,{BackgroundTransparency=1},.5)
        end
        for _,ch in ipairs(obj:GetChildren()) do fadeOut(ch) end
    end

    fadeOut(bootLogo); fadeOut(bootSub); fadeOut(bootVer)
    fadeOut(pbBg); fadeOut(pbStatus)
    task.wait(.3)
    tw(boot,{BackgroundTransparency=1},.5)
    task.wait(.55)
    boot:Destroy()

    -- Welcome notification
    task.delay(0.5, function()
        notify("Welcome!", "LuaOS v3.0 Aurora loaded.\n"..player.DisplayName..", enjoy!", 5, "👋")
    end)
end)

Features & Information

LuaOS v3.0 Aurora - Full Desktop OS for Roblox yeah so i made a whole operating system that runs in roblox executors. it's actually pretty sick what's included: got 3 themes you can swap between - dark mode, hacker green (matrix style), and this pink sakura theme that looks clean af apps: terminal with like 25+ actual working commands notepad to write stuff task manager where you can see processes and kill them fake browser with pages file explorer calculator that actually works system monitor showing fps and ram settings to change themes the terminal is legit supports commands like ls, cd, cat, grep, mkdir, rm, mv, cp, neofetch (yes theres neofetch lol), tree, ps, kill, top, and a bunch more. even has command history with arrow keys other stuff: windows can be dragged around, minimized, maximized taskbar at the bottom shows what's open notifications pop up has a whole file system you can navigate process manager running in background cool boot animation when it starts start menu like windows clock that actually updates basically spent way too much time making this way more detailed than it needed to be but whatever, it works pretty well how to use: paste the whole thing into your executor and run it. works on synapse, krnl, fluxus, delta, whatever you got it's all in english, well organized code if you wanna look through it or modify stuff

Community Comments (1)

chillingchillingFeb 23, 2026

yeah that it

More Scripts for Universal Scripts