代码块

This commit is contained in:
2026-06-20 10:11:10 +08:00 Unverified
parent 2abe35fa4e
commit 72143f35af
3 changed files with 171 additions and 75 deletions
+46 -9
View File
@@ -54,9 +54,18 @@ const consoleSites = [
<script is:inline> <script is:inline>
(() => { (() => {
const storageKey = 'site-theme'; const storageKey = 'site-theme';
const savedTheme = localStorage.getItem(storageKey); const media = window.matchMedia('(prefers-color-scheme: dark)');
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; const getSystemTheme = () => (media.matches ? 'dark' : 'light');
document.documentElement.dataset.theme = savedTheme || systemTheme; const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
document.documentElement.dataset.theme = getSavedTheme() || getSystemTheme();
})(); })();
</script> </script>
<link rel="stylesheet" href={siteConfig.cdn.instantsearchCss} /> <link rel="stylesheet" href={siteConfig.cdn.instantsearchCss} />
@@ -257,25 +266,53 @@ const consoleSites = [
const button = document.querySelector('[data-theme-toggle]'); const button = document.querySelector('[data-theme-toggle]');
const media = window.matchMedia('(prefers-color-scheme: dark)'); const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light'); const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getTheme = () => localStorage.getItem(storageKey) || getSystemTheme(); const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
const setSavedTheme = (theme) => {
try {
if (theme === getSystemTheme()) localStorage.removeItem(storageKey);
else localStorage.setItem(storageKey, theme);
} catch {
// localStorage can be unavailable in strict privacy modes.
}
};
const getTheme = () => getSavedTheme() || getSystemTheme();
function applyTheme(theme) { function applyTheme(theme) {
root.dataset.theme = theme; root.dataset.theme = theme;
root.dataset.themeMode = getSavedTheme() ? 'manual' : 'auto';
button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式'); button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute('title', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式'); button?.setAttribute(
'title',
getSavedTheme()
? (theme === 'dark' ? '切换到日间模式' : '切换到夜间模式')
: `跟随系统:${theme === 'dark' ? '夜间' : '日间'}模式`
);
} }
applyTheme(getTheme()); applyTheme(getTheme());
button?.addEventListener('click', () => { button?.addEventListener('click', () => {
const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark'; const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark';
localStorage.setItem(storageKey, nextTheme); setSavedTheme(nextTheme);
applyTheme(nextTheme); applyTheme(nextTheme);
}); });
media.addEventListener('change', () => { const handleSystemThemeChange = () => {
if (!localStorage.getItem(storageKey)) applyTheme(getSystemTheme()); if (!getSavedTheme()) applyTheme(getSystemTheme());
}); };
if (typeof media.addEventListener === 'function') {
media.addEventListener('change', handleSystemThemeChange);
} else if (typeof media.addListener === 'function') {
media.addListener(handleSystemThemeChange);
}
})(); })();
(() => { (() => {
+14 -2
View File
@@ -390,9 +390,17 @@ const relatedPosts = allPosts
toggleButton.textContent = '展开'; toggleButton.textContent = '展开';
toggleButton.setAttribute('aria-expanded', 'false'); toggleButton.setAttribute('aria-expanded', 'false');
const expandCue = document.createElement('button');
expandCue.className = 'code-block-expand-cue';
expandCue.type = 'button';
expandCue.setAttribute('aria-label', 'Expand code block');
expandCue.setAttribute('aria-expanded', 'false');
expandCue.innerHTML = '<span aria-hidden="true"></span>';
toolbar.append(copyButton, toggleButton); toolbar.append(copyButton, toggleButton);
header.append(language, toolbar); header.append(language, toolbar);
wrapper.appendChild(header); wrapper.appendChild(header);
wrapper.appendChild(expandCue);
const codeLines = [...code.querySelectorAll(':scope > .line')]; const codeLines = [...code.querySelectorAll(':scope > .line')];
if (codeLines.length > 0) { if (codeLines.length > 0) {
@@ -421,11 +429,15 @@ const relatedPosts = allPosts
} }
}); });
toggleButton.addEventListener('click', () => { function toggleExpanded() {
const isExpanded = wrapper.classList.toggle('is-expanded'); const isExpanded = wrapper.classList.toggle('is-expanded');
toggleButton.textContent = isExpanded ? '收起' : '展开'; toggleButton.textContent = isExpanded ? '收起' : '展开';
toggleButton.setAttribute('aria-expanded', String(isExpanded)); toggleButton.setAttribute('aria-expanded', String(isExpanded));
}); expandCue.setAttribute('aria-expanded', String(isExpanded));
}
toggleButton.addEventListener('click', toggleExpanded);
expandCue.addEventListener('click', toggleExpanded);
}); });
})(); })();
</script> </script>
+111 -64
View File
@@ -19,14 +19,14 @@
:root[data-theme='dark'] { :root[data-theme='dark'] {
color-scheme: dark; color-scheme: dark;
--bg: #0f171a; --bg: #0b1014;
--surface: #162225; --surface: #141b21;
--text: #e9f0ee; --text: #e7edf0;
--muted: #a7b4b1; --muted: #9ba9b1;
--line: rgba(174, 205, 197, 0.18); --line: rgba(166, 184, 194, 0.2);
--accent: #72ded2; --accent: #7dd3c7;
--accent-strong: #9af0d6; --accent-strong: #b7e7d4;
--shadow: 0 18px 48px rgba(0, 0, 0, 0.28); --shadow: 0 18px 52px rgba(0, 0, 0, 0.36);
} }
* { * {
@@ -49,7 +49,7 @@ body {
:root[data-theme='dark'] body { :root[data-theme='dark'] body {
background: background:
linear-gradient(rgba(8, 13, 16, 0.86), rgba(10, 17, 20, 0.94)), linear-gradient(rgba(7, 10, 14, 0.9), rgba(8, 13, 17, 0.96)),
url('/images/background.png') center top / cover fixed; url('/images/background.png') center top / cover fixed;
} }
@@ -563,20 +563,20 @@ a {
} }
:root[data-theme='dark'] .nav { :root[data-theme='dark'] .nav {
border-color: rgba(174, 205, 197, 0.2); border-color: rgba(166, 184, 194, 0.2);
background: background:
linear-gradient(135deg, rgba(29, 47, 51, 0.78), rgba(14, 23, 27, 0.54)), linear-gradient(135deg, rgba(25, 35, 42, 0.82), rgba(10, 15, 20, 0.66)),
rgba(12, 19, 22, 0.62); rgba(10, 15, 20, 0.68);
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.12),
inset 0 -18px 38px rgba(0, 0, 0, 0.18), inset 0 -18px 38px rgba(0, 0, 0, 0.18),
0 18px 54px rgba(0, 0, 0, 0.34); 0 18px 54px rgba(0, 0, 0, 0.42);
} }
:root[data-theme='dark'] .nav::before { :root[data-theme='dark'] .nav::before {
background: background:
radial-gradient(circle at 18% 0%, rgba(114, 222, 210, 0.18), transparent 32%), radial-gradient(circle at 18% 0%, rgba(125, 211, 199, 0.16), transparent 32%),
linear-gradient(90deg, rgba(255, 255, 255, 0.08), transparent 42%, rgba(114, 222, 210, 0.1)); linear-gradient(90deg, rgba(255, 255, 255, 0.07), transparent 42%, rgba(125, 211, 199, 0.08));
} }
:root[data-theme='dark'] .nav::after { :root[data-theme='dark'] .nav::after {
@@ -589,8 +589,8 @@ a {
:root[data-theme='dark'] .nav-console:hover, :root[data-theme='dark'] .nav-console:hover,
:root[data-theme='dark'] .theme-toggle:hover, :root[data-theme='dark'] .theme-toggle:hover,
:root[data-theme='dark'] .nav-menu-toggle:hover { :root[data-theme='dark'] .nav-menu-toggle:hover {
border-color: rgba(114, 222, 210, 0.26); border-color: rgba(125, 211, 199, 0.28);
background: rgba(114, 222, 210, 0.12); background: rgba(125, 211, 199, 0.11);
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.12),
0 8px 18px rgba(0, 0, 0, 0.18); 0 8px 18px rgba(0, 0, 0, 0.18);
@@ -601,14 +601,14 @@ a {
} }
:root[data-theme='dark'] .control-console-panel { :root[data-theme='dark'] .control-console-panel {
border-color: rgba(174, 205, 197, 0.18); border-color: rgba(166, 184, 194, 0.2);
background: background:
radial-gradient(circle at 14% 0%, rgba(114, 222, 210, 0.1), transparent 34%), radial-gradient(circle at 14% 0%, rgba(125, 211, 199, 0.08), transparent 34%),
linear-gradient(145deg, rgba(28, 43, 47, 0.88), rgba(12, 22, 25, 0.8)), linear-gradient(145deg, rgba(24, 34, 42, 0.9), rgba(10, 17, 22, 0.84)),
rgba(17, 28, 31, 0.82); rgba(14, 22, 28, 0.84);
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 28px 80px rgba(0, 0, 0, 0.38); 0 28px 80px rgba(0, 0, 0, 0.46);
} }
:root[data-theme='dark'] .control-console-head h2, :root[data-theme='dark'] .control-console-head h2,
@@ -620,8 +620,8 @@ a {
:root[data-theme='dark'] .control-site-card, :root[data-theme='dark'] .control-site-card,
:root[data-theme='dark'] .control-console-info section, :root[data-theme='dark'] .control-console-info section,
:root[data-theme='dark'] .control-console-close { :root[data-theme='dark'] .control-console-close {
border-color: rgba(114, 222, 210, 0.2); border-color: rgba(125, 211, 199, 0.2);
background: rgba(114, 222, 210, 0.1); background: rgba(125, 211, 199, 0.08);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
} }
@@ -631,35 +631,35 @@ a {
} }
:root[data-theme='dark'] .custom-context-menu { :root[data-theme='dark'] .custom-context-menu {
border-color: rgba(174, 205, 197, 0.2); border-color: rgba(166, 184, 194, 0.2);
color: #d8e5e2; color: #d8e5e2;
background: background:
linear-gradient(145deg, rgba(31, 48, 52, 0.88), rgba(13, 23, 26, 0.78)), linear-gradient(145deg, rgba(27, 39, 47, 0.9), rgba(10, 17, 22, 0.82)),
rgba(15, 25, 28, 0.82); rgba(14, 22, 28, 0.84);
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 18px 42px rgba(0, 0, 0, 0.34); 0 18px 42px rgba(0, 0, 0, 0.42);
} }
:root[data-theme='dark'] .context-menu-nav :where(a, button) { :root[data-theme='dark'] .context-menu-nav :where(a, button) {
border-color: rgba(174, 205, 197, 0.16); border-color: rgba(166, 184, 194, 0.16);
color: #b7c7c4; color: #b7c3c8;
background: rgba(255, 255, 255, 0.06); background: rgba(255, 255, 255, 0.06);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
} }
:root[data-theme='dark'] .context-menu-group { :root[data-theme='dark'] .context-menu-group {
border-top-color: rgba(174, 205, 197, 0.16); border-top-color: rgba(166, 184, 194, 0.16);
} }
:root[data-theme='dark'] .custom-context-menu :where(a, button):hover, :root[data-theme='dark'] .custom-context-menu :where(a, button):hover,
:root[data-theme='dark'] .custom-context-menu :where(a, button):focus-visible { :root[data-theme='dark'] .custom-context-menu :where(a, button):focus-visible {
color: var(--accent); color: var(--accent);
background: rgba(114, 222, 210, 0.11); background: rgba(125, 211, 199, 0.1);
} }
:root[data-theme='dark'] .custom-context-menu i { :root[data-theme='dark'] .custom-context-menu i {
color: #a8b8b5; color: #a8b5ba;
} }
.hero { .hero {
@@ -2235,6 +2235,7 @@ time {
.prose .code-block.is-collapsible:not(.is-expanded)::after { .prose .code-block.is-collapsible:not(.is-expanded)::after {
content: ""; content: "";
position: absolute; position: absolute;
z-index: 1;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
@@ -2243,6 +2244,52 @@ time {
pointer-events: none; pointer-events: none;
} }
.code-block-expand-cue {
appearance: none;
-webkit-appearance: none;
position: absolute;
z-index: 3;
right: 50%;
bottom: 10px;
display: none;
width: 36px;
height: 28px;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 999px;
padding: 0;
background: rgba(22, 31, 36, 0.72);
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18);
cursor: pointer;
transform: translateX(50%);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
transition:
border-color 0.2s ease,
background-color 0.2s ease,
transform 0.2s ease;
}
.code-block-expand-cue span {
width: 10px;
height: 10px;
border-right: 2px solid rgba(255, 255, 255, 0.9);
border-bottom: 2px solid rgba(255, 255, 255, 0.9);
transform: translateY(-2px) rotate(45deg);
}
.code-block-expand-cue:hover,
.code-block-expand-cue:focus-visible {
border-color: rgba(255, 255, 255, 0.36);
background: rgba(62, 184, 190, 0.82);
transform: translateX(50%) translateY(-1px);
}
.prose .code-block.is-collapsible:not(.is-expanded) .code-block-expand-cue {
display: inline-flex;
}
.prose .code-block code { .prose .code-block code {
color: #e8edf2; color: #e8edf2;
line-height: 1.42; line-height: 1.42;
@@ -3882,11 +3929,11 @@ meting-js {
.pagination-link, .pagination-link,
.pagination-number .pagination-number
) { ) {
border-color: rgba(174, 205, 197, 0.18); border-color: rgba(166, 184, 194, 0.18);
background: background:
radial-gradient(circle at 14% 0%, rgba(114, 222, 210, 0.1), transparent 34%), radial-gradient(circle at 14% 0%, rgba(125, 211, 199, 0.08), transparent 34%),
linear-gradient(145deg, rgba(28, 43, 47, 0.82), rgba(12, 22, 25, 0.72)), linear-gradient(145deg, rgba(24, 34, 42, 0.84), rgba(10, 17, 22, 0.76)),
rgba(17, 28, 31, 0.74); rgba(14, 22, 28, 0.78);
box-shadow: var(--shadow); box-shadow: var(--shadow);
} }
@@ -3931,12 +3978,12 @@ meting-js {
} }
:root[data-theme='dark'] .chart-legend-item { :root[data-theme='dark'] .chart-legend-item {
border-color: rgba(174, 205, 197, 0.16); border-color: rgba(166, 184, 194, 0.16);
background: rgba(255, 255, 255, 0.05); background: rgba(255, 255, 255, 0.05);
} }
:root[data-theme='dark'] .pie-chart-track { :root[data-theme='dark'] .pie-chart-track {
stroke: rgba(174, 205, 197, 0.16); stroke: rgba(166, 184, 194, 0.16);
} }
:root[data-theme='dark'] .line-chart-dot { :root[data-theme='dark'] .line-chart-dot {
@@ -3954,9 +4001,9 @@ meting-js {
.post-copyright-action, .post-copyright-action,
.post-copyright-icon .post-copyright-icon
) { ) {
border-color: rgba(114, 222, 210, 0.22); border-color: rgba(125, 211, 199, 0.22);
color: var(--accent); color: var(--accent);
background: rgba(114, 222, 210, 0.1); background: rgba(125, 211, 199, 0.1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
} }
@@ -3980,30 +4027,30 @@ meting-js {
} }
:root[data-theme='dark'] .article-header-cover { :root[data-theme='dark'] .article-header-cover {
background: #0d1f21; background: #0d171d;
} }
:root[data-theme='dark'] .article-header-cover::before { :root[data-theme='dark'] .article-header-cover::before {
background: background:
linear-gradient(180deg, rgba(5, 12, 14, 0.54), rgba(7, 19, 21, 0.22) 38%, rgba(3, 10, 11, 0.82)), linear-gradient(180deg, rgba(5, 9, 12, 0.58), rgba(8, 16, 20, 0.28) 38%, rgba(3, 8, 11, 0.86)),
linear-gradient(90deg, rgba(5, 18, 20, 0.62), rgba(12, 60, 57, 0.16) 54%, rgba(5, 18, 20, 0.44)); linear-gradient(90deg, rgba(5, 13, 17, 0.66), rgba(20, 57, 58, 0.14) 54%, rgba(5, 13, 17, 0.48));
} }
:root[data-theme='dark'] .prose .code-block { :root[data-theme='dark'] .prose .code-block {
border-color: rgba(114, 222, 210, 0.2); border-color: rgba(125, 211, 199, 0.18);
background: rgba(5, 10, 12, 0.96); background: rgba(5, 8, 12, 0.96);
box-shadow: 0 14px 32px rgba(0, 0, 0, 0.24); box-shadow: 0 14px 32px rgba(0, 0, 0, 0.32);
} }
:root[data-theme='dark'] .prose :not(pre) > code { :root[data-theme='dark'] .prose :not(pre) > code {
border-color: rgba(114, 222, 210, 0.22); border-color: rgba(125, 211, 199, 0.22);
color: var(--accent); color: var(--accent);
background: rgba(114, 222, 210, 0.1); background: rgba(125, 211, 199, 0.1);
} }
:root[data-theme='dark'] .butterfly-note { :root[data-theme='dark'] .butterfly-note {
color: #dce9e6; color: #dce9e6;
background: rgba(114, 222, 210, 0.08); background: rgba(125, 211, 199, 0.08);
} }
:root[data-theme='dark'] .butterfly-note--disabled { :root[data-theme='dark'] .butterfly-note--disabled {
@@ -4015,7 +4062,7 @@ meting-js {
} }
:root[data-theme='dark'] .butterfly-hide-block__content { :root[data-theme='dark'] .butterfly-hide-block__content {
border-left-color: rgba(114, 222, 210, 0.22); border-left-color: rgba(125, 211, 199, 0.22);
} }
:root[data-theme='dark'] .prose table { :root[data-theme='dark'] .prose table {
@@ -4025,43 +4072,43 @@ meting-js {
:root[data-theme='dark'] .prose thead th { :root[data-theme='dark'] .prose thead th {
color: #effaf7; color: #effaf7;
background: background:
linear-gradient(135deg, rgba(40, 70, 70, 0.86), rgba(22, 41, 44, 0.76)), linear-gradient(135deg, rgba(35, 55, 61, 0.86), rgba(18, 31, 38, 0.78)),
rgba(13, 24, 27, 0.8); rgba(12, 21, 27, 0.84);
} }
:root[data-theme='dark'] .prose tbody tr:nth-child(even) td { :root[data-theme='dark'] .prose tbody tr:nth-child(even) td {
background: rgba(114, 222, 210, 0.07); background: rgba(125, 211, 199, 0.06);
} }
:root[data-theme='dark'] .prose tbody tr:hover td { :root[data-theme='dark'] .prose tbody tr:hover td {
background: rgba(114, 222, 210, 0.12); background: rgba(125, 211, 199, 0.1);
} }
:root[data-theme='dark'] .prose :where(th, td) { :root[data-theme='dark'] .prose :where(th, td) {
border-color: rgba(114, 222, 210, 0.12); border-color: rgba(125, 211, 199, 0.12);
} }
:root[data-theme='dark'] .site-footer { :root[data-theme='dark'] .site-footer {
color: rgba(197, 214, 211, 0.74); color: rgba(199, 211, 216, 0.76);
background: background:
linear-gradient(180deg, rgba(12, 20, 23, 0.68), rgba(8, 14, 17, 0.88)), linear-gradient(180deg, rgba(10, 16, 21, 0.7), rgba(6, 10, 14, 0.9)),
rgba(8, 14, 17, 0.84); rgba(7, 11, 15, 0.86);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
} }
:root[data-theme='dark'] .footer-socials a { :root[data-theme='dark'] .footer-socials a {
border-color: rgba(174, 205, 197, 0.18); border-color: rgba(166, 184, 194, 0.18);
color: rgba(218, 234, 231, 0.82); color: rgba(218, 234, 231, 0.82);
background: background:
linear-gradient(145deg, rgba(34, 51, 55, 0.78), rgba(14, 24, 27, 0.72)), linear-gradient(145deg, rgba(28, 40, 48, 0.8), rgba(10, 17, 22, 0.74)),
rgba(18, 29, 32, 0.72); rgba(14, 22, 28, 0.74);
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.08),
0 10px 24px rgba(0, 0, 0, 0.22); 0 10px 24px rgba(0, 0, 0, 0.3);
} }
:root[data-theme='dark'] .footer-bottom { :root[data-theme='dark'] .footer-bottom {
border-top-color: rgba(174, 205, 197, 0.16); border-top-color: rgba(166, 184, 194, 0.16);
} }
@media (min-width: 960px) { @media (min-width: 960px) {