diff --git a/index.html b/index.html index 4255934..c1529a1 100644 --- a/index.html +++ b/index.html @@ -9,10 +9,54 @@ - +
+ + +
@@ -24,16 +68,13 @@ 浙ICP备2023044109号 -
- 备案图标 - - 浙公网安备33100402331786号 - -
+ + 浙公网安备33100402331786号 +
diff --git a/main.js b/main.js index d985e88..e5433be 100644 --- a/main.js +++ b/main.js @@ -81,37 +81,186 @@ document.querySelector("#sites").innerHTML = pins.map(pin).join("") + sites.map(item).join("") // 主题切换功能 -const themeToggle = document.getElementById("themeToggle"); +const themeToggle = document.getElementById("themeToggle") +const designThemeButton = document.getElementById("designThemeButton") +const designThemeList = document.getElementById("designThemeList") + +const DESIGN_THEMES = ["fluent", "aurora", "forest", "sunset", "terminal"] // 获取保存的主题或系统偏好 function getInitialTheme() { - const savedTheme = localStorage.getItem("theme"); + const savedTheme = localStorage.getItem("theme") if (savedTheme) { - return savedTheme; + return savedTheme } // 如果没有保存的主题,使用系统偏好 return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" - : "light"; + : "light" } // 应用主题 function setTheme(theme) { - document.documentElement.setAttribute("data-theme", theme); - localStorage.setItem("theme", theme); + document.documentElement.setAttribute("data-theme", theme) + localStorage.setItem("theme", theme) // 图标通过 CSS 自动切换显示 } // 切换主题 function toggleTheme() { - const currentTheme = document.documentElement.getAttribute("data-theme") || "light"; - const newTheme = currentTheme === "dark" ? "light" : "dark"; - setTheme(newTheme); + if ( + document.documentElement.getAttribute("data-design-theme") === "terminal" + ) { + return + } + const currentTheme = + document.documentElement.getAttribute("data-theme") || "light" + const newTheme = currentTheme === "dark" ? "light" : "dark" + setTheme(newTheme) +} + +function getInitialDesignTheme() { + const savedDesignTheme = localStorage.getItem("designTheme") + if (savedDesignTheme && DESIGN_THEMES.includes(savedDesignTheme)) { + return savedDesignTheme + } + return "fluent" +} + +function setDesignTheme(designTheme) { + const safeDesignTheme = DESIGN_THEMES.includes(designTheme) + ? designTheme + : "fluent" + const previousDesignTheme = + document.documentElement.getAttribute("data-design-theme") || "fluent" + document.documentElement.setAttribute("data-design-theme", safeDesignTheme) + localStorage.setItem("designTheme", safeDesignTheme) + + if (safeDesignTheme === "terminal") { + if (previousDesignTheme !== "terminal") { + const currentTheme = + document.documentElement.getAttribute("data-theme") || "light" + localStorage.setItem("themeBeforeTerminal", currentTheme) + } + setTheme("dark") + } else if (previousDesignTheme === "terminal") { + const restoreTheme = localStorage.getItem("themeBeforeTerminal") + if (restoreTheme === "dark" || restoreTheme === "light") { + setTheme(restoreTheme) + } + localStorage.removeItem("themeBeforeTerminal") + } +} + +function getDesignThemeLabel(designTheme) { + const optionEl = designThemeList?.querySelector( + `[role="option"][data-value="${designTheme}"]`, + ) + if (optionEl) return optionEl.textContent?.trim() || "流光" + const fallback = { + fluent: "流光", + aurora: "极光", + forest: "森林", + sunset: "日落", + terminal: "终端", + } + return fallback[designTheme] || "流光" +} + +function setSelectedDesignThemeUI(designTheme) { + if (!designThemeList) return + const options = [...designThemeList.querySelectorAll('[role="option"]')] + options.forEach((el) => { + el.setAttribute( + "aria-selected", + el.getAttribute("data-value") === designTheme ? "true" : "false", + ) + }) + if (designThemeButton) { + designThemeButton.textContent = getDesignThemeLabel(designTheme) + } +} + +function setDesignThemeMenuOpen(open) { + if (!designThemeButton || !designThemeList) return + designThemeButton.setAttribute("aria-expanded", open ? "true" : "false") + designThemeList.hidden = !open + if (open) { + designThemeList.focus() + } +} + +function getCurrentDesignTheme() { + return document.documentElement.getAttribute("data-design-theme") || "fluent" } // 初始化主题 -const initialTheme = getInitialTheme(); -setTheme(initialTheme); +const initialTheme = getInitialTheme() +setTheme(initialTheme) + +const initialDesignTheme = getInitialDesignTheme() +setDesignTheme(initialDesignTheme) +setSelectedDesignThemeUI(initialDesignTheme) +setDesignThemeMenuOpen(false) + +if (designThemeButton && designThemeList) { + designThemeButton.addEventListener("click", () => { + const isOpen = designThemeButton.getAttribute("aria-expanded") === "true" + setDesignThemeMenuOpen(!isOpen) + }) + + designThemeList.addEventListener("click", (e) => { + const option = e.target.closest?.('[role="option"][data-value]') + if (!option) return + const value = option.getAttribute("data-value") + setDesignTheme(value) + setSelectedDesignThemeUI(value) + setDesignThemeMenuOpen(false) + }) + + document.addEventListener("click", (e) => { + if (!designThemeButton || !designThemeList) return + const clickedInside = + designThemeButton.contains(e.target) || designThemeList.contains(e.target) + if (!clickedInside) setDesignThemeMenuOpen(false) + }) + + document.addEventListener("keydown", (e) => { + const isOpen = designThemeButton.getAttribute("aria-expanded") === "true" + if (!isOpen) return + + if (e.key === "Escape") { + e.preventDefault() + setDesignThemeMenuOpen(false) + designThemeButton.focus() + return + } + + const options = [...designThemeList.querySelectorAll('[role="option"]')] + if (!options.length) return + const current = getCurrentDesignTheme() + const currentIndex = Math.max( + 0, + options.findIndex((el) => el.getAttribute("data-value") === current), + ) + + if (e.key === "ArrowDown" || e.key === "ArrowUp") { + e.preventDefault() + const delta = e.key === "ArrowDown" ? 1 : -1 + const nextIndex = (currentIndex + delta + options.length) % options.length + const nextValue = options[nextIndex].getAttribute("data-value") + setDesignTheme(nextValue) + setSelectedDesignThemeUI(nextValue) + return + } + + if (e.key === "Enter" || e.key === " ") { + e.preventDefault() + setDesignThemeMenuOpen(false) + designThemeButton.focus() + } + }) +} // 监听系统主题变化(仅在用户未手动设置时) window @@ -119,9 +268,9 @@ window .addEventListener("change", (e) => { // 如果用户没有手动设置过主题,则跟随系统 if (!localStorage.getItem("theme")) { - setTheme(e.matches ? "dark" : "light"); + setTheme(e.matches ? "dark" : "light") } - }); + }) // 绑定点击事件 -themeToggle.addEventListener("click", toggleTheme); +themeToggle.addEventListener("click", toggleTheme) diff --git a/style.css b/style.css index f132de8..ab24b83 100644 --- a/style.css +++ b/style.css @@ -3,23 +3,19 @@ body { padding: 0; margin: 0; font-family: - -apple-system, - BlinkMacSystemFont, - "Segoe UI", - Roboto, - Oxygen, - Ubuntu, - Cantarell, - "Fira Sans", - "Droid Sans", - "Helvetica Neue", - sans-serif; + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; min-height: 100vh; } -/* Fluent 2 柔和渐变背景 */ -body { - background: linear-gradient( +:root { + --accent: #0078d4; + --accent-rgb: 0, 120, 212; + --accent-2: #106ebe; + --accent-3: #005a9e; + --accent-secondary-rgb: 106, 90, 205; + + --page-gradient: linear-gradient( 135deg, #e3f2fd 0%, #f0f4ff 25%, @@ -27,6 +23,113 @@ body { #e8f0f8 75%, #dde8f5 100% ); + --page-texture: + radial-gradient( + circle at 20% 50%, + rgba(var(--accent-rgb), 0.03) 0%, + transparent 50% + ), + radial-gradient( + circle at 80% 80%, + rgba(var(--accent-secondary-rgb), 0.03) 0%, + transparent 50% + ); + --title-gradient: linear-gradient( + 135deg, + var(--accent) 0%, + var(--accent-2) 30%, + var(--accent-3) 60%, + var(--accent) 100% + ); + + --control-bg: rgba(255, 255, 255, 0.7); + --control-border: rgba(255, 255, 255, 0.8); + --control-inset: rgba(255, 255, 255, 0.9); + --control-fg: #323130; +} + +html[data-design-theme="aurora"] { + --accent: #7c4dff; + --accent-rgb: 124, 77, 255; + --accent-2: #5e35b1; + --accent-3: #4527a0; + --accent-secondary-rgb: 0, 188, 212; + --page-gradient: linear-gradient( + 135deg, + #f3e5f5 0%, + #ede7f6 25%, + #e8eaf6 50%, + #e0f7fa 75%, + #e3f2fd 100% + ); +} + +html[data-design-theme="forest"] { + --accent: #2e7d32; + --accent-rgb: 46, 125, 50; + --accent-2: #1b5e20; + --accent-3: #0d3d14; + --accent-secondary-rgb: 0, 150, 136; + --page-gradient: linear-gradient( + 135deg, + #e8f5e9 0%, + #e3f2fd 25%, + #f1f8e9 50%, + #e0f2f1 75%, + #e8f5e9 100% + ); +} + +html[data-design-theme="sunset"] { + --accent: #ff6d00; + --accent-rgb: 255, 109, 0; + --accent-2: #f44336; + --accent-3: #8e24aa; + --accent-secondary-rgb: 255, 64, 129; + --page-gradient: linear-gradient( + 135deg, + #fff3e0 0%, + #ffe0b2 25%, + #fce4ec 50%, + #ede7f6 75%, + #e3f2fd 100% + ); +} + +html[data-design-theme="terminal"] { + color-scheme: dark; + + --accent: #33ff00; + --accent-rgb: 51, 255, 0; + --accent-2: #33ff00; + --accent-3: #33ff00; + --accent-secondary-rgb: 255, 176, 0; + + --page-gradient: #0a0a0a; + --page-texture: + repeating-linear-gradient( + to bottom, + rgba(var(--accent-rgb), 0.035) 0px, + rgba(var(--accent-rgb), 0.035) 1px, + transparent 2px, + transparent 4px + ), + radial-gradient( + circle at 50% 50%, + rgba(var(--accent-rgb), 0.05) 0%, + transparent 60% + ); + --title-gradient: none; + + --control-bg: rgba(10, 10, 10, 0.85); + --control-border: rgba(var(--accent-rgb), 0.35); + --control-inset: transparent; + --control-fg: var(--accent); +} + +/* Fluent 2 柔和渐变背景 */ +body { + background: var(--page-gradient); background-attachment: fixed; position: relative; } @@ -39,9 +142,7 @@ body::before { left: 0; right: 0; bottom: 0; - background-image: - radial-gradient(circle at 20% 50%, rgba(0, 120, 212, 0.03) 0%, transparent 50%), - radial-gradient(circle at 80% 80%, rgba(106, 90, 205, 0.03) 0%, transparent 50%); + background-image: var(--page-texture); pointer-events: none; z-index: 0; } @@ -61,29 +162,155 @@ a { z-index: 1; } -/* 主题切换按钮 */ -.theme-toggle { +/* 主题控制区 */ +.theme-controls { position: fixed; top: 20px; right: 20px; + display: flex; + gap: 10px; + align-items: center; + z-index: 1000; +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.design-theme { + position: relative; + display: flex; + align-items: center; +} + +.design-theme-button { + height: 44px; + min-width: 118px; + border: 1px solid var(--control-border); + border-radius: 12px; + background: var(--control-bg); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.08), + 0 1px 2px rgba(0, 0, 0, 0.04), + inset 0 1px 0 var(--control-inset); + padding: 0 34px 0 14px; + font: inherit; + color: var(--control-fg); + cursor: pointer; + text-align: center; + justify-content: center; + position: relative; + display: inline-flex; + align-items: center; +} + +.design-theme-button::after { + content: "▾"; + position: absolute; + right: 14px; + top: 50%; + transform: translateY(-50%); + pointer-events: none; + opacity: 0.7; + color: var(--control-fg); +} + +.design-theme-button:hover { + border-color: rgba(var(--accent-rgb), 0.3); +} + +.design-theme-button:focus-visible { + outline: 2px solid rgba(var(--accent-rgb), 0.35); + outline-offset: 2px; +} + +.design-theme-list { + position: absolute; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + min-width: 160px; + max-height: 240px; + overflow: auto; + padding: 6px; + margin: 0; + list-style: none; + border: 1px solid var(--control-border); + border-radius: 14px; + background: rgba(255, 255, 255, 0.82); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + box-shadow: + 0 12px 30px rgba(0, 0, 0, 0.12), + 0 6px 12px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.9); + z-index: 1001; +} + +html[data-theme="dark"]:not([data-design-theme="terminal"]) .design-theme-list { + background: rgba(20, 20, 20, 0.8); + box-shadow: + 0 12px 30px rgba(0, 0, 0, 0.55), + 0 6px 12px rgba(0, 0, 0, 0.35), + inset 0 1px 0 rgba(255, 255, 255, 0.06); +} + +.design-theme-list [role="option"] { + padding: 10px 10px; + border-radius: 10px; + cursor: pointer; + color: var(--control-fg); + user-select: none; + text-align: center; + transition: + background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1), + color 0.15s cubic-bezier(0.4, 0, 0.2, 1); +} + +.design-theme-list [role="option"]:hover { + background: rgba(var(--accent-rgb), 0.12); + color: var(--control-fg); +} + +.design-theme-list [role="option"][aria-selected="true"] { + background: rgba(var(--accent-rgb), 0.18); + color: var(--control-fg); +} + +.design-theme-list [role="option"]:focus-visible { + outline: 2px solid rgba(var(--accent-rgb), 0.35); + outline-offset: 2px; +} + +/* 主题切换按钮 */ +.theme-toggle { width: 44px; height: 44px; border: none; border-radius: 12px; - background: rgba(255, 255, 255, 0.7); + background: var(--control-bg); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.8); - box-shadow: + border: 1px solid var(--control-border); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04), - inset 0 1px 0 rgba(255, 255, 255, 0.9); + inset 0 1px 0 var(--control-inset); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - z-index: 1000; padding: 0; } @@ -91,7 +318,9 @@ a { width: 20px; height: 20px; display: block; - transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1), transform 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transition: + opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1), + transform 0.2s cubic-bezier(0.4, 0, 0.2, 1); } .theme-icon-sun { @@ -102,22 +331,22 @@ a { display: block; } -html[data-theme="dark"] .theme-icon-sun { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .theme-icon-sun { display: block; } -html[data-theme="dark"] .theme-icon-moon { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .theme-icon-moon { display: none; } .theme-toggle:hover { transform: translateY(-2px); - box-shadow: - 0 8px 24px rgba(0, 120, 212, 0.15), + box-shadow: + 0 8px 24px rgba(var(--accent-rgb), 0.15), 0 4px 8px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.95); - border-color: rgba(0, 120, 212, 0.3); - color: #0078d4; + border-color: rgba(var(--accent-rgb), 0.3); + color: var(--accent); } .theme-toggle:active { @@ -125,25 +354,29 @@ html[data-theme="dark"] .theme-icon-moon { transition: all 0.1s cubic-bezier(0.4, 0, 0.2, 1); } -html[data-theme="dark"] .theme-toggle { - background: rgba(30, 30, 30, 0.7); - backdrop-filter: blur(20px) saturate(180%); - -webkit-backdrop-filter: blur(20px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: +html[data-theme="dark"]:not([data-design-theme="terminal"]) .theme-toggle { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05); - color: #ffffff; } -html[data-theme="dark"] .theme-toggle:hover { - border-color: rgba(0, 120, 212, 0.4); - box-shadow: - 0 8px 24px rgba(0, 120, 212, 0.25), +html[data-theme="dark"]:not([data-design-theme="terminal"]) + .design-theme-button { + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.3), + 0 1px 2px rgba(0, 0, 0, 0.2), + inset 0 1px 0 var(--control-inset); +} + +html[data-theme="dark"]:not([data-design-theme="terminal"]) + .theme-toggle:hover { + border-color: rgba(var(--accent-rgb), 0.4); + box-shadow: + 0 8px 24px rgba(var(--accent-rgb), 0.25), 0 4px 8px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1); - color: #60cdff; + color: var(--accent); } .main { @@ -169,13 +402,7 @@ html[data-theme="dark"] .theme-toggle:hover { /* Fluent 2 风格的标题渐变 - 使用 Fluent 蓝系 */ .title { - background: linear-gradient( - 135deg, - #0078d4 0%, - #106ebe 30%, - #005a9e 60%, - #0078d4 100% - ); + background: var(--title-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; @@ -210,22 +437,22 @@ html[data-theme="dark"] .theme-toggle:hover { color: inherit; text-decoration: none; max-width: 300px; - + /* 亚克力玻璃效果 */ background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); - + /* Fluent 2 圆角系统 - 等距圆角 */ border-radius: 12px; - + /* 高光描边效果 */ border: 1px solid rgba(255, 255, 255, 0.8); - box-shadow: + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.9); - + /* Fluent 交互动效 - 轻量空间变化 */ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transform: translateY(0); @@ -243,11 +470,13 @@ html[data-theme="dark"] .theme-toggle:hover { padding: 1px; background: linear-gradient( 135deg, - rgba(0, 120, 212, 0.1) 0%, + rgba(var(--accent-rgb), 0.1) 0%, rgba(255, 255, 255, 0.3) 50%, - rgba(0, 120, 212, 0.1) 100% + rgba(var(--accent-rgb), 0.1) 100% ); - -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask: + linear-gradient(#fff 0 0) content-box, + linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; @@ -264,13 +493,13 @@ html[data-theme="dark"] .theme-toggle:hover { /* Fluent 2 Hover 效果 - 轻量上浮 */ .card:hover, .card:focus { - color: #0078d4; + color: var(--accent); transform: translateY(-2px); - box-shadow: - 0 8px 24px rgba(0, 120, 212, 0.15), + box-shadow: + 0 8px 24px rgba(var(--accent-rgb), 0.15), 0 4px 8px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.95); - border-color: rgba(0, 120, 212, 0.3); + border-color: rgba(var(--accent-rgb), 0.3); } .card:hover::before, @@ -294,7 +523,7 @@ html[data-theme="dark"] .theme-toggle:hover { .card:hover h2, .card:focus h2 { - color: #0078d4; + color: var(--accent); } .card .title-icon { @@ -357,7 +586,132 @@ html[data-theme="dark"] .theme-toggle:hover { } .beian a:hover { - color: #0078d4; + color: var(--accent); +} + +@keyframes terminal-cursor-blink { + 0%, + 49% { + opacity: 1; + } + 50%, + 100% { + opacity: 0; + } +} + +html[data-design-theme="terminal"] body { + font-family: + ui-monospace, "JetBrains Mono", "Fira Code", "VT323", Menlo, Consolas, + "Liberation Mono", monospace; + letter-spacing: 0.01em; + color: var(--accent); +} + +html[data-design-theme="terminal"] .theme-controls { + gap: 12px; +} + +html[data-design-theme="terminal"] .design-theme-button, +html[data-design-theme="terminal"] .theme-toggle { + border-radius: 0; + box-shadow: none; + backdrop-filter: none; + -webkit-backdrop-filter: none; + border: 1px solid rgba(var(--accent-rgb), 0.55); +} + +html[data-design-theme="terminal"] .theme-toggle { + cursor: not-allowed; +} + +html[data-design-theme="terminal"] .design-theme-button:hover, +html[data-design-theme="terminal"] .theme-toggle:hover { + background: var(--accent); + color: #0a0a0a; + border-color: var(--accent); + transform: none; +} + +html[data-design-theme="terminal"] .design-theme-button::after { + color: currentColor; +} + +html[data-design-theme="terminal"] .design-theme-list { + border-radius: 0; + box-shadow: none; + backdrop-filter: none; + -webkit-backdrop-filter: none; + background: rgba(10, 10, 10, 0.92); + border: 1px solid rgba(var(--accent-rgb), 0.55); +} + +html[data-design-theme="terminal"] .design-theme-list [role="option"] { + border-radius: 0; + text-transform: uppercase; +} + +html[data-design-theme="terminal"] .design-theme-list [role="option"]:hover, +html[data-design-theme="terminal"] + .design-theme-list + [role="option"][aria-selected="true"] { + background: var(--accent); + color: #0a0a0a; +} + +html[data-design-theme="terminal"] .title { + background: none; + -webkit-text-fill-color: currentColor; + color: var(--accent); + text-shadow: 0 0 5px rgba(var(--accent-rgb), 0.5); + text-transform: uppercase; + letter-spacing: 0.04em; + position: relative; +} + +html[data-design-theme="terminal"] .title::after { + content: "█"; + margin-left: 8px; + animation: terminal-cursor-blink 1s step-end infinite; +} + +html[data-design-theme="terminal"] .card { + border-radius: 0; + background: transparent; + border: 1px solid rgba(var(--accent-rgb), 0.35); + box-shadow: none; + backdrop-filter: none; + -webkit-backdrop-filter: none; + transform: none; +} + +html[data-design-theme="terminal"] .card::before { + display: none; +} + +html[data-design-theme="terminal"] .card h2, +html[data-design-theme="terminal"] .card p, +html[data-design-theme="terminal"] .beian a { + color: var(--accent); + text-shadow: 0 0 5px rgba(var(--accent-rgb), 0.25); +} + +html[data-design-theme="terminal"] .card:hover, +html[data-design-theme="terminal"] .card:focus { + background: rgba(var(--accent-rgb), 0.06); + border-color: var(--accent); + box-shadow: none; +} + +html[data-design-theme="terminal"] .card:hover h2, +html[data-design-theme="terminal"] .card:focus h2 { + color: var(--accent); +} + +html[data-design-theme="terminal"] .beian a:hover { + background: var(--accent); + color: #0a0a0a; + text-shadow: none; } @media (max-width: 600px) { @@ -365,16 +719,27 @@ html[data-theme="dark"] .theme-toggle:hover { width: 100%; flex-direction: column; } + + .theme-controls { + top: 12px; + right: 12px; + gap: 8px; + } + + .design-theme-button { + min-width: 108px; + } } /* Fluent 2 深色模式 */ -html[data-theme="dark"] { +html[data-theme="dark"]:not([data-design-theme="terminal"]) { color-scheme: dark; -} + --accent: #60cdff; + --accent-rgb: 96, 205, 255; + --accent-2: #4fc3f7; + --accent-3: #29b6f6; -html[data-theme="dark"] body { - color: #ffffff; - background: linear-gradient( + --page-gradient: linear-gradient( 135deg, #1a1a1a 0%, #1f1f1f 25%, @@ -382,85 +747,109 @@ html[data-theme="dark"] body { #1d1d1d 75%, #1a1a1a 100% ); + --page-texture: + radial-gradient( + circle at 20% 50%, + rgba(var(--accent-rgb), 0.08) 0%, + transparent 50% + ), + radial-gradient( + circle at 80% 80%, + rgba(var(--accent-secondary-rgb), 0.08) 0%, + transparent 50% + ); + + --control-bg: rgba(30, 30, 30, 0.7); + --control-border: rgba(255, 255, 255, 0.1); + --control-inset: rgba(255, 255, 255, 0.05); + --control-fg: #ffffff; } -html[data-theme="dark"] body::before { - background-image: - radial-gradient(circle at 20% 50%, rgba(0, 120, 212, 0.08) 0%, transparent 50%), - radial-gradient(circle at 80% 80%, rgba(106, 90, 205, 0.08) 0%, transparent 50%); +html[data-theme="dark"]:not([data-design-theme="terminal"]) body { + color: #ffffff; } -html[data-theme="dark"] .title { - background: linear-gradient( - 135deg, - #60cdff 0%, - #4fc3f7 30%, - #29b6f6 60%, - #60cdff 100% - ); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - color: transparent; +html[data-theme="dark"][data-design-theme="aurora"] { + --accent: #b388ff; + --accent-rgb: 179, 136, 255; + --accent-2: #9575cd; + --accent-3: #7e57c2; + --accent-secondary-rgb: 77, 208, 225; } -html[data-theme="dark"] .card { +html[data-theme="dark"][data-design-theme="forest"] { + --accent: #66bb6a; + --accent-rgb: 102, 187, 106; + --accent-2: #43a047; + --accent-3: #2e7d32; + --accent-secondary-rgb: 38, 166, 154; +} + +html[data-theme="dark"][data-design-theme="sunset"] { + --accent: #ffb74d; + --accent-rgb: 255, 183, 77; + --accent-2: #ff8a65; + --accent-3: #ce93d8; + --accent-secondary-rgb: 244, 143, 177; +} + +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card { background: rgba(30, 30, 30, 0.7); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05); } -html[data-theme="dark"] .card::before { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card::before { background: linear-gradient( 135deg, - rgba(0, 120, 212, 0.2) 0%, + rgba(var(--accent-rgb), 0.2) 0%, rgba(255, 255, 255, 0.1) 50%, - rgba(0, 120, 212, 0.2) 100% + rgba(var(--accent-rgb), 0.2) 100% ); } -html[data-theme="dark"] .card h2 { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card h2 { color: #ffffff; } -html[data-theme="dark"] .card:hover h2, -html[data-theme="dark"] .card:focus h2 { - color: #60cdff; +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:hover h2, +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:focus h2 { + color: var(--accent); } -html[data-theme="dark"] .card:hover, -html[data-theme="dark"] .card:focus { - border-color: rgba(0, 120, 212, 0.4); - box-shadow: - 0 8px 24px rgba(0, 120, 212, 0.25), +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:hover, +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:focus { + border-color: rgba(var(--accent-rgb), 0.4); + box-shadow: + 0 8px 24px rgba(var(--accent-rgb), 0.25), 0 4px 8px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1); } -html[data-theme="dark"] .card p { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card p { color: #c8c6c4; } -html[data-theme="dark"] .card:hover p, -html[data-theme="dark"] .card:focus p { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:hover p, +html[data-theme="dark"]:not([data-design-theme="terminal"]) .card:focus p { color: #e1dfdd; } -html[data-theme="dark"] .pin.card { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .pin.card { background: rgba(40, 40, 40, 0.75); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); } -html[data-theme="dark"] .beian a { +html[data-theme="dark"]:not([data-design-theme="terminal"]) .beian a { color: #c8c6c4; } -html[data-theme="dark"] .beian a:hover { - color: #60cdff; +html[data-theme="dark"]:not([data-design-theme="terminal"]) .beian a:hover { + color: var(--accent); }