From 8ccbdf4a2e5075b772fc32ca3cac9f952640e378 Mon Sep 17 00:00:00 2001
From: yuetsh <517252939@qq.com>
Date: Tue, 13 Jan 2026 21:59:03 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E7=A7=8D=E4=B8=BB=E9=A2=98=E7=9A=84?=
=?UTF-8?q?=E5=88=87=E6=8D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
index.html | 69 ++++--
main.js | 177 ++++++++++++++--
style.css | 601 +++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 713 insertions(+), 134 deletions(-)
diff --git a/index.html b/index.html
index 4255934..c1529a1 100644
--- a/index.html
+++ b/index.html
@@ -9,10 +9,54 @@
-
+
+
+
+
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);
}