diff --git a/global/navigation.css b/global/navigation.css index 027cac4..9c94731 100644 --- a/global/navigation.css +++ b/global/navigation.css @@ -84,6 +84,7 @@ .nav-item img,.nav-item svg { width:24px; height:24px; + filter: var(--icon-filter); } .nav-item.active svg path { fill:var(--accent-accent); diff --git a/global/theme.css b/global/theme.css index 0a27cb2..b49f317 100644 --- a/global/theme.css +++ b/global/theme.css @@ -13,6 +13,7 @@ --accent-secondary:#6E8F1B; --accent-shadow:#647e2226; --accent-15:#a7dc2226; + --icon-filter:brightness(0) saturate(100%) invert(76%) sepia(65%) saturate(482%) hue-rotate(35deg) brightness(98%) contrast(89%); --warning-accent:var(--grades-2); --warning-text:#8F531B; --warning-15:#ffa04626; @@ -47,6 +48,7 @@ --accent-secondary:#6E8F1B; --accent-shadow:#647e2226; --accent-15:#a7dc2226; + --icon-filter:brightness(0) saturate(100%) invert(76%) sepia(65%) saturate(482%) hue-rotate(35deg) brightness(98%) contrast(89%); --warning-accent:var(--grades-2); --warning-text:#8F531B; --warning-15:#ffa04626; @@ -81,6 +83,7 @@ --accent-secondary:#CBEE71; --accent-shadow:#0000; --accent-15:#a7dc2226; + --icon-filter:brightness(0) saturate(100%) invert(76%) sepia(65%) saturate(482%) hue-rotate(35deg) brightness(98%) contrast(89%); --warning-accent:var(--grades-2); --warning-text:#f0b37a; --warning-15:#ffa04626; @@ -127,3 +130,41 @@ body { ::-webkit-scrollbar-thumb:hover { background:var(--text-primary); } + +/* SVG ikonok színezése a kiemelő színnel */ +.icon-accent, +svg.icon-accent, +img.icon-accent { + filter: var(--icon-filter); +} + +/* Minden SVG-re alkalmazható osztály */ +.themed-icon { + filter: var(--icon-filter); + transition: filter 0.2s ease; +} + +/* Automatikus ikon színezés - minden icons/ mappából származó kép */ +img[src*="icons/"], +img[src*="icons%2F"], +img[src$=".svg"] { + filter: var(--icon-filter); + transition: filter 0.2s ease; +} + +/* Warning színű ikonok (narancssárga) */ +img[src*="icons/dkt.svg"], +img[src*="icons%2Fdkt.svg"], +img[src*="icons/assigment.svg"], +img[src*="icons%2Fassigment.svg"], +img[src$="dkt.svg"], +img[src$="assigment.svg"] { + filter: brightness(0) saturate(100%) invert(67%) sepia(44%) saturate(1057%) hue-rotate(349deg) brightness(101%) contrast(101%) !important; +} + +/* Error színű ikonok (piros/rózsaszín) */ +img[src*="icons/logout.svg"], +img[src*="icons%2Flogout.svg"], +img[src$="logout.svg"] { + filter: brightness(0) saturate(100%) invert(52%) sepia(75%) saturate(1637%) hue-rotate(306deg) brightness(101%) contrast(101%) !important; +} diff --git a/global/theme.js b/global/theme.js index 2f5c6b9..c6c2edb 100644 --- a/global/theme.js +++ b/global/theme.js @@ -1,8 +1,128 @@ (() => { + let customThemes = []; + + async function loadCustomThemes() { + try { + const saved = await storageManager.get("customThemes", []); + customThemes = Array.isArray(saved) ? saved : []; + } catch (error) { + console.error("Error loading custom themes:", error); + customThemes = []; + } + } + + function applyCustomThemeColors(theme) { + const root = document.documentElement; + const isDark = theme.mode === "dark"; + + root.style.setProperty("--background", theme.colors.background); + root.style.setProperty("--background-0", theme.colors.background + "00"); + root.style.setProperty("--card-card", theme.colors.card); + root.style.setProperty("--card-translucent", theme.colors.card + "80"); + root.style.setProperty("--accent-accent", theme.colors.accent); + root.style.setProperty("--text-primary", theme.colors.text); + + // Származtatott színek + root.style.setProperty("--text-secondary", theme.colors.text + "cc"); + root.style.setProperty("--text-teritary", theme.colors.text + "80"); + root.style.setProperty("--accent-15", theme.colors.accent + "26"); + root.style.setProperty("--button-secondaryFill", isDark ? lightenColor(theme.colors.card, 10) : darkenColor(theme.colors.card, 5)); + root.style.setProperty("--accent-secondary", isDark ? lightenColor(theme.colors.accent, 20) : darkenColor(theme.colors.accent, 20)); + root.style.setProperty("--shadow-blur", isDark ? "0" : "2px"); + root.style.setProperty("--accent-shadow", isDark ? "#0000" : theme.colors.accent + "26"); + + // SVG ikon filter beállítása a kiemelő szín alapján + root.style.setProperty("--icon-filter", hexToFilter(theme.colors.accent)); + } + + // Hex szín átalakítása CSS filterré + function hexToFilter(hex) { + // Hex -> RGB + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + + // RGB -> HSL + const rNorm = r / 255; + const gNorm = g / 255; + const bNorm = b / 255; + + const max = Math.max(rNorm, gNorm, bNorm); + const min = Math.min(rNorm, gNorm, bNorm); + let h, s, l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case rNorm: h = ((gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0)) / 6; break; + case gNorm: h = ((bNorm - rNorm) / d + 2) / 6; break; + case bNorm: h = ((rNorm - gNorm) / d + 4) / 6; break; + } + } + + const hue = Math.round(h * 360); + const saturation = Math.round(s * 100); + const lightness = Math.round(l * 100); + + // Filter létrehozása + // Ez egy egyszerűsített megközelítés - a pontos szín reprodukálásához + // komplexebb számítás kellene, de ez megfelelő a legtöbb esetben + const brightnessVal = lightness > 50 ? 1 + (lightness - 50) / 100 : 0.5 + lightness / 100; + const saturateVal = saturation > 0 ? 1 + saturation / 100 : 0; + + return `brightness(0) saturate(100%) invert(${lightness}%) sepia(${saturation}%) saturate(${Math.min(500, saturation * 5)}%) hue-rotate(${hue}deg) brightness(${brightnessVal}) contrast(${90 + saturation / 10}%)`; + } + + function lightenColor(color, percent) { + const num = parseInt(color.replace("#", ""), 16); + const amt = Math.round(2.55 * percent); + const R = Math.min(255, (num >> 16) + amt); + const G = Math.min(255, ((num >> 8) & 0x00ff) + amt); + const B = Math.min(255, (num & 0x0000ff) + amt); + return "#" + (0x1000000 + R * 0x10000 + G * 0x100 + B).toString(16).slice(1); + } + + function darkenColor(color, percent) { + const num = parseInt(color.replace("#", ""), 16); + const amt = Math.round(2.55 * percent); + const R = Math.max(0, (num >> 16) - amt); + const G = Math.max(0, ((num >> 8) & 0x00ff) - amt); + const B = Math.max(0, (num & 0x0000ff) - amt); + return "#" + (0x1000000 + R * 0x10000 + G * 0x100 + B).toString(16).slice(1); + } + + function clearCustomThemeStyles() { + const root = document.documentElement; + const customProps = [ + "--background", "--background-0", "--card-card", "--card-translucent", + "--accent-accent", "--text-primary", "--text-secondary", "--text-teritary", + "--accent-15", "--button-secondaryFill", "--accent-secondary", + "--shadow-blur", "--accent-shadow", "--icon-filter" + ]; + customProps.forEach(prop => root.style.removeProperty(prop)); + } + async function setTheme(theme) { try { + // Töröljük az előző egyéni téma stílusait + clearCustomThemeStyles(); + document.documentElement.setAttribute("data-theme", theme); await storageManager.set("themePreference", theme); + + // Ha egyéni téma, alkalmazzuk a színeket + if (theme.startsWith("custom-")) { + await loadCustomThemes(); + const themeId = theme.replace("custom-", ""); + const customTheme = customThemes.find(t => t.id === themeId); + if (customTheme) { + applyCustomThemeColors(customTheme); + } + } + chrome.runtime .sendMessage({ action: "themeChanged", @@ -103,6 +223,7 @@ async function initializeTheme() { try { const theme = await storageManager.get("themePreference", "light-green"); + await loadCustomThemes(); await setTheme(theme); setPageTitleAndFavicon(); @@ -123,6 +244,10 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === "changeTheme") { + // Ha egyéni témák is jöttek az üzenetben, frissítsük a lokális listát + if (message.customThemes) { + customThemes = message.customThemes; + } setTheme(message.theme); sendResponse({ success: true }); } diff --git a/i18n/en.json b/i18n/en.json index b30b9aa..da354bd 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -19,6 +19,29 @@ "dark_lime": "Dark Lime", "dark_indigo": "Dark Indigo" }, + "custom_themes": { + "title": "Custom themes", + "no_themes": "No custom themes yet", + "create": "Create new theme", + "edit": "Edit theme", + "name": "Theme name", + "mode": "Mode", + "dark_mode": "Dark", + "light_mode": "Light", + "colors": "Colors", + "accent_color": "Accent color", + "background_color": "Background color", + "card_color": "Card color", + "text_color": "Text color", + "preview": "Preview", + "share": "Share theme", + "share_description": "Copy the code and share it with others:", + "import": "Import theme", + "import_description": "Paste the theme code:", + "import_error_empty": "Please paste the theme code!", + "import_error_invalid": "Invalid theme code!", + "delete_confirm": "Are you sure you want to delete this theme?" + }, "languages": { "hu": "Magyar", "en": "English" diff --git a/i18n/hu.json b/i18n/hu.json index 52436cb..a55d766 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -21,6 +21,29 @@ "dark_lime": "Sötét Lime", "dark_indigo": "Sötét Indigó" }, + "custom_themes": { + "title": "Egyéni témák", + "no_themes": "Még nincsenek egyéni témák", + "create": "Új téma létrehozása", + "edit": "Téma szerkesztése", + "name": "Téma neve", + "mode": "Mód", + "dark_mode": "Sötét", + "light_mode": "Világos", + "colors": "Színek", + "accent_color": "Kiemelő szín", + "background_color": "Háttér szín", + "card_color": "Kártya szín", + "text_color": "Szöveg szín", + "preview": "Előnézet", + "share": "Téma megosztása", + "share_description": "Másold ki a kódot és oszd meg másokkal:", + "import": "Téma importálása", + "import_description": "Illeszd be a téma kódot:", + "import_error_empty": "Kérlek illeszd be a téma kódot!", + "import_error_invalid": "Érvénytelen téma kód!", + "delete_confirm": "Biztosan törölni szeretnéd ezt a témát?" + }, "languages": { "hu": "Magyar", "en": "English" diff --git a/icons/ArrowsExpandFull.svg b/icons/ArrowsExpandFull.svg index 6f908c2..94fb43d 100644 --- a/icons/ArrowsExpandFull.svg +++ b/icons/ArrowsExpandFull.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/BadgeCheck.svg b/icons/BadgeCheck.svg index 9ac0d2b..3d48643 100644 --- a/icons/BadgeCheck.svg +++ b/icons/BadgeCheck.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/Calendar.svg b/icons/Calendar.svg index 7d752b5..b8ffb85 100644 --- a/icons/Calendar.svg +++ b/icons/Calendar.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/ChevronLeftCircle.svg b/icons/ChevronLeftCircle.svg index 2bafa6b..92c7c7c 100644 --- a/icons/ChevronLeftCircle.svg +++ b/icons/ChevronLeftCircle.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/ChevronRightCircle.svg b/icons/ChevronRightCircle.svg index c40a1f8..80f2786 100644 --- a/icons/ChevronRightCircle.svg +++ b/icons/ChevronRightCircle.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/CloseCircle.svg b/icons/CloseCircle.svg index 4116cde..bba7b6b 100644 --- a/icons/CloseCircle.svg +++ b/icons/CloseCircle.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/Subject.svg b/icons/Subject.svg index 94937ab..21b6ed5 100644 --- a/icons/Subject.svg +++ b/icons/Subject.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/absences-active.svg b/icons/absences-active.svg index d67438d..62f9775 100644 --- a/icons/absences-active.svg +++ b/icons/absences-active.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/absences-inactive.svg b/icons/absences-inactive.svg index 2d127f7..d974e57 100644 --- a/icons/absences-inactive.svg +++ b/icons/absences-inactive.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/assigment.svg b/icons/assigment.svg index 00ebfa9..333c2fe 100644 --- a/icons/assigment.svg +++ b/icons/assigment.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/dashboard-active.svg b/icons/dashboard-active.svg index 3e0fa00..b48add9 100644 --- a/icons/dashboard-active.svg +++ b/icons/dashboard-active.svg @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/icons/dashboard-inactive.svg b/icons/dashboard-inactive.svg index 7007744..c0b1782 100644 --- a/icons/dashboard-inactive.svg +++ b/icons/dashboard-inactive.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/delete.svg b/icons/delete.svg index 32e95a4..ad79cbe 100644 --- a/icons/delete.svg +++ b/icons/delete.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/dkt.svg b/icons/dkt.svg index 29f01d8..6d52618 100644 --- a/icons/dkt.svg +++ b/icons/dkt.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/eye-off.svg b/icons/eye-off.svg index 1f0be33..54ccbe7 100644 --- a/icons/eye-off.svg +++ b/icons/eye-off.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/eye-on.svg b/icons/eye-on.svg index 830ed47..24dfb34 100644 --- a/icons/eye-on.svg +++ b/icons/eye-on.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/grades-active.svg b/icons/grades-active.svg index 59bda98..7307c1b 100644 --- a/icons/grades-active.svg +++ b/icons/grades-active.svg @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/icons/grades-inactive.svg b/icons/grades-inactive.svg index 1448963..f20ed92 100644 --- a/icons/grades-inactive.svg +++ b/icons/grades-inactive.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/homework.svg b/icons/homework.svg index 82d0a49..5852072 100644 --- a/icons/homework.svg +++ b/icons/homework.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/logout.svg b/icons/logout.svg index 00ec2a8..b0d2c6b 100644 --- a/icons/logout.svg +++ b/icons/logout.svg @@ -1,4 +1,4 @@ \ No newline at end of file diff --git a/icons/messages-active.svg b/icons/messages-active.svg index d90031c..b5f2db4 100644 --- a/icons/messages-active.svg +++ b/icons/messages-active.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/messages-inactive.svg b/icons/messages-inactive.svg index 8affba8..c267aa5 100644 --- a/icons/messages-inactive.svg +++ b/icons/messages-inactive.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/naplo.svg b/icons/naplo.svg index 5b65937..1bc7d47 100644 --- a/icons/naplo.svg +++ b/icons/naplo.svg @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/icons/others.svg b/icons/others.svg index 666094f..e280a46 100644 --- a/icons/others.svg +++ b/icons/others.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/pipa.svg b/icons/pipa.svg index 6580bd5..384cfdc 100644 --- a/icons/pipa.svg +++ b/icons/pipa.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/plus.svg b/icons/plus.svg index 36c33bd..72e80e9 100644 --- a/icons/plus.svg +++ b/icons/plus.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/profile.svg b/icons/profile.svg index b750730..976d879 100644 --- a/icons/profile.svg +++ b/icons/profile.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/select-all.svg b/icons/select-all.svg index 710dc26..f4fee33 100644 --- a/icons/select-all.svg +++ b/icons/select-all.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/select-none.svg b/icons/select-none.svg index defddb5..83f11af 100644 --- a/icons/select-none.svg +++ b/icons/select-none.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/select.svg b/icons/select.svg index a19ad41..834fd31 100644 --- a/icons/select.svg +++ b/icons/select.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/settings.svg b/icons/settings.svg index 0f23909..0ac44cf 100644 --- a/icons/settings.svg +++ b/icons/settings.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/timetable-active.svg b/icons/timetable-active.svg index 54f0cb6..0a8d7be 100644 --- a/icons/timetable-active.svg +++ b/icons/timetable-active.svg @@ -1,4 +1,4 @@ \ No newline at end of file diff --git a/icons/timetable-inactive.svg b/icons/timetable-inactive.svg index 58dd202..e895299 100644 --- a/icons/timetable-inactive.svg +++ b/icons/timetable-inactive.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/icons/trash.svg b/icons/trash.svg index d0aba98..a5b2b77 100644 --- a/icons/trash.svg +++ b/icons/trash.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/icons/undo.svg b/icons/undo.svg index bcf2518..9e0f1c3 100644 --- a/icons/undo.svg +++ b/icons/undo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/login/login.css b/login/login.css index fbbd656..6d5c3f9 100644 --- a/login/login.css +++ b/login/login.css @@ -136,7 +136,7 @@ body { height:20px; opacity:0.6; transition:opacity 0.2s ease; - filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness)); + filter: var(--icon-filter); } .show-password:hover .icon-eye { opacity:1; diff --git a/login/twofactor.css b/login/twofactor.css index bc3f7c9..96a7f15 100644 --- a/login/twofactor.css +++ b/login/twofactor.css @@ -128,7 +128,7 @@ body { height:20px; opacity:0.6; transition:opacity 0.2s ease; - filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness)); + filter: var(--icon-filter); } .show-password:hover .icon-eye { opacity:1; diff --git a/manifest.json b/manifest.json index 3236c18..6021c00 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Firxa", - "version": "1.3.5", + "version": "1.4.0", "description": "KRÉTA webes verziójának újraírása", "icons": { "128": "images/firka_logo_128.png" diff --git a/manifest_fox.json b/manifest_fox.json index 58b88fc..051bb6c 100644 --- a/manifest_fox.json +++ b/manifest_fox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Firxa", - "version": "1.3.4", + "version": "1.4.0", "description": "KRÉTA webes verziójának újraírása", "icons": { "128": "images/firka_logo_128.png" diff --git a/roleselect/roleselect.css b/roleselect/roleselect.css index 373e505..13c3747 100644 --- a/roleselect/roleselect.css +++ b/roleselect/roleselect.css @@ -133,7 +133,7 @@ body { } .logout-card { height:180px; - background:var(--error-card); + background:var(--card-card); box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow); } .role-icon { diff --git a/settings/index.css b/settings/index.css index 79945db..cf71ae8 100644 --- a/settings/index.css +++ b/settings/index.css @@ -245,3 +245,496 @@ h2 { font-size:18px; vertical-align:middle; } + +.custom-themes-section { + margin-top: 16px; + padding-top: 16px; + border-top: 1px solid var(--border-border, var(--text-teritary)); +} + +.custom-themes-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; + font-weight: 600; + font-size: 14px; + color: var(--text-primary); +} + +.add-theme-btn { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: none; + border-radius: 8px; + background: var(--accent-15); + color: var(--accent-accent); + cursor: pointer; + transition: all 0.2s ease; +} + +.add-theme-btn:hover { + background: var(--accent-accent); + color: var(--button-secondaryFill); +} + +.custom-themes-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + min-height: 50px; +} + +.custom-theme-option { + position: relative; + display: flex; + flex-direction: column; + background: var(--button-secondaryFill); + border-radius: 12px; + overflow: hidden; + border: 1px solid var(--border-border, var(--text-teritary)); + transition: all 0.2s ease; +} + +.custom-theme-option:hover { + border-color: var(--accent-accent); + transform: translateY(-2px); +} + +.custom-theme-option.active { + border-color: var(--accent-accent); + box-shadow: 0 0 0 2px var(--accent-15); +} + +.custom-theme-option .theme-preview { + height: 70px; + border-radius: 0; +} + +.custom-theme-option .theme-info { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 10px; + background: var(--button-secondaryFill); + border-top: 1px solid var(--border-border, var(--text-teritary)); + gap: 8px; +} + +.custom-theme-option .theme-name { + font-size: 12px; + font-weight: 600; + color: var(--text-primary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + min-width: 0; +} + +.custom-theme-option .theme-actions { + display: flex; + gap: 4px; + flex-shrink: 0; +} + +.theme-action-btn { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border: none; + border-radius: 6px; + background: var(--accent-15); + color: var(--accent-accent); + cursor: pointer; + transition: all 0.2s ease; +} + +.theme-action-btn:hover { + background: var(--accent-accent); + color: var(--button-secondaryFill); +} + +.theme-action-btn.delete-theme { + background: rgba(255, 80, 80, 0.15); + color: #ff5050; +} + +.theme-action-btn.delete-theme:hover { + background: #ff5050; + color: white; +} + +.theme-action-btn .material-icons-round { + font-size: 16px; +} + +.no-custom-themes { + grid-column: 1 / -1; + text-align: center; + color: var(--text-secondary); + font-size: 12px; + padding: 20px 0; +} + +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); + display: none; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 16px; + animation: fadeIn 0.2s ease; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.modal-overlay.active { + display: flex; +} + +.modal-content { + background: var(--card-card); + border-radius: 20px; + width: 100%; + max-width: 420px; + max-height: 90vh; + overflow-y: auto; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); + animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1); + border: 1px solid var(--border-border, var(--text-teritary)); +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(20px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px; + border-bottom: 1px solid var(--border-border, var(--text-teritary)); +} + +.modal-header h3 { + font-size: 18px; + font-weight: 700; + color: var(--text-primary); + margin: 0; +} + +.modal-close { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border: none; + border-radius: 10px; + background: var(--button-secondaryFill); + color: var(--text-secondary); + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.modal-close:hover { + background: var(--error-15); + color: var(--error-accent); + transform: rotate(90deg); +} + +.modal-close .material-icons-round { + font-size: 20px; +} + +.modal-body { + padding: 20px; +} + +.modal-footer { + display: flex; + gap: 8px; + padding: 16px; + border-top: 1px solid var(--border-border, var(--text-teritary)); +} + +.modal-footer button { + flex: 1; + padding: 10px 16px; + border: none; + border-radius: 8px; + font-weight: 500; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + font-family: "Montserrat", serif; +} + +.btn-primary { + background: var(--accent-accent); + color: #000; +} + +.btn-primary:hover { + opacity: 0.9; +} + +.btn-secondary { + background: var(--button-secondaryFill); + color: var(--text-primary); +} + +.btn-secondary:hover { + background: var(--accent-15); +} + +.theme-form .form-group { + margin-bottom: 16px; +} + +.theme-form label { + display: block; + font-size: 13px; + font-weight: 500; + color: var(--text-primary); + margin-bottom: 8px; +} + +.theme-form input[type="text"] { + width: 100%; + padding: 10px 12px; + border: 1px solid var(--border-border, var(--text-teritary)); + border-radius: 8px; + background: var(--button-secondaryFill); + color: var(--text-primary); + font-size: 14px; + font-family: "Montserrat", serif; + outline: none; + transition: border-color 0.2s ease; +} + +.theme-form input[type="text"]:focus { + border-color: var(--accent-accent); +} + +.mode-selector { + display: flex; + gap: 8px; +} + +.mode-option { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 10px; + border: 1px solid var(--border-border, var(--text-teritary)); + border-radius: 8px; + background: var(--button-secondaryFill); + color: var(--text-secondary); + cursor: pointer; + transition: all 0.2s ease; + font-family: "Montserrat", serif; + font-size: 13px; +} + +.mode-option:hover { + border-color: var(--accent-accent); +} + +.mode-option.active { + background: var(--accent-15); + border-color: var(--accent-accent); + color: var(--accent-accent); +} + +.color-section { + margin-top: 20px; +} + +.color-section h4 { + font-size: 14px; + font-weight: 600; + color: var(--text-primary); + margin: 0 0 12px 0; +} + +.color-group { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; +} + +.color-group label { + font-size: 13px; + color: var(--text-secondary); + margin: 0; +} + +.color-input-wrapper { + display: flex; + align-items: center; + gap: 8px; +} + +.color-input-wrapper input[type="color"] { + width: 32px; + height: 32px; + border: none; + border-radius: 6px; + cursor: pointer; + padding: 0; + background: transparent; +} + +.color-input-wrapper input[type="color"]::-webkit-color-swatch-wrapper { + padding: 0; +} + +.color-input-wrapper input[type="color"]::-webkit-color-swatch { + border: none; + border-radius: 6px; +} + +.color-hex { + width: 80px; + padding: 6px 8px; + border: 1px solid var(--border-border, var(--text-teritary)); + border-radius: 6px; + background: var(--button-secondaryFill); + color: var(--text-primary); + font-size: 12px; + font-family: monospace; + text-transform: uppercase; +} + +.theme-preview-section { + margin-top: 20px; +} + +.theme-preview-section h4 { + font-size: 14px; + font-weight: 600; + color: var(--text-primary); + margin: 0 0 12px 0; +} + +.live-preview { + width: 100%; + height: 80px; + border-radius: 8px; + overflow: hidden; + position: relative; +} + +.live-preview .preview-header { + height: 30%; + width: 100%; +} + +.live-preview .preview-content { + padding: 8px; +} + +.live-preview .preview-card { + height: 20px; + border-radius: 4px; + margin-bottom: 4px; +} + +.live-preview .preview-text { + font-size: 10px; +} + +.share-code-wrapper { + position: relative; + margin-top: 12px; +} + +.share-code-wrapper textarea, +#importCode { + width: 100%; + min-height: 80px; + padding: 12px; + border: 1px solid var(--border-border, var(--text-teritary)); + border-radius: 8px; + background: var(--button-secondaryFill); + color: var(--text-primary); + font-family: monospace; + font-size: 12px; + resize: none; + outline: none; +} + +.share-code-wrapper textarea:focus, +#importCode:focus { + border-color: var(--accent-accent); +} + +.copy-btn { + position: absolute; + top: 8px; + right: 8px; + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: none; + border-radius: 6px; + background: var(--accent-15); + color: var(--accent-accent); + cursor: pointer; + transition: all 0.2s ease; +} + +.copy-btn:hover { + background: var(--accent-accent); + color: var(--button-secondaryFill); +} + +.copy-btn.copied { + background: var(--grades-4); + color: white; +} + +.error-message { + color: var(--error-accent); + font-size: 12px; + margin-top: 8px; + min-height: 16px; +} + +.import-modal .modal-body p { + color: var(--text-secondary); + font-size: 13px; + margin-bottom: 8px; +} + +#importCode { + margin-top: 8px; +} diff --git a/settings/index.html b/settings/index.html index ea222df..b043de6 100644 --- a/settings/index.html +++ b/settings/index.html @@ -51,6 +51,17 @@ Sötét Zöld + +