diff --git a/README.md b/README.md index 1c5c7dd..7b17232 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # Installer -CLI installation tool that automates the installation, removal and maintenance of themes. +GUI/CLI installation tool that automates the installation, removal and maintenance of themes. diff --git a/discord.ps1 b/cli/discord.ps1 similarity index 100% rename from discord.ps1 rename to cli/discord.ps1 diff --git a/steam.ps1 b/cli/steam.ps1 similarity index 100% rename from steam.ps1 rename to cli/steam.ps1 diff --git a/gui/main.js b/gui/main.js new file mode 100644 index 0000000..dd4112b --- /dev/null +++ b/gui/main.js @@ -0,0 +1,244 @@ +const { app, BrowserWindow, ipcMain } = require('electron'); +const path = require('path'); +const fs = require('fs'); +const https = require('https'); +const AdmZip = require('adm-zip'); + +function createWindow() { + const win = new BrowserWindow({ + width: 750, + height: 500, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + preload: path.join(__dirname, 'src/preload.js') + }, + icon: path.join(__dirname, 'src/assets/logo.png'), + frame: false, + transparent: true, + backgroundColor: '#00000000', + autoHideMenuBar: true, + resizable: false + }); + + win.loadFile('src/index.html'); +} + +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +ipcMain.on('start-installation', async (event, data) => { + const appData = process.env.APPDATA; + + function sendLog(message) { + console.log('Debug:', message); + event.reply('installation-logs', [message]); + } + + sendLog('Preparing installation...'); + await delay(1000); + + if (data.theme === 'DiscordTheme') { + const betterDiscordPath = path.join(appData, 'BetterDiscord', 'themes'); + const vencordPath = path.join(appData, 'Vencord', 'themes'); + const vencordThemePath = path.join(vencordPath, 'SpaceTheme.theme.css'); + const betterDiscordThemePath = path.join(betterDiscordPath, 'SpaceTheme.theme.css'); + const themeUrl = 'https://raw.githubusercontent.com/SpaceTheme/Discord/refs/heads/main/SpaceTheme.theme.css'; + + async function installTheme(themePath, clientName) { + try { + if (!fs.existsSync(themePath)) { + fs.mkdirSync(themePath, { recursive: true }); + sendLog(`Created directory for ${clientName}`); + } + + const themeFile = path.join(themePath, 'SpaceTheme.theme.css'); + const file = fs.createWriteStream(themeFile); + + return new Promise((resolve, reject) => { + sendLog(`Downloading theme for ${clientName}...`); + https.get(themeUrl, response => { + response.pipe(file); + file.on('finish', () => { + sendLog(`SpaceTheme.theme.css downloaded successfully in ${themePath}`); + file.close(); + sendLog(`SpaceTheme installed successfully for ${clientName}`); + resolve(); + }); + }).on('error', error => { + sendLog(`Error downloading theme for ${clientName}: ${error.message}`); + reject(error); + }); + }); + } catch (error) { + sendLog(`Error installing theme for ${clientName}: ${error.message}`); + throw error; + } + } + + try { + if (data.option === 'uninstall-theme') { + let uninstalled = false; + if (fs.existsSync(vencordThemePath)) { + fs.unlinkSync(vencordThemePath); + sendLog('SpaceTheme uninstalled successfully from Vencord'); + uninstalled = true; + } + if (fs.existsSync(betterDiscordThemePath)) { + fs.unlinkSync(betterDiscordThemePath); + sendLog('SpaceTheme uninstalled successfully from BetterDiscord'); + uninstalled = true; + } + if (!uninstalled) { + sendLog('Discord theme not found in any supported client'); + } + return; + } + + if (data.option === 'reset-theme') { + sendLog('Starting theme reset process...'); + if (fs.existsSync(vencordThemePath)) { + fs.unlinkSync(vencordThemePath); + sendLog('Removed existing Vencord theme'); + } + if (fs.existsSync(betterDiscordThemePath)) { + fs.unlinkSync(betterDiscordThemePath); + sendLog('Removed existing BetterDiscord theme'); + } + } + + let installed = false; + if (fs.existsSync(betterDiscordPath)) { + await installTheme(betterDiscordPath, 'BetterDiscord'); + installed = true; + } + if (fs.existsSync(vencordPath)) { + await installTheme(vencordPath, 'Vencord'); + installed = true; + } + if (!installed) { + sendLog('Neither BetterDiscord nor Vencord is installed. Please install one of them first.'); + } + } catch (error) { + sendLog(`Installation failed: ${error.message}`); + } + + } else if (data.theme === 'SteamTheme') { + await delay(1000); + + const skinsFolder = 'C:\\Program Files (x86)\\Steam\\steamui\\skins'; + const destinationFolder = path.join(skinsFolder, 'SpaceTheme for Steam'); + const tempPath = path.join(process.env.TEMP, 'SpaceTheme_for_Steam.zip'); + const extractedFolderPath = path.join(skinsFolder, 'Steam-main'); + + function cleanup() { + try { + if (fs.existsSync(tempPath)) { + fs.unlinkSync(tempPath); + } + if (fs.existsSync(extractedFolderPath)) { + fs.rmSync(extractedFolderPath, { recursive: true, force: true }); + } + } catch (error) { + sendLog(`Cleanup error: ${error.message}`); + } + } + + try { + if (data.option === 'uninstall-theme') { + sendLog('Starting Steam theme uninstallation...'); + sendLog('Trying to see if you have SteamTheme installed...'); + if (fs.existsSync(destinationFolder)) { + fs.rmSync(destinationFolder, { recursive: true, force: true }); + sendLog('SteamTheme path was found and deleted!'); + sendLog('SpaceTheme uninstalled successfully for Steam.'); + } else { + sendLog('Steam theme not found'); + } + return; + } + + if (data.option === 'reset-theme') { + sendLog('Starting Steam theme reset...'); + if (fs.existsSync(destinationFolder)) { + fs.rmSync(destinationFolder, { recursive: true, force: true }); + sendLog('Removed existing Steam theme installation'); + sendLog('Starting installation...'); + } else { + sendLog('No existing Steam theme found, proceeding with installation...'); + } + } + + if (!fs.existsSync(skinsFolder)) { + sendLog('Steam skins folder not found. Please install Steam first.'); + return; + } + + sendLog('Downloading SpaceTheme for Steam...'); + const file = fs.createWriteStream(tempPath); + + await new Promise((resolve, reject) => { + sendLog('Checking website availability...'); + https.get('https://github.com/SpaceTheme/Steam/archive/refs/heads/main.zip', response => { + if (response.statusCode === 302 || response.statusCode === 301) { + https.get(response.headers.location, redirectResponse => { + if (redirectResponse.statusCode !== 200) { + reject(new Error(`Download failed with status ${redirectResponse.statusCode}`)); + return; + } + redirectResponse.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + }).on('error', reject); + } else if (response.statusCode === 200) { + response.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + } else { + reject(new Error(`Unexpected status code: ${response.statusCode}`)); + } + }).on('error', reject); + }); + + sendLog('Website is available for you!'); + sendLog(`SpaceTheme for Steam was successfully installed in ${tempPath} folder.`); + sendLog('Extracting files... '); + const zip = new AdmZip(tempPath); + zip.extractAllTo(skinsFolder, true); + sendLog(`SpaceTheme for Steam was successfully extracted to ${skinsFolder} folder.`); + + if (fs.existsSync(extractedFolderPath)) { + fs.renameSync(extractedFolderPath, destinationFolder); + sendLog('SpaceTheme installed successfully for Steam.'); + } else { + throw new Error('Failed to extract theme files'); + } + } catch (error) { + sendLog(`Error during Steam theme operation: ${error.message}`); + } finally { + cleanup(); + } + } +}); + +ipcMain.on('close-window', () => { + const win = BrowserWindow.getFocusedWindow(); + if (win) win.close(); +}); + +app.whenReady().then(createWindow); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); diff --git a/gui/package.json b/gui/package.json new file mode 100644 index 0000000..5baf538 --- /dev/null +++ b/gui/package.json @@ -0,0 +1,36 @@ +{ + "name": "spacetheme-installer", + "private": true, + "version": "1.0.1", + "main": "main.js", + "scripts": { + "start": "electron .", + "build": "electron-builder" + }, + "dependencies": { + "adm-zip": "^0.5.16" + }, + "keywords": [], + "author": "", + "license": "MIT", + "description": "", + "build": { + "appId": "com.noxy.st-installer", + "productName": "SpaceTheme-Installer", + "copyright": "Copyright © 2024 SpaceTheme", + "win": { + "target": [ + "nsis", + "portable" + ], + "icon": "src/assets/logo.png" + }, + "directories": { + "buildResources": "public" + } + }, + "devDependencies": { + "electron": "^29.1.0", + "electron-builder": "^25.1.8" + } +} diff --git a/gui/src/assets/arrow-left-disabled.svg b/gui/src/assets/arrow-left-disabled.svg new file mode 100644 index 0000000..e5ef17e --- /dev/null +++ b/gui/src/assets/arrow-left-disabled.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/arrow-left.svg b/gui/src/assets/arrow-left.svg new file mode 100644 index 0000000..741a6e0 --- /dev/null +++ b/gui/src/assets/arrow-left.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/arrow-right-disabled.svg b/gui/src/assets/arrow-right-disabled.svg new file mode 100644 index 0000000..e7f8ad5 --- /dev/null +++ b/gui/src/assets/arrow-right-disabled.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/arrow-right.svg b/gui/src/assets/arrow-right.svg new file mode 100644 index 0000000..b01f107 --- /dev/null +++ b/gui/src/assets/arrow-right.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/checkmark.svg b/gui/src/assets/checkmark.svg new file mode 100644 index 0000000..3e6cba5 --- /dev/null +++ b/gui/src/assets/checkmark.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/close-icon.svg b/gui/src/assets/close-icon.svg new file mode 100644 index 0000000..ade0b03 --- /dev/null +++ b/gui/src/assets/close-icon.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/gui/src/assets/discord.svg b/gui/src/assets/discord.svg new file mode 100644 index 0000000..8e68cbd --- /dev/null +++ b/gui/src/assets/discord.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/donate.svg b/gui/src/assets/donate.svg new file mode 100644 index 0000000..4136659 --- /dev/null +++ b/gui/src/assets/donate.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/github.svg b/gui/src/assets/github.svg new file mode 100644 index 0000000..1731e64 --- /dev/null +++ b/gui/src/assets/github.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/installation-icon.svg b/gui/src/assets/installation-icon.svg new file mode 100644 index 0000000..f4f0e94 --- /dev/null +++ b/gui/src/assets/installation-icon.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/installdone-disabled.svg b/gui/src/assets/installdone-disabled.svg new file mode 100644 index 0000000..6e5a7bf --- /dev/null +++ b/gui/src/assets/installdone-disabled.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/installdone.svg b/gui/src/assets/installdone.svg new file mode 100644 index 0000000..6e5a7bf --- /dev/null +++ b/gui/src/assets/installdone.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/logo.ico b/gui/src/assets/logo.ico new file mode 100644 index 0000000..a00e712 Binary files /dev/null and b/gui/src/assets/logo.ico differ diff --git a/gui/src/assets/logo.png b/gui/src/assets/logo.png new file mode 100644 index 0000000..09fbdd1 Binary files /dev/null and b/gui/src/assets/logo.png differ diff --git a/gui/src/assets/minimize-icon.svg b/gui/src/assets/minimize-icon.svg new file mode 100644 index 0000000..cb3aeaa --- /dev/null +++ b/gui/src/assets/minimize-icon.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/mit-icon.svg b/gui/src/assets/mit-icon.svg new file mode 100644 index 0000000..f3a0bad --- /dev/null +++ b/gui/src/assets/mit-icon.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/assets/website.svg b/gui/src/assets/website.svg new file mode 100644 index 0000000..3a3aab9 --- /dev/null +++ b/gui/src/assets/website.svg @@ -0,0 +1,7 @@ + + + Created with Pixso. + + + + diff --git a/gui/src/index.html b/gui/src/index.html new file mode 100644 index 0000000..22203f6 --- /dev/null +++ b/gui/src/index.html @@ -0,0 +1,150 @@ + + + + + + SpaceTheme Installer + + + + + +
+
+
+
+
Space
+
Theme
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ MIT License +
+ +
+
MIT License + +Copyright (c) 2024 SpaceTheme + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
+
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/gui/src/logs.html b/gui/src/logs.html new file mode 100644 index 0000000..82ae83f --- /dev/null +++ b/gui/src/logs.html @@ -0,0 +1,159 @@ + + + + + + SpaceTheme Installer + + + + + +
+
+
+
+
Space
+
Theme
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ Installation +
+
+
+
+ + +
+
+
+ + + + + \ No newline at end of file diff --git a/gui/src/preload.js b/gui/src/preload.js new file mode 100644 index 0000000..d5095e7 --- /dev/null +++ b/gui/src/preload.js @@ -0,0 +1,5 @@ +const { ipcRenderer } = require('electron'); + +window.closeWindow = () => ipcRenderer.send('close-window'); + +console.log('preload script finally loaded!'); \ No newline at end of file diff --git a/gui/src/select-theme.html b/gui/src/select-theme.html new file mode 100644 index 0000000..d71bc0d --- /dev/null +++ b/gui/src/select-theme.html @@ -0,0 +1,196 @@ + + + + + + SpaceTheme Installer + + + + + +
+
+
+
+
Space
+
Theme
+
+
+
+ +
+
+
+ +
+
+
+ Select theme + + +
+ + + +
+
+
Please select a theme to install
+
+ +
+
Please select a theme to reset
+
+ +
+
Please select a theme to uninstall
+
+
+
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/gui/src/style.css b/gui/src/style.css new file mode 100644 index 0000000..f9d4bad --- /dev/null +++ b/gui/src/style.css @@ -0,0 +1,485 @@ +@import url('https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + user-select: none; +} + +body { + background-color: rgba(0,0,0,0); + font-family: Be Vietnam Pro; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + color: #fff; + overflow: hidden; +} + + +*::-webkit-scrollbar { + width: 14px !important; +} + +*::-webkit-scrollbar-track { + border-radius: 8px !important; +} + +*::-webkit-scrollbar-thumb { + border-radius: 8px !important; + border: 4px solid transparent !important; + background-clip: content-box !important; + background-color: rgb(102, 108, 255) !important; +} + +*::-webkit-scrollbar-thumb:hover { + border: 3px solid transparent !important; + background-color: rgb(135, 140, 255) !important; +} + + +.window { + width: 750px; + height: 500px; + background-color: rgb(10, 10, 10); + display: flex; + flex-direction: column; + border: 2px solid rgb(60, 58, 61); + border-radius: 10px; + overflow: hidden; +} + +.everything { + display: flex; + flex-direction: column; + flex: 1; +} + +.title-bar { + padding: 12px 16px; + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgb(10, 10, 10); + -webkit-app-region: drag; + height: 48px; +} + +.title { + font-size: 18px; + line-height: 123%; + letter-spacing: 0%; + text-align: center; + flex-direction: row; + display: flex; +} + +.title-first { + color: rgb(135, 140, 255); + font-weight: 500; +} + +.title-second { + color: rgb(102, 108, 255); + font-weight: 900; +} + +.window-controls { + -webkit-app-region: no-drag; + display: flex; + gap: 16px; +} + +.closeButt { + cursor: pointer; + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; +} + +.close-icon { + width: 16px; + height: 16px; +} + +.main-content { + flex: 1; + padding: 0 16px 16px; + display: flex; + flex-direction: column; + gap: 16px; + background-color: rgb(10, 10, 10); +} + +.outer-container { + background-color: rgb(17, 17, 17); + border-radius: 8px; + padding: 16px; + display: flex; + flex-direction: column; + gap: 16px; + flex: 1; +} + + + +.license-header { + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgb(17, 17, 17); +} + +.license-title { + display: flex; + align-items: center; + gap: 12px; + font-size: 16px; + color: rgb(255, 255, 255); + font-weight: 400; +} + +.license-icon-bg { + width: 25px; + height: 25px; + border-radius: 4px; + background: rgb(30, 30, 30); + display: flex; + justify-content: center; + align-items: center; +} + +.license-icon { + width: 15px; + height: 15px; +} + +.checkbox-wrapper { + display: flex; + align-items: center; + gap: 8px; + color: #fff; + font-size: 14px; + font-weight: 400; + line-height: 123%; + letter-spacing: 0%; + text-align: right; +} + +.custom-checkbox { + width: 25px; + height: 25px; + border-radius: 4px; + border: 2px solid rgb(42, 42, 42); + appearance: none; + background: rgb(30, 30, 30); + cursor: pointer; + position: relative; + background-repeat: no-repeat; + background-position: center; + background-size: 16px; + transition: all 0.5s ease; +} + +.custom-checkbox:checked { + background-color: rgb(102, 108, 255); + border-color: rgb(102, 108, 255); + background-image: url('assets/checkmark.svg'); +} + +.custom-checkbox:hover { + box-sizing: border-box; + border: 2px solid rgb(102, 108, 255); +} + +.license-content { + height: 100%; + background: rgb(30, 30, 30); + border-radius: 8px; + padding: 16px; + flex: 1; + overflow-y: auto; + color: #fff; + font-size: 12px; + line-height: 1.6; + white-space: pre-wrap; + max-height: 300px; + font-weight: 300; +} + + + +.theme-selector { + background: rgb(30, 30, 30); + border-radius: 8px; + padding: 12px 16px; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + transition: background 0.3s ease; + position: relative; +} + +.theme-selector-arrow { + color: #666; + transition: transform 0.3s ease; +} + +.theme-selector.active .theme-selector-arrow { + transform: rotate(90deg); +} + +.dropdown-menu { + max-height: 222px; + overflow-y: auto; + position: absolute; + top: calc(100% + 6px); + left: 0; + right: 0; + display: flex; + flex-direction: column; + gap: 6px; + padding: 6px; + background: rgb(30, 30, 30); + border-radius: 8px; + border: 2px solid rgb(60, 58, 61); + overflow: hidden; + opacity: 0; + pointer-events: none; + transition: all 0.3s ease; + z-index: 1000; +} + +.dropdown-menu.active { + opacity: 1; + transform: translateY(0); + pointer-events: all; +} + +.dropdown-item { + font-weight: 400; + color: #888; + transition: all 0.3s ease; + cursor: pointer; + background: rgb(17, 17, 17); + padding: 7.5px 16px; + border-radius: 5px; +} + +.dropdown-item:hover { + background: rgb(35, 35, 35); + color: #fff; +} + +.theme-selector-text { + color: #888; + font-weight: 400; +} + +.theme-selector-arrow { + color: #888; + transition: transform 0.3s ease; +} + +.dropdown-item:hover { + background: rgb(40, 40, 40); +} + +.theme-selector:hover { + background: rgb(25, 25, 25); +} + +.theme-options { + flex: 1; + display: flex; + flex-direction: column; + gap: 12px; +} + +.theme-option { + background: rgb(30, 30, 30); + border-radius: 8px; + padding: 18px; + cursor: pointer; + transition: background 0.3s ease; +} + +.theme-option:hover { + background: rgb(25, 25, 25); +} + +.theme-text { + color: #888; + font-weight: 400; + font-size: 14px; + align-items: center; + text-align: center; +} + + + +.installation-header { + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgb(17, 17, 17); +} + +.installation-title { + display: flex; + align-items: center; + gap: 12px; + font-size: 16px; + color: rgb(255, 255, 255); + font-weight: 400; +} + +.installation-icon-bg { + width: 25px; + height: 25px; + border-radius: 4px; + background: rgb(30, 30, 30); + display: flex; + justify-content: center; + align-items: center; +} + +.installation-icon { + width: 15px; + height: 15px; +} + +.logs-content { + background: rgb(30, 30, 30); + border-radius: 8px; + padding: 16px; + flex: 1; + overflow-y: auto; + color: #fff; + font-size: 12px; + white-space: pre-wrap; + max-height: 275px; + font-weight: 300; +} + + + +.footer { + background: rgb(30, 30, 30); + border-radius: 8px; + padding: 6px; + margin: 0; + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; +} + +.social-links { + display: flex; + gap: 7.5px; +} + +.social-link { + width: 30px; + height: 30px; + border: 2px solid rgb(17, 17, 17); + border-radius: 4px; + background: rgb(17, 17, 17); + display: flex; + justify-content: center; + align-items: center; + transition: all 0.5s ease; + cursor: pointer; +} + +.social-link:hover img { + filter: brightness(1.3); +} + +.social-link-icon { + width: 18px; + height: 18px; +} + +.nav-buttons { + display: flex; + gap: 8px; +} + +.nav-button { + opacity: 1; + padding: 2px 18px; + border-radius: 6px; + border: none; + cursor: pointer; + font-size: 14px; +} +.nav-button.disabled { + opacity: 0.5; +} + +.arrow-left, +.arrow-right { + width: 20px; + height: 20px; + top: 1px; + position: relative; + justify-content: center; + align-items: center; +} + + +.next { + border: 2px solid rgb(102, 108, 255); + background-color: rgb(102, 108, 255); + color: #fff; + transition: all 0.5s ease; +} +.next.disabled { + cursor: not-allowed; +} + +.back { + border: 2px solid rgb(17, 17, 17); + background-color: rgb(17, 17, 17); + color: #fff; + transition: all 0.5s ease; +} +.back.disabled { + cursor: not-allowed; + background-color: unset; +} + + +.popup { + position: fixed; + top: 20px; + left: 50%; + transform: translateX(-50%); + background: rgba(255, 0, 0, 0.8); + padding: 10px 20px; + border-radius: 8px; + display: none; + z-index: 1001; + color: white; +} + +.theme-option.active { + background: rgb(102, 108, 255) !important; + color: white; +} + +.theme-option.active .theme-text { + color: white; +} + +.nav-button.next.available { + cursor: pointer; + opacity: 1; +} \ No newline at end of file