Redesign settings UI and update Electron to v40
Revamps the settings page with improved layout, modernized CSS, and enhanced accessibility, including new layout helpers, better grouping, and consistent styling. Updates Electron from v39.2.7 to v40.0.0 in dependencies. Adds dynamic theme application to the settings page, ensuring user-selected themes are reflected immediately.
This commit is contained in:
+397
-233
@@ -14,16 +14,19 @@
|
||||
.plugin-authors .muted { opacity:.7; margin-right: 6px; }
|
||||
:root {
|
||||
--bg: #121418;
|
||||
--dark-blue: #0B1C2B;
|
||||
--dark-purple: #1B1035;
|
||||
--gradient-end: #1B1035;
|
||||
--surface: rgba(255, 255, 255, 0.06);
|
||||
--surface-hover: rgba(255, 255, 255, 0.10);
|
||||
--primary: #7B2EFF;
|
||||
--primary-hover: #9654FF;
|
||||
--accent: #00C6FF;
|
||||
--text: #E0E0E0;
|
||||
--surface-1: rgba(255, 255, 255, 0.04);
|
||||
--surface-2: rgba(255, 255, 255, 0.06);
|
||||
--card-border: rgba(255, 255, 255, 0.10);
|
||||
--ring: 0 0 0 3px rgba(123, 46, 255, 0.35);
|
||||
--glow: 0 8px 30px rgba(123, 46, 255, 0.25), 0 2px 10px rgba(0, 198, 255, 0.15);
|
||||
--text-secondary: #B8B8C0;
|
||||
--text-muted: #8f8f9d;
|
||||
--border: rgba(255, 255, 255, 0.12);
|
||||
--border-subtle: rgba(255, 255, 255, 0.06);
|
||||
--ring: 0 0 0 2px rgba(123, 46, 255, 0.4);
|
||||
--glow-subtle: 0 4px 20px rgba(123, 46, 255, 0.15);
|
||||
}
|
||||
|
||||
/* Load InterVariable */
|
||||
@@ -35,15 +38,14 @@
|
||||
}
|
||||
|
||||
body {
|
||||
/* Nebula gradient background with subtle radial glow */
|
||||
background:
|
||||
radial-gradient(1200px 600px at 10% -10%, rgba(0, 198, 255, 0.15), transparent 60%),
|
||||
radial-gradient(1000px 500px at 110% 10%, rgba(123, 46, 255, 0.2), transparent 60%),
|
||||
linear-gradient(145deg, var(--bg) 0%, var(--dark-purple) 100%);
|
||||
background:
|
||||
radial-gradient(800px 400px at 10% 0%, rgba(123, 46, 255, 0.08), transparent 60%),
|
||||
radial-gradient(800px 400px at 100% 20%, rgba(0, 198, 255, 0.06), transparent 60%),
|
||||
linear-gradient(180deg, var(--bg), var(--gradient-end));
|
||||
color: var(--text);
|
||||
font-family: 'InterVariable', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||||
font-family: 'InterVariable', system-ui, -apple-system, 'Segoe UI', 'Roboto', sans-serif;
|
||||
margin: 0;
|
||||
padding: 2rem;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
@@ -53,47 +55,39 @@ body {
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--bg) 85%, #000 15%), color-mix(in srgb, var(--dark-purple, var(--bg)) 80%, #000 20%));
|
||||
backdrop-filter: blur(14px) saturate(120%);
|
||||
-webkit-backdrop-filter: blur(14px) saturate(120%);
|
||||
background: var(--bg);
|
||||
padding: 0;
|
||||
border-radius: 18px;
|
||||
border: 1px solid var(--card-border);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
|
||||
max-width: 1200px;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
max-width: 100vw;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
max-height: calc(100vh - 4rem);
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* Subtle animated sheen around the container */
|
||||
.container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -1px;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 25%, transparent), color-mix(in srgb, var(--accent) 18%, transparent) 40%, transparent 60%);
|
||||
filter: blur(20px);
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
/* Sidebar + content layout */
|
||||
.sidebar {
|
||||
width: 280px;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--text) 6%, transparent), color-mix(in srgb, var(--text) 4%, transparent));
|
||||
border-right: 1px solid rgba(255,255,255,0.08);
|
||||
padding: 1.25rem 1rem;
|
||||
width: 260px;
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02));
|
||||
border-right: 1px solid var(--border);
|
||||
padding: 1.5rem 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sidebar h1 {
|
||||
font-size: 1.1rem;
|
||||
margin: 0 0 1rem 0;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 300;
|
||||
margin: 0 0 1.5rem 0;
|
||||
padding: 0 1rem;
|
||||
color: var(--primary);
|
||||
letter-spacing: 0.4px;
|
||||
letter-spacing: -0.01em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
@@ -102,58 +96,50 @@ body {
|
||||
.tabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.tab-link {
|
||||
text-align: left;
|
||||
background: linear-gradient(180deg, transparent, transparent);
|
||||
color: var(--text);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px 10px 14px;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 10px 1rem;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.1s ease;
|
||||
font-size: 14px;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
font-family: inherit;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
.tab-link:hover {
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-color: rgba(255,255,255,0.08);
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.tab-link.active {
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 22%, transparent), color-mix(in srgb, var(--accent) 14%, transparent));
|
||||
background: linear-gradient(90deg, rgba(123, 46, 255, 0.12), rgba(0, 198, 255, 0.08));
|
||||
color: var(--text);
|
||||
border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 8%, transparent);
|
||||
border-left-color: var(--primary);
|
||||
font-weight: 500;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Left accent bar */
|
||||
.tab-link.active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
width: 3px;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(180deg, var(--accent), var(--primary));
|
||||
}
|
||||
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 1.25rem 1.5rem 2rem 1.5rem;
|
||||
padding: 2rem 3rem;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background:
|
||||
radial-gradient(800px 300px at 60% -10%, rgba(0, 198, 255, 0.10), transparent 50%),
|
||||
radial-gradient(700px 260px at 20% -20%, rgba(123, 46, 255, 0.18), transparent 50%);
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
.tab-panel {
|
||||
@@ -164,92 +150,112 @@ body {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
|
||||
.setting-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 1rem;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1.5rem;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 1rem 1.25rem;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 400;
|
||||
margin-bottom: 0.35rem;
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0.6rem;
|
||||
font-size: 1rem;
|
||||
border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
|
||||
border-radius: 10px;
|
||||
margin-bottom: 0.75rem;
|
||||
background-color: color-mix(in srgb, var(--bg) 82%, #000 18%);
|
||||
input[type="text"],
|
||||
input[type="file"] {
|
||||
padding: 0.5rem 0.65rem;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
margin-bottom: 0.5rem;
|
||||
background-color: var(--surface);
|
||||
color: var(--text);
|
||||
outline: none;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
input:focus {
|
||||
input[type="text"]:focus,
|
||||
input[type="file"]:focus {
|
||||
box-shadow: var(--ring);
|
||||
border-color: color-mix(in srgb, var(--primary) 50%, transparent);
|
||||
border-color: var(--primary);
|
||||
background-color: var(--surface-hover);
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 0.5rem 0.65rem;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
background-color: var(--surface);
|
||||
color: var(--text);
|
||||
outline: none;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
box-shadow: var(--ring);
|
||||
border-color: var(--primary);
|
||||
background-color: var(--surface-hover);
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.65rem 0.9rem;
|
||||
font-size: 0.95rem;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 90%, var(--accent) 10%), color-mix(in srgb, var(--primary) 80%, #000 20%));
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 14px;
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
border: 1px solid color-mix(in srgb, var(--primary) 18%, transparent);
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.08s ease, box-shadow 0.2s ease, background 0.2s ease, filter 0.2s ease;
|
||||
font-weight: 400;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(1.03) saturate(1.05);
|
||||
box-shadow: var(--glow);
|
||||
background: var(--surface-hover);
|
||||
box-shadow: var(--glow-subtle);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
|
||||
/* Primary button style (e.g., Big Picture Mode) */
|
||||
.primary-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 24px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, color-mix(in srgb, var(--primary) 60%, #000 40%) 50%, var(--accent) 100%);
|
||||
background-size: 200% 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
background: linear-gradient(135deg, var(--primary), var(--accent));
|
||||
color: var(--text);
|
||||
border: 1px solid rgba(255,255,255,0.15);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--primary);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 20px color-mix(in srgb, var(--primary) 30%, transparent);
|
||||
transition: all 0.15s ease;
|
||||
box-shadow: var(--glow-subtle);
|
||||
}
|
||||
|
||||
.primary-btn:hover {
|
||||
background-position: 100% 0;
|
||||
box-shadow: 0 6px 30px color-mix(in srgb, var(--primary) 45%, transparent), 0 0 20px color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
transform: translateY(-2px);
|
||||
background: linear-gradient(135deg, var(--primary-hover), var(--accent));
|
||||
box-shadow: 0 4px 24px rgba(123, 46, 255, 0.25);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.primary-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 10px color-mix(in srgb, var(--primary) 30%, transparent);
|
||||
}
|
||||
|
||||
|
||||
.note {
|
||||
font-size: 0.8rem;
|
||||
color: color-mix(in srgb, var(--text) 70%, transparent);
|
||||
margin-top: 1rem;
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.35rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.status {
|
||||
@@ -259,14 +265,14 @@ button:active {
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background-color: color-mix(in srgb, var(--bg) 82%, #000 18%);
|
||||
gap: 0.75rem;
|
||||
background-color: var(--surface);
|
||||
color: var(--text);
|
||||
padding: 0.8rem 1.2rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
|
||||
box-shadow: 0 8px 30px rgba(0,0,0,0.5);
|
||||
font-size: 1rem;
|
||||
padding: 0.75rem 1.25rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.4);
|
||||
font-size: 14px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
@@ -298,95 +304,187 @@ button:active {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.setting-group .setting-row button,
|
||||
.setting-group .setting-row input,
|
||||
.setting-group .setting-row select {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Inline layout helpers (Firefox-like settings rows) */
|
||||
.setting-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.setting-row label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.setting-row .note {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.label-min {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.setting-row button,
|
||||
.setting-row input,
|
||||
.setting-row select {
|
||||
width: auto;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.setting-row select {
|
||||
flex: 1 1 220px;
|
||||
}
|
||||
|
||||
.button-row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.range-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.range-row input[type="range"] {
|
||||
flex: 1 1 auto;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.range-row .range-value {
|
||||
min-width: 56px;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
color: color-mix(in srgb, var(--text) 85%, transparent);
|
||||
}
|
||||
|
||||
.settings-fieldset {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
padding: 1rem;
|
||||
background: rgba(123, 46, 255, 0.03);
|
||||
}
|
||||
|
||||
.settings-fieldset legend {
|
||||
padding: 0 0.5rem;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Cards (customization groups) */
|
||||
.customization-group {
|
||||
background: linear-gradient(180deg, var(--surface-1, color-mix(in srgb, var(--bg) 85%, #000 15%)), var(--surface-2, color-mix(in srgb, var(--bg) 78%, #000 22%)));
|
||||
border: 1px solid var(--card-border);
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px 16px 16px;
|
||||
box-shadow: 0 6px 24px rgba(0,0,0,0.25);
|
||||
margin-bottom: 20px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 1rem 1.25rem;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.customization-group > h3 {
|
||||
margin: 0 0 10px 0;
|
||||
margin: 0 0 0.75rem 0;
|
||||
position: relative;
|
||||
padding-left: 10px;
|
||||
padding-left: 0;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.customization-group > h3::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(180deg, var(--accent), var(--primary));
|
||||
|
||||
|
||||
.setting-group > h3 {
|
||||
margin: 0 0 0.75rem 0;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Section titles */
|
||||
h2 {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 1.2rem;
|
||||
margin: 0 0 12px 0;
|
||||
display: block;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 300;
|
||||
margin: 0 0 1.5rem 0;
|
||||
color: var(--text);
|
||||
letter-spacing: -0.01em;
|
||||
position: relative;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
h2::after {
|
||||
content: '';
|
||||
flex: 1 1 auto;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0.15), transparent);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 60px;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, var(--primary), var(--accent));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Theming: theme selector buttons override */
|
||||
.theme-selector {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||
gap: 16px;
|
||||
padding: 10px 0;
|
||||
background: linear-gradient(180deg, var(--surface-1, color-mix(in srgb, var(--bg) 85%, #000 15%)), var(--surface-2, color-mix(in srgb, var(--bg) 78%, #000 22%)));
|
||||
border: 1px solid var(--card-border);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
|
||||
gap: 12px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
.theme-btn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 8px;
|
||||
border: 1px solid rgba(255,255,255,0.10) !important;
|
||||
border-radius: 12px !important;
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.02)) !important;
|
||||
padding: 10px 8px;
|
||||
border: 2px solid var(--border) !important;
|
||||
border-radius: 8px !important;
|
||||
background: var(--surface) !important;
|
||||
color: var(--text);
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
font-size: 13px;
|
||||
min-height: 90px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.theme-btn:hover {
|
||||
background: var(--surface-hover) !important;
|
||||
border-color: var(--text-muted) !important;
|
||||
}
|
||||
.theme-btn:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.25); }
|
||||
.theme-btn.active {
|
||||
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06), var(--glow);
|
||||
border-color: var(--primary) !important;
|
||||
box-shadow: 0 0 0 2px var(--primary), var(--glow-subtle);
|
||||
background: linear-gradient(180deg, rgba(123, 46, 255, 0.08), rgba(0, 198, 255, 0.05)) !important;
|
||||
}
|
||||
.theme-preview {
|
||||
width: 60px;
|
||||
height: 40px;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
width: 64px;
|
||||
height: 42px;
|
||||
border-radius: 4px !important;
|
||||
border: 1px solid var(--border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.theme-preview::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 6px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.custom-theme-btn { border-style: dashed !important; opacity: 0.95; }
|
||||
.custom-theme-btn:hover { opacity: 1; }
|
||||
|
||||
@@ -394,66 +492,86 @@ h2::after {
|
||||
input[type="range"] {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
height: 6px;
|
||||
background: linear-gradient(90deg, rgba(123,46,255,0.6), rgba(0,198,255,0.6));
|
||||
border-radius: 999px;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--primary), var(--accent));
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
border: 1px solid rgba(255,255,255,0.15);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
input[type="range"]:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
border: 2px solid rgba(123,46,255,0.9);
|
||||
box-shadow: 0 2px 10px rgba(123,46,255,0.35);
|
||||
background: var(--primary);
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-thumb {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
border: 2px solid rgba(123,46,255,0.9);
|
||||
box-shadow: 0 2px 10px rgba(123,46,255,0.35);
|
||||
background: var(--primary);
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Checkboxes/radios */
|
||||
input[type="checkbox"], input[type="radio"] {
|
||||
accent-color: #8a4dff;
|
||||
accent-color: var(--primary);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* Layout & logo options */
|
||||
.layout-options { display: flex; flex-direction: column; gap: 10px; }
|
||||
.layout-options label { display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 8px; border-radius: 6px; transition: background 0.2s ease; }
|
||||
.layout-options label:hover { background: rgba(255,255,255,0.05); }
|
||||
.layout-options label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
.layout-options label:hover { background: var(--surface); }
|
||||
.logo-options { display: flex; flex-direction: column; gap: 12px; }
|
||||
.logo-options label { display: flex; align-items: center; gap: 8px; }
|
||||
.logo-options input[type="text"] { flex: 1; }
|
||||
|
||||
/* Color customization controls */
|
||||
.color-controls { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; }
|
||||
.color-group { display: flex; flex-direction: column; gap: 5px; }
|
||||
.color-group label { font-size: 0.9rem; color: var(--text); opacity: 0.9; }
|
||||
.color-group { display: flex; flex-direction: column; gap: 8px; }
|
||||
.color-group label { font-size: 14px; color: var(--text-secondary); font-weight: 500; }
|
||||
input[type="color"] {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
border: 1px solid rgba(255,255,255,0.2);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Preview area */
|
||||
.preview-container {
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.03)) !important;
|
||||
border-radius: 14px !important;
|
||||
border: 1px solid var(--card-border) !important;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
background: var(--surface) !important;
|
||||
border-radius: 8px !important;
|
||||
border: 1px solid var(--border) !important;
|
||||
box-shadow: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.preview-home {
|
||||
display: flex;
|
||||
@@ -462,9 +580,9 @@ input[type="color"] {
|
||||
gap: 15px;
|
||||
padding: 20px;
|
||||
background: var(--bg);
|
||||
border-radius: 8px;
|
||||
border-radius: 4px;
|
||||
min-height: 200px;
|
||||
border: 1px dashed rgba(255,255,255,0.12);
|
||||
border: 1px dashed var(--border);
|
||||
}
|
||||
.preview-text { letter-spacing: 0.3px; }
|
||||
.preview-logo { font-size: 1.5rem; font-weight: 700; color: var(--primary); }
|
||||
@@ -481,76 +599,122 @@ input[type="color"] {
|
||||
}
|
||||
#search-history-list li, #site-history-list li {
|
||||
list-style: none;
|
||||
padding: 8px 10px;
|
||||
background: rgba(255,255,255,0.03);
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
#site-history-list a {
|
||||
color: var(--accent);
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
#site-history-list a:hover { text-decoration: underline; }
|
||||
#site-history-list a:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--primary-hover);
|
||||
}
|
||||
|
||||
/* About buttons */
|
||||
.github-btn, .help-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background: var(--accent);
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
border: 1px solid rgba(255,255,255,0.08) !important;
|
||||
border-radius: 10px !important;
|
||||
border: 1px solid var(--border) !important;
|
||||
border-radius: 4px !important;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: transform 0.08s ease, box-shadow 0.2s ease, filter 0.2s ease;
|
||||
box-shadow: 0 6px 18px rgba(0,0,0,0.25);
|
||||
transition: background 0.15s ease;
|
||||
font-size: 14px;
|
||||
}
|
||||
.github-btn:hover, .help-btn:hover {
|
||||
background: var(--surface-hover);
|
||||
}
|
||||
.github-btn svg, .help-btn svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
.github-btn:hover, .help-btn:hover { filter: brightness(1.03) saturate(1.05); box-shadow: var(--glow); }
|
||||
.github-btn:active, .help-btn:active { transform: translateY(1px); }
|
||||
.about-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
|
||||
|
||||
/* Debug info */
|
||||
.debug-info {
|
||||
background: rgba(0,0,0,0.35) !important;
|
||||
border: 1px solid rgba(255,255,255,0.1);
|
||||
border-radius: 10px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
}
|
||||
|
||||
/* General lists inside cards */
|
||||
.customization-group ul { list-style: none; padding: 0; margin: 0; }
|
||||
.customization-group ul li { padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,0.06); }
|
||||
.customization-group ul li {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.customization-group ul li:last-child { border-bottom: none; }
|
||||
|
||||
/* Theme management buttons */
|
||||
.theme-management { display: flex; flex-wrap: wrap; gap: 10px; }
|
||||
#reset-to-default { background: linear-gradient(180deg, #e53e3e, #c53030); }
|
||||
#reset-to-default {
|
||||
background: #d41b2c;
|
||||
border-color: #d41b2c;
|
||||
color: white;
|
||||
}
|
||||
#reset-to-default:hover {
|
||||
background: #a4161a;
|
||||
border-color: #a4161a;
|
||||
}
|
||||
|
||||
/* Scrollbar styling (Chromium) */
|
||||
*::-webkit-scrollbar { height: 10px; width: 10px; }
|
||||
*::-webkit-scrollbar-track { background: rgba(255,255,255,0.04); border-radius: 999px; }
|
||||
*::-webkit-scrollbar-thumb { background: linear-gradient(180deg, rgba(123,46,255,0.7), rgba(0,198,255,0.7)); border-radius: 999px; }
|
||||
*::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, rgba(123,46,255,0.9), rgba(0,198,255,0.9)); }
|
||||
*::-webkit-scrollbar { height: 12px; width: 12px; }
|
||||
*::-webkit-scrollbar-track { background: var(--bg); }
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, var(--primary), var(--accent));
|
||||
border-radius: 6px;
|
||||
border: 2px solid var(--bg);
|
||||
}
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, var(--primary-hover), var(--accent));
|
||||
}
|
||||
|
||||
/* small-screen adjustments */
|
||||
@media (max-width: 480px) {
|
||||
.container {
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 0;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.35);
|
||||
}
|
||||
.container {
|
||||
flex-direction: column;
|
||||
max-width: 100%;
|
||||
height: 100vh;
|
||||
border-radius: 0;
|
||||
}
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 1rem;
|
||||
}
|
||||
.tabs { flex-direction: row; flex-wrap: wrap; gap: 6px; }
|
||||
.tab-link { flex: 1 1 auto; }
|
||||
h1 {
|
||||
.tabs {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
.tab-link {
|
||||
flex: 1 1 auto;
|
||||
min-width: 120px;
|
||||
}
|
||||
.content {
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
+31
-26
@@ -24,17 +24,20 @@
|
||||
<!-- General Panel -->
|
||||
<section class="tab-panel active" id="panel-general" role="tabpanel" aria-labelledby="tab-general">
|
||||
<h2>General</h2>
|
||||
|
||||
<div class="setting-group">
|
||||
<label for="clear-data-btn">Clear All Cookies & Data</label>
|
||||
<button id="clear-data-btn">Clear Data</button>
|
||||
<h3>Data Management</h3>
|
||||
<p class="note">Clear all cookies, cache, and browsing data stored locally on this device.</p>
|
||||
<div class="setting-row">
|
||||
<button id="clear-data-btn">Clear All Data</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="note">Settings are stored locally on this device.</p>
|
||||
|
||||
<!-- Big Picture Mode -->
|
||||
<div class="setting-group">
|
||||
<h3>🎮 Big Picture Mode</h3>
|
||||
<h3>Big Picture Mode</h3>
|
||||
<p class="note">A controller-friendly UI designed for Steam Deck and handheld devices.</p>
|
||||
<div style="display: flex; align-items: center; gap: 12px; margin-top: 10px;">
|
||||
<div class="setting-row">
|
||||
<button id="launch-bigpicture-btn" class="primary-btn">
|
||||
<span style="font-size: 18px;">🎮</span> Launch Big Picture Mode
|
||||
</button>
|
||||
@@ -43,21 +46,25 @@
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<h3>Weather</h3>
|
||||
<fieldset class="weather-units" style="display:flex; flex-direction:column; gap:8px; border:1px solid rgba(255,255,255,0.15); padding:10px; border-radius:8px;">
|
||||
<legend style="padding:0 6px; opacity:.85;">Temperature units</legend>
|
||||
<label><input type="radio" name="weather-unit" id="weather-unit-auto" value="auto" checked> Auto (based on locale)</label>
|
||||
<label><input type="radio" name="weather-unit" id="weather-unit-c" value="c"> Celsius (°C)</label>
|
||||
<label><input type="radio" name="weather-unit" id="weather-unit-f" value="f"> Fahrenheit (°F)</label>
|
||||
<h3>Weather Display</h3>
|
||||
<p class="note">Choose how temperature is displayed on the Home page weather card.</p>
|
||||
<fieldset class="weather-units settings-fieldset">
|
||||
<legend>Temperature units</legend>
|
||||
<label style="display: block; margin-bottom: 8px;"><input type="radio" name="weather-unit" id="weather-unit-auto" value="auto" checked> Auto (based on locale)</label>
|
||||
<label style="display: block; margin-bottom: 8px;"><input type="radio" name="weather-unit" id="weather-unit-c" value="c"> Celsius (°C)</label>
|
||||
<label style="display: block; margin-bottom: 8px;"><input type="radio" name="weather-unit" id="weather-unit-f" value="f"> Fahrenheit (°F)</label>
|
||||
</fieldset>
|
||||
<p class="note">Affects the weather card on the Home page.</p>
|
||||
</div>
|
||||
<div class="debug-info" id="debug-info">Loading debug info...</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<h3>System Information</h3>
|
||||
<div class="debug-info" id="debug-info">Loading debug info...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Appearance Panel -->
|
||||
<section class="tab-panel" id="panel-appearance" role="tabpanel" aria-labelledby="tab-appearance">
|
||||
<h2>🎨 Appearance</h2>
|
||||
<h2>Appearance</h2>
|
||||
<!-- Theme Selection -->
|
||||
<div class="customization-group">
|
||||
<h3>Theme Presets</h3>
|
||||
@@ -120,12 +127,10 @@
|
||||
<!-- Display Scale -->
|
||||
<div class="customization-group">
|
||||
<h3>Display Scale</h3>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px;">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<input type="range" id="display-scale-slider" min="50" max="300" value="100" step="10" style="flex: 1; cursor: pointer;">
|
||||
<span id="display-scale-value" style="min-width: 50px; text-align: right; font-weight: bold;">100%</span>
|
||||
</div>
|
||||
<p class="note">Adjust the default display scale (zoom) when opening the browser. Requires reload to take effect.</p>
|
||||
<p class="note">Adjust the default zoom level when opening the browser. Changes require a reload to take effect.</p>
|
||||
<div class="range-row">
|
||||
<input type="range" id="display-scale-slider" min="50" max="300" value="100" step="10">
|
||||
<span id="display-scale-value" class="range-value">100%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -214,7 +219,7 @@
|
||||
<div class="customization-group">
|
||||
<h3>Site History</h3>
|
||||
<ul id="site-history-list"></ul>
|
||||
<div style="display:flex; gap:10px; margin-top:10px; flex-wrap:wrap;">
|
||||
<div class="button-row" style="margin-top:10px;">
|
||||
<button id="clear-site-history-btn">Clear Site History</button>
|
||||
<button id="add-test-history-btn">Add Test History</button>
|
||||
</div>
|
||||
@@ -225,7 +230,7 @@
|
||||
<section class="tab-panel" id="panel-plugins" role="tabpanel" aria-labelledby="tab-plugins">
|
||||
<h2>Plugins</h2>
|
||||
<div class="customization-group">
|
||||
<div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center;">
|
||||
<div class="button-row">
|
||||
<button id="plugins-reload-all">Reload Plugins</button>
|
||||
<span class="note">Changes to renderer preloads may require app restart.</span>
|
||||
</div>
|
||||
@@ -273,7 +278,7 @@
|
||||
<h3>Security Updates</h3>
|
||||
<p class="note" style="margin-bottom: 12px;">Nebula Browser is distributed via Steam, but the Electron runtime can be updated separately for security patches and performance improvements.</p>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 12px;">
|
||||
<div class="stack">
|
||||
<!-- Update Status Banner -->
|
||||
<div id="electron-update-banner" style="display: none; padding: 12px; border-radius: 8px; background: rgba(123, 46, 255, 0.1); border: 1px solid rgba(123, 46, 255, 0.3);">
|
||||
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
|
||||
@@ -297,9 +302,9 @@
|
||||
|
||||
<!-- Version Info -->
|
||||
<div style="font-size: 0.9em; opacity: 0.8;">
|
||||
<div style="display: flex; gap: 8px; align-items: center; margin-bottom: 8px;">
|
||||
<label for="electron-version-select" style="min-width: 100px;">Update Channel:</label>
|
||||
<select id="electron-version-select" style="flex: 1; padding: 8px; border-radius: 4px; background-color: var(--secondary, #00C6FF); color: var(--bg, #121418); border: none; cursor: pointer;">
|
||||
<div class="setting-row" style="margin-bottom: 8px;">
|
||||
<label for="electron-version-select" class="label-min">Update Channel:</label>
|
||||
<select id="electron-version-select">
|
||||
<option value="stable">Stable (Recommended)</option>
|
||||
<option value="nightly">Nightly (Latest Features)</option>
|
||||
</select>
|
||||
|
||||
@@ -300,6 +300,56 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
initTabs();
|
||||
});
|
||||
|
||||
// Apply current theme to settings page
|
||||
function applyCurrentThemeToSettings() {
|
||||
if (!window.BrowserCustomizer) return;
|
||||
|
||||
const savedTheme = localStorage.getItem('nebula-theme');
|
||||
let theme = null;
|
||||
|
||||
if (savedTheme) {
|
||||
try {
|
||||
theme = JSON.parse(savedTheme);
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse saved theme', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!theme || !theme.colors) return;
|
||||
|
||||
// Apply theme colors to CSS variables
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--bg', theme.colors.bg || '#121418');
|
||||
root.style.setProperty('--gradient-end', theme.colors.darkPurple || '#1B1035');
|
||||
root.style.setProperty('--primary', theme.colors.primary || '#7B2EFF');
|
||||
root.style.setProperty('--accent', theme.colors.accent || '#00C6FF');
|
||||
root.style.setProperty('--text', theme.colors.text || '#E0E0E0');
|
||||
|
||||
// Update glow colors based on theme
|
||||
const primaryRgb = hexToRgb(theme.colors.primary || '#7B2EFF');
|
||||
if (primaryRgb) {
|
||||
root.style.setProperty('--ring', `0 0 0 2px rgba(${primaryRgb.r}, ${primaryRgb.g}, ${primaryRgb.b}, 0.4)`);
|
||||
root.style.setProperty('--glow-subtle', `0 4px 20px rgba(${primaryRgb.r}, ${primaryRgb.g}, ${primaryRgb.b}, 0.15)`);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to convert hex to RGB
|
||||
function hexToRgb(hex) {
|
||||
const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
// Listen for theme changes
|
||||
window.addEventListener('storage', (e) => {
|
||||
if (e.key === 'nebula-theme') {
|
||||
applyCurrentThemeToSettings();
|
||||
}
|
||||
});
|
||||
|
||||
// About tab population
|
||||
async function populateAbout() {
|
||||
try {
|
||||
@@ -356,6 +406,7 @@ async function populateAbout() {
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
populateAbout();
|
||||
setupElectronUpdater();
|
||||
applyCurrentThemeToSettings();
|
||||
|
||||
// Refresh about info when About tab is clicked
|
||||
const aboutTabBtn = document.getElementById('tab-about');
|
||||
|
||||
Reference in New Issue
Block a user