Pārlūkot izejas kodu

fix(theme): default to dark, polish theme cycle visibility and hover

New installs land on plain dark instead of ultra-dark. The cycle button
icon now has an explicit colour so it stays visible inside the mobile
drawer (the previous color:inherit didn't cascade through the teleported
node), and hover/focus matches the menu's blue across sidebar, login,
and sub pages.
MHSanaei 17 stundas atpakaļ
vecāks
revīzija
88061bac10

+ 22 - 5
frontend/src/components/AppSidebar.vue

@@ -128,7 +128,8 @@ function cycleTheme() {
           <svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
             stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
             <circle cx="12" cy="12" r="4" />
-            <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
+            <path
+              d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
           </svg>
           <svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
             stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -169,7 +170,8 @@ function cycleTheme() {
             <svg v-if="!theme.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
               stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
               <circle cx="12" cy="12" r="4" />
-              <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
+              <path
+                d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
             </svg>
             <svg v-else-if="!theme.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
               stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -275,16 +277,18 @@ function cycleTheme() {
   align-items: center;
   justify-content: center;
   cursor: pointer;
-  color: inherit;
+  color: rgba(0, 0, 0, 0.75);
   padding: 0;
   flex-shrink: 0;
-  transition: background-color 0.2s, transform 0.15s;
+  transition: background-color 0.2s, transform 0.15s, color 0.2s;
 }
 
 .theme-cycle:hover,
 .theme-cycle:focus-visible {
-  background: rgba(128, 128, 128, 0.18);
+  background-color: rgba(64, 150, 255, 0.1);
+  color: #4096ff;
   transform: scale(1.08);
+  outline: none;
 }
 
 .theme-cycle svg {
@@ -446,6 +450,19 @@ html[data-theme='ultra-dark'] .drawer-close {
   color: rgba(255, 255, 255, 0.85);
 }
 
+/* Force a visible icon colour on the theme cycle button across themes.
+ * The scoped `color: inherit` previously relied on parent chain to
+ * cascade — fine on the desktop sider where `.sider-brand` is themed,
+ * but inside the teleported drawer body the cascade didn't reach and
+ * the icon merged into the dark background on mobile. */
+body.dark .theme-cycle {
+  color: rgba(255, 255, 255, 0.85);
+}
+
+html[data-theme='ultra-dark'] .theme-cycle {
+  color: rgba(255, 255, 255, 0.92);
+}
+
 /* Pin the drawer surface to the same colour the desktop sider uses
  * (Layout.colorBgHeader / Menu.colorItemBg from useTheme.js) so the
  * header, empty body region, and menu items read as one continuous

+ 1 - 1
frontend/src/composables/useTheme.js

@@ -16,7 +16,7 @@ function readBool(key, fallback) {
 }
 
 const isDark = readBool(STORAGE_DARK, true);
-const isUltra = readBool(STORAGE_ULTRA, true);
+const isUltra = readBool(STORAGE_ULTRA, false);
 
 export const theme = reactive({
   isDark,

+ 41 - 12
frontend/src/pages/login/LoginPage.vue

@@ -93,7 +93,8 @@ function cycleTheme() {
             <svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
               stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
               <circle cx="12" cy="12" r="4" />
-              <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
+              <path
+                d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
             </svg>
             <svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
               stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -277,24 +278,49 @@ function cycleTheme() {
 }
 
 @keyframes blob-drift-a {
-  0%   { transform: translate(0, 0) scale(1); }
-  50%  { transform: translate(18vw, 10vh) scale(1.15); }
-  100% { transform: translate(34vw, 22vh) scale(1.25); }
+  0% {
+    transform: translate(0, 0) scale(1);
+  }
+
+  50% {
+    transform: translate(18vw, 10vh) scale(1.15);
+  }
+
+  100% {
+    transform: translate(34vw, 22vh) scale(1.25);
+  }
 }
 
 @keyframes blob-drift-b {
-  0%   { transform: translate(0, 0) scale(1); }
-  50%  { transform: translate(-16vw, -10vh) scale(1.12); }
-  100% { transform: translate(-30vw, -22vh) scale(1.2); }
+  0% {
+    transform: translate(0, 0) scale(1);
+  }
+
+  50% {
+    transform: translate(-16vw, -10vh) scale(1.12);
+  }
+
+  100% {
+    transform: translate(-30vw, -22vh) scale(1.2);
+  }
 }
 
 @keyframes blob-drift-c {
-  0%   { transform: translate(-50%, -50%) scale(1); }
-  50%  { transform: translate(-20%, -20%) scale(1.1); }
-  100% { transform: translate(-80%, -10%) scale(1.05); }
+  0% {
+    transform: translate(-50%, -50%) scale(1);
+  }
+
+  50% {
+    transform: translate(-20%, -20%) scale(1.1);
+  }
+
+  100% {
+    transform: translate(-80%, -10%) scale(1.05);
+  }
 }
 
 @media (prefers-reduced-motion: reduce) {
+
   .login-app::before,
   .login-app::after,
   .login-content::before {
@@ -310,7 +336,7 @@ function cycleTheme() {
   position: relative;
 }
 
-.login-content > * {
+.login-content>* {
   position: relative;
   z-index: 1;
 }
@@ -347,7 +373,8 @@ function cycleTheme() {
 
 .theme-cycle:hover,
 .theme-cycle:focus-visible {
-  color: var(--color-accent);
+  background-color: rgba(64, 150, 255, 0.1);
+  color: #4096ff;
   transform: scale(1.05);
   outline: none;
 }
@@ -428,10 +455,12 @@ function cycleTheme() {
 .headline-leave-active {
   transition: opacity 280ms ease, transform 280ms ease;
 }
+
 .headline-enter-from {
   opacity: 0;
   transform: translateY(6px);
 }
+
 .headline-leave-to {
   opacity: 0;
   transform: translateY(-6px);

+ 5 - 2
frontend/src/pages/sub/SubPage.vue

@@ -164,7 +164,8 @@ const themeClass = computed(() => ({
                     <svg v-if="!themeState.isDark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                       stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                       <circle cx="12" cy="12" r="4" />
-                      <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
+                      <path
+                        d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
                     </svg>
                     <svg v-else-if="!themeState.isUltra" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                       stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -503,7 +504,8 @@ const themeClass = computed(() => ({
 
 .theme-cycle:hover,
 .theme-cycle:focus-visible {
-  color: #1677ff;
+  background-color: rgba(64, 150, 255, 0.1);
+  color: #4096ff;
   transform: scale(1.05);
   outline: none;
 }
@@ -520,6 +522,7 @@ const themeClass = computed(() => ({
 
 .is-dark .theme-cycle:hover,
 .is-dark .theme-cycle:focus-visible {
+  background-color: rgba(64, 150, 255, 0.1);
   color: #4096ff;
 }