2026-03-24 17:33:01 +00:00
|
|
|
|
---
|
2026-03-24 18:01:45 +00:00
|
|
|
|
import BaseLayout from "./BaseLayout.astro";
|
2026-04-13 19:35:33 +00:00
|
|
|
|
import Remark42Embed from "@/components/Remark42Embed.astro";
|
2026-04-18 18:38:42 +00:00
|
|
|
|
import PostNav from "@/components/Posts/PostNav.astro";
|
2026-09-17 07:05:12 +00:00
|
|
|
|
import TagLink from "@/components/TagLink.astro";
|
2026-04-18 19:29:51 +00:00
|
|
|
|
import PostMenu from "@/components/Posts/PostMenu.astro";
|
2026-04-24 22:12:09 +00:00
|
|
|
|
import Dialog from "@/components/Posts/Dialog.astro";
|
2026-04-15 23:43:42 +00:00
|
|
|
|
import { fade } from "astro:transitions";
|
2026-04-18 18:38:42 +00:00
|
|
|
|
import { getTranslations } from "@/i18n";
|
2026-03-24 18:01:45 +00:00
|
|
|
|
import "@/styles/global.css";
|
2026-03-25 07:25:40 +00:00
|
|
|
|
|
2026-04-18 19:29:51 +00:00
|
|
|
|
const { post, frontmatter, lang, slug, postId, headings } = Astro.props;
|
2026-04-04 09:48:25 +00:00
|
|
|
|
const comments = lang === "zh" ? "评论区" : "comments";
|
2026-03-25 07:25:40 +00:00
|
|
|
|
const t = getTranslations(lang);
|
2026-09-17 07:26:33 +00:00
|
|
|
|
const publishedDate = new Intl.DateTimeFormat(
|
|
|
|
|
|
lang === "zh" ? "zh-CN" : "en-US",
|
|
|
|
|
|
{
|
|
|
|
|
|
year: "numeric",
|
|
|
|
|
|
month: "long",
|
|
|
|
|
|
day: "numeric",
|
|
|
|
|
|
},
|
|
|
|
|
|
).format(frontmatter.pubDate);
|
2026-03-24 17:33:01 +00:00
|
|
|
|
---
|
2026-03-24 18:01:45 +00:00
|
|
|
|
|
2026-03-25 15:26:22 +00:00
|
|
|
|
<BaseLayout
|
2026-03-28 20:42:16 +00:00
|
|
|
|
pageTitle=`${frontmatter.title} - ${t.banner.title}`
|
2026-03-25 15:26:22 +00:00
|
|
|
|
description={frontmatter.description}
|
|
|
|
|
|
image={frontmatter.image?.url}
|
|
|
|
|
|
>
|
2026-09-17 08:16:27 +00:00
|
|
|
|
<div class="post-layout page-shell">
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<div id="reading-progress" aria-hidden="true"></div>
|
|
|
|
|
|
<a
|
|
|
|
|
|
href="/"
|
|
|
|
|
|
class="back-button"
|
|
|
|
|
|
id="back-button"
|
|
|
|
|
|
aria-label="Go back"
|
|
|
|
|
|
title="返回"
|
2026-04-10 22:22:44 +00:00
|
|
|
|
>
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
width="20"
|
|
|
|
|
|
height="20"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2.2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="M15 18l-6-6 6-6"></path>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
<PostMenu headings={headings} />
|
|
|
|
|
|
|
|
|
|
|
|
<article class="post-article">
|
|
|
|
|
|
<div class="post-header">
|
|
|
|
|
|
<div class="post-meta">
|
|
|
|
|
|
<h1 class="post-title" transition:name={`post-title-${postId}`}>
|
|
|
|
|
|
{frontmatter.title}
|
|
|
|
|
|
</h1>
|
|
|
|
|
|
<p class="description">
|
2026-09-17 08:16:27 +00:00
|
|
|
|
{frontmatter.description}
|
2026-09-17 05:35:59 +00:00
|
|
|
|
</p>
|
2026-09-17 07:26:33 +00:00
|
|
|
|
<p class="post-byline">
|
|
|
|
|
|
<span>{t.post.writtenBy} {frontmatter.author}</span>
|
|
|
|
|
|
<span class="byline-separator" aria-hidden="true">·</span>
|
|
|
|
|
|
<time datetime={frontmatter.pubDate.toISOString()}>
|
|
|
|
|
|
{t.post.publishedOn} {publishedDate}
|
|
|
|
|
|
</time>
|
2026-09-17 05:35:59 +00:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="tags" transition:name={`post-tags-${postId}`}>
|
|
|
|
|
|
{
|
|
|
|
|
|
frontmatter.tags.map((tag: string) => (
|
2026-09-17 07:05:12 +00:00
|
|
|
|
<TagLink tag={tag} lang={lang} />
|
2026-09-17 05:35:59 +00:00
|
|
|
|
))
|
|
|
|
|
|
}
|
|
|
|
|
|
</div>
|
2026-03-26 15:35:06 +00:00
|
|
|
|
</div>
|
2026-03-25 07:25:40 +00:00
|
|
|
|
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<img
|
|
|
|
|
|
src={frontmatter.image.url}
|
|
|
|
|
|
alt={frontmatter.image.alt}
|
|
|
|
|
|
class="post-cover"
|
|
|
|
|
|
transition:name={`post-image-${postId}`}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2026-03-24 18:01:45 +00:00
|
|
|
|
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<div class="post-divider"></div>
|
2026-03-25 08:12:49 +00:00
|
|
|
|
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<div class="post-content" transition:animate={fade({ duration: "0.2s" })}>
|
|
|
|
|
|
<slot />
|
|
|
|
|
|
</div>
|
2026-03-24 18:39:50 +00:00
|
|
|
|
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<Dialog />
|
2026-04-24 22:05:50 +00:00
|
|
|
|
|
2026-09-17 05:35:59 +00:00
|
|
|
|
<PostNav post={post} lang={lang} />
|
2026-04-18 18:38:42 +00:00
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
<section
|
|
|
|
|
|
id="comments"
|
|
|
|
|
|
class="comments-section"
|
|
|
|
|
|
aria-labelledby="comments-heading"
|
|
|
|
|
|
>
|
|
|
|
|
|
<h2 id="comments-heading">{comments}</h2>
|
|
|
|
|
|
{t.post.commentsDesc.map((line: string) => <p set:html={line} />)}
|
|
|
|
|
|
<Remark42Embed slug={slug} />
|
|
|
|
|
|
</section>
|
2026-09-17 05:35:59 +00:00
|
|
|
|
</article>
|
2026-09-17 08:16:27 +00:00
|
|
|
|
</div>
|
2026-03-24 18:01:45 +00:00
|
|
|
|
</BaseLayout>
|
2026-03-25 07:25:40 +00:00
|
|
|
|
|
2026-03-25 15:26:22 +00:00
|
|
|
|
<script
|
|
|
|
|
|
type="application/ld+json"
|
|
|
|
|
|
set:html={JSON.stringify({
|
|
|
|
|
|
"@context": "https://schema.org",
|
|
|
|
|
|
"@type": "BlogPosting",
|
|
|
|
|
|
headline: frontmatter.title,
|
|
|
|
|
|
description: frontmatter.description,
|
|
|
|
|
|
image: frontmatter.image
|
|
|
|
|
|
? [
|
|
|
|
|
|
new URL(
|
|
|
|
|
|
frontmatter.image.url ?? frontmatter.image,
|
|
|
|
|
|
Astro.site,
|
|
|
|
|
|
).toString(),
|
|
|
|
|
|
]
|
|
|
|
|
|
: undefined,
|
|
|
|
|
|
datePublished: frontmatter.pubDate,
|
|
|
|
|
|
dateModified: frontmatter.updatedDate ?? frontmatter.pubDate,
|
|
|
|
|
|
author: {
|
|
|
|
|
|
"@type": "Person",
|
|
|
|
|
|
name: "CLoverta",
|
|
|
|
|
|
},
|
|
|
|
|
|
mainEntityOfPage: {
|
|
|
|
|
|
"@type": "WebPage",
|
|
|
|
|
|
"@id": new URL(Astro.url.pathname, Astro.site).toString(),
|
|
|
|
|
|
},
|
|
|
|
|
|
})}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-04-10 22:22:44 +00:00
|
|
|
|
<script>
|
|
|
|
|
|
const initFloatingActions = () => {
|
|
|
|
|
|
const backButton = document.getElementById("back-button");
|
|
|
|
|
|
|
|
|
|
|
|
if (backButton && backButton.dataset.bound !== "true") {
|
|
|
|
|
|
const toggleBackButton = () => {
|
|
|
|
|
|
if (window.scrollY > 300) {
|
|
|
|
|
|
backButton.classList.add("show");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
backButton.classList.remove("show");
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
backButton.addEventListener("click", () => {
|
|
|
|
|
|
if (window.history.length > 1) {
|
|
|
|
|
|
window.history.back();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
window.location.href = "/";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener("scroll", toggleBackButton, {
|
|
|
|
|
|
passive: true,
|
|
|
|
|
|
});
|
|
|
|
|
|
toggleBackButton();
|
|
|
|
|
|
backButton.dataset.bound = "true";
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-09-17 08:16:27 +00:00
|
|
|
|
const initReadingProgress = () => {
|
|
|
|
|
|
const readingWindow = window as typeof window & {
|
|
|
|
|
|
__postReadingProgressHandler?: () => void;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (readingWindow.__postReadingProgressHandler) {
|
|
|
|
|
|
window.removeEventListener(
|
|
|
|
|
|
"scroll",
|
|
|
|
|
|
readingWindow.__postReadingProgressHandler,
|
|
|
|
|
|
);
|
|
|
|
|
|
window.removeEventListener(
|
|
|
|
|
|
"resize",
|
|
|
|
|
|
readingWindow.__postReadingProgressHandler,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2026-04-11 17:46:53 +00:00
|
|
|
|
|
|
|
|
|
|
const bar = document.getElementById("reading-progress");
|
2026-09-17 08:16:27 +00:00
|
|
|
|
const content = document.querySelector<HTMLElement>(".post-content");
|
|
|
|
|
|
if (!bar || !content) return;
|
|
|
|
|
|
|
2026-09-17 10:59:45 +00:00
|
|
|
|
// Keep the fixed progress bar outside Astro's animated page container.
|
|
|
|
|
|
// Otherwise the header's transformed compositor layer can paint above it.
|
|
|
|
|
|
if (bar.parentElement !== document.body) {
|
|
|
|
|
|
document.body.appendChild(bar);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
const updateProgress = () => {
|
|
|
|
|
|
const contentTop = content.getBoundingClientRect().top + window.scrollY;
|
|
|
|
|
|
const readableDistance = Math.max(
|
|
|
|
|
|
content.scrollHeight - window.innerHeight,
|
|
|
|
|
|
1,
|
|
|
|
|
|
);
|
|
|
|
|
|
const progress = Math.min(
|
|
|
|
|
|
Math.max((window.scrollY - contentTop) / readableDistance, 0),
|
|
|
|
|
|
1,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
bar.style.transform = `scaleX(${progress})`;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
readingWindow.__postReadingProgressHandler = updateProgress;
|
|
|
|
|
|
window.addEventListener("scroll", updateProgress, { passive: true });
|
|
|
|
|
|
window.addEventListener("resize", updateProgress);
|
|
|
|
|
|
updateProgress();
|
2026-04-11 17:46:53 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
initReadingProgress();
|
2026-04-10 22:22:44 +00:00
|
|
|
|
initFloatingActions();
|
2026-09-17 08:16:27 +00:00
|
|
|
|
document.addEventListener("astro:page-load", initReadingProgress);
|
2026-04-10 22:22:44 +00:00
|
|
|
|
document.addEventListener("astro:page-load", initFloatingActions);
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
2026-03-24 18:01:45 +00:00
|
|
|
|
<style>
|
2026-09-17 05:35:59 +00:00
|
|
|
|
.post-layout {
|
2026-09-17 08:16:27 +00:00
|
|
|
|
min-width: 0;
|
2026-09-17 05:35:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-15 23:43:42 +00:00
|
|
|
|
#reading-progress {
|
2026-04-11 17:46:53 +00:00
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
z-index: 9999;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
width: 100%;
|
2026-04-11 17:46:53 +00:00
|
|
|
|
height: 3px;
|
|
|
|
|
|
background: #5a89ff;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
transform: scaleX(0);
|
|
|
|
|
|
transform-origin: left center;
|
|
|
|
|
|
transition: transform 0.08s linear;
|
2026-04-11 17:46:53 +00:00
|
|
|
|
pointer-events: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-10 22:22:44 +00:00
|
|
|
|
.back-button {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 1.25rem;
|
|
|
|
|
|
left: 1.25rem;
|
|
|
|
|
|
width: 3rem;
|
|
|
|
|
|
height: 3rem;
|
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
text-decoration: none;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
border-top: #536493 1.5px dotted;
|
|
|
|
|
|
border-left: #536493 1.5px dotted;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
border-right: #536493 2.5px solid;
|
|
|
|
|
|
border-bottom: #536493 2.5px solid;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
background: color-mix(in srgb, var(--background-color) 94%, transparent);
|
2026-04-10 22:22:44 +00:00
|
|
|
|
color: #222;
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
visibility: hidden;
|
2026-04-11 17:46:53 +00:00
|
|
|
|
transform: translateY(-80px);
|
|
|
|
|
|
/* opacity: 0; */
|
2026-04-10 22:22:44 +00:00
|
|
|
|
transition:
|
|
|
|
|
|
opacity 0.2s ease,
|
2026-04-15 23:43:42 +00:00
|
|
|
|
transform 0.27s ease,
|
|
|
|
|
|
visibility 0.2s ease,
|
2026-04-10 22:22:44 +00:00
|
|
|
|
box-shadow 0.2s ease,
|
|
|
|
|
|
background 0.2s ease,
|
|
|
|
|
|
color 0.2s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.back-button.show {
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
visibility: visible;
|
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.back-button.show:hover {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
transform: translateY(-2.5px);
|
|
|
|
|
|
box-shadow: 2px 3px 0px var(--deep-blue);
|
2026-04-10 22:22:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.back-button:hover {
|
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:global(.dark) .back-button {
|
2026-09-17 08:16:27 +00:00
|
|
|
|
background: color-mix(
|
|
|
|
|
|
in srgb,
|
|
|
|
|
|
var(--background-color-dark) 94%,
|
|
|
|
|
|
transparent
|
|
|
|
|
|
);
|
2026-04-10 22:22:44 +00:00
|
|
|
|
color: #f5f5f5;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
border-top-color: #515151;
|
|
|
|
|
|
border-left-color: #515151;
|
|
|
|
|
|
border-right-color: #515151;
|
|
|
|
|
|
border-bottom-color: #515151;
|
2026-04-10 22:22:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 640px) {
|
|
|
|
|
|
.back-button {
|
|
|
|
|
|
top: 1rem;
|
|
|
|
|
|
left: 1rem;
|
|
|
|
|
|
width: 2.75rem;
|
|
|
|
|
|
height: 2.75rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-26 15:35:06 +00:00
|
|
|
|
.post-content {
|
2026-09-17 08:16:27 +00:00
|
|
|
|
--article-muted: #596672;
|
|
|
|
|
|
--article-rule: rgba(83, 100, 147, 0.25);
|
|
|
|
|
|
--article-tint: rgba(83, 100, 147, 0.045);
|
2026-03-26 15:35:06 +00:00
|
|
|
|
font-family:
|
|
|
|
|
|
system-ui,
|
|
|
|
|
|
-apple-system,
|
|
|
|
|
|
BlinkMacSystemFont,
|
|
|
|
|
|
"Segoe UI",
|
|
|
|
|
|
"PingFang SC",
|
|
|
|
|
|
"Hiragino Sans GB",
|
|
|
|
|
|
"Microsoft YaHei",
|
|
|
|
|
|
"Noto Sans CJK SC",
|
|
|
|
|
|
"Source Han Sans SC",
|
|
|
|
|
|
sans-serif;
|
2026-04-16 17:50:59 +00:00
|
|
|
|
font-weight: 400;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
line-height: 1.85;
|
|
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(> :first-child) {
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(p) {
|
|
|
|
|
|
margin-block: 1.05em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(h2) {
|
|
|
|
|
|
margin: 3.2rem 0 1rem;
|
|
|
|
|
|
font-family: "Noto Sans SC", system-ui, sans-serif;
|
|
|
|
|
|
font-size: clamp(1.35rem, 2vw, 1.55rem);
|
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
|
text-wrap: balance;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(h3) {
|
|
|
|
|
|
margin: 2.25rem 0 0.8rem;
|
|
|
|
|
|
font-family: "Noto Sans SC", system-ui, sans-serif;
|
|
|
|
|
|
font-size: clamp(1.12rem, 1.6vw, 1.28rem);
|
|
|
|
|
|
line-height: 1.45;
|
|
|
|
|
|
text-wrap: balance;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(h4) {
|
|
|
|
|
|
margin: 1.8rem 0 0.65rem;
|
|
|
|
|
|
font-family: "Noto Sans SC", system-ui, sans-serif;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
font-size: 1.05em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(:is(h2, h3, h4) + :is(h3, h4, p, ul, ol)) {
|
|
|
|
|
|
margin-top: 0.7rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(ul),
|
|
|
|
|
|
.post-content :global(ol) {
|
|
|
|
|
|
margin-block: 1.1em;
|
|
|
|
|
|
padding-inline-start: 1.6em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(li::marker) {
|
|
|
|
|
|
color: var(--article-muted);
|
|
|
|
|
|
font-variant-numeric: tabular-nums;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(li > p) {
|
|
|
|
|
|
margin-block: 0.45em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(li > :is(ul, ol)) {
|
|
|
|
|
|
margin-block: 0.5em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(li + li) {
|
|
|
|
|
|
margin-top: 0.35rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(img:not(.code-copy-icon)) {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
height: auto;
|
|
|
|
|
|
margin-inline: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(figure) {
|
|
|
|
|
|
margin: 2rem 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(figcaption) {
|
|
|
|
|
|
margin-top: 0.55rem;
|
|
|
|
|
|
color: var(--article-muted);
|
|
|
|
|
|
font-family: "Noto Sans SC", system-ui, sans-serif;
|
|
|
|
|
|
font-size: 0.78rem;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(table) {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
margin-block: 1.75rem;
|
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
|
line-height: 1.65;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(th),
|
|
|
|
|
|
.post-content :global(td) {
|
|
|
|
|
|
padding: 0.65rem 0.85rem;
|
|
|
|
|
|
border-bottom: 1px solid var(--article-rule);
|
|
|
|
|
|
vertical-align: top;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(th) {
|
|
|
|
|
|
background: var(--article-tint);
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(a) {
|
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
|
text-decoration-thickness: 1px;
|
|
|
|
|
|
text-underline-offset: 0.2em;
|
|
|
|
|
|
text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(a:hover) {
|
|
|
|
|
|
text-decoration-color: currentColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(:is(a, summary):focus-visible) {
|
|
|
|
|
|
outline: 2px solid var(--deep-blue);
|
|
|
|
|
|
outline-offset: 3px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(hr) {
|
|
|
|
|
|
margin-block: 2.5rem;
|
|
|
|
|
|
border: 0;
|
|
|
|
|
|
border-top: 1px dashed var(--article-rule);
|
2026-03-26 15:35:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-content :global(code),
|
|
|
|
|
|
.post-content :global(pre),
|
|
|
|
|
|
.post-content :global(kbd),
|
|
|
|
|
|
.post-content :global(samp) {
|
|
|
|
|
|
font-family: "Maple Mono", "Maple Mono CN", monospace;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 18:01:45 +00:00
|
|
|
|
a {
|
2026-09-17 08:16:27 +00:00
|
|
|
|
color: var(--url-color);
|
2026-03-25 07:25:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-header {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: minmax(0, 1fr) 300px;
|
|
|
|
|
|
align-items: start;
|
|
|
|
|
|
gap: 1.5rem;
|
|
|
|
|
|
margin-bottom: 1.5rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-meta {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-title {
|
|
|
|
|
|
margin: 0 0 0.5rem 0;
|
|
|
|
|
|
line-height: 1.25;
|
|
|
|
|
|
overflow-wrap: anywhere;
|
|
|
|
|
|
word-break: break-word;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
text-wrap: balance;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.description {
|
|
|
|
|
|
margin: 0 0 0.7rem 0;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
color: #596672;
|
|
|
|
|
|
font-weight: 400;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
overflow-wrap: anywhere;
|
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 07:26:33 +00:00
|
|
|
|
.post-byline {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
gap: 0.3rem 0.55rem;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
margin: 0.3rem 0;
|
2026-09-17 07:26:33 +00:00
|
|
|
|
color: #66717c;
|
|
|
|
|
|
font-family: "Noto Sans SC", system-ui, sans-serif;
|
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
line-height: 1.5;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
overflow-wrap: anywhere;
|
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 07:26:33 +00:00
|
|
|
|
.byline-separator {
|
|
|
|
|
|
opacity: 0.65;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:global(html.dark) .post-byline {
|
|
|
|
|
|
color: #aab7c4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
:global(html.dark) .description {
|
|
|
|
|
|
color: #b5bec7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (min-width: 701px) {
|
|
|
|
|
|
.post-title {
|
|
|
|
|
|
margin-bottom: 0.85rem;
|
|
|
|
|
|
font-size: clamp(1.7rem, 2.2vw, 2rem);
|
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.description {
|
|
|
|
|
|
margin-bottom: 1rem;
|
|
|
|
|
|
font-size: 1rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-25 07:25:40 +00:00
|
|
|
|
.post-cover {
|
|
|
|
|
|
width: 300px;
|
|
|
|
|
|
height: auto;
|
2026-04-15 23:43:42 +00:00
|
|
|
|
aspect-ratio: 16 / 10;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
object-fit: cover;
|
|
|
|
|
|
object-position: center;
|
|
|
|
|
|
display: block;
|
2026-03-24 18:01:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-25 08:12:49 +00:00
|
|
|
|
.post-divider {
|
|
|
|
|
|
border-top: 1px dashed #dfe4e9;
|
|
|
|
|
|
margin: 1.2rem 0 1.5rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:global(.dark) .post-divider {
|
|
|
|
|
|
border-top-color: #7f91a3;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 18:01:45 +00:00
|
|
|
|
.tags {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
2026-09-17 07:05:12 +00:00
|
|
|
|
gap: 0.25rem 0.9rem;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
margin-top: 0.8rem;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
font-size: 0.88rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 07:10:30 +00:00
|
|
|
|
@media (max-width: 560px) {
|
2026-03-25 07:25:40 +00:00
|
|
|
|
.post-header {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.post-cover {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
max-width: 100%;
|
2026-04-15 23:43:42 +00:00
|
|
|
|
aspect-ratio: 16 / 9;
|
2026-03-25 07:25:40 +00:00
|
|
|
|
}
|
2026-03-24 18:01:45 +00:00
|
|
|
|
}
|
2026-06-01 18:35:05 +00:00
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
margin: 1.5rem 0;
|
|
|
|
|
|
overflow: hidden;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
border-top: 1px solid var(--article-rule);
|
|
|
|
|
|
border-bottom: 1px solid var(--article-rule);
|
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
|
background: var(--article-tint);
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details summary) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 0.5rem;
|
|
|
|
|
|
padding: 0.8rem 0.9rem;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
list-style: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details summary::-webkit-details-marker) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details summary::before) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
content: "›";
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
font-size: 1.25rem;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
transition: transform 0.2s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details[open] summary::before) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
transform: rotate(90deg);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 展开内容 */
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details > :not(summary)) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
box-sizing: border-box;
|
2026-09-17 08:16:27 +00:00
|
|
|
|
margin: 0.8rem 1rem;
|
|
|
|
|
|
padding: 0;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
2026-06-01 18:35:05 +00:00
|
|
|
|
|
2026-07-25 10:51:08 +00:00
|
|
|
|
/* 为列表序号预留空间 */
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details > ol),
|
|
|
|
|
|
.post-content :global(details > ul) {
|
|
|
|
|
|
padding-inline-start: 1.6em;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(details li) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
margin: 0.8rem 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(blockquote) {
|
|
|
|
|
|
margin: 1.5rem 0;
|
|
|
|
|
|
padding: 0.15rem 0 0.15rem 1rem;
|
|
|
|
|
|
border-left: 3px solid var(--deep-blue);
|
|
|
|
|
|
color: var(--article-muted);
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
border-radius: 0;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(blockquote p) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(blockquote p + p) {
|
2026-07-25 10:51:08 +00:00
|
|
|
|
margin-top: 0.75rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 块级公式:超出屏幕时只滚动公式,不撑宽整篇文章 */
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(.katex-display) {
|
2026-06-01 18:35:05 +00:00
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
|
padding: 0.25rem 0;
|
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
2026-06-01 18:35:05 +00:00
|
|
|
|
|
2026-07-25 10:51:08 +00:00
|
|
|
|
/* 避免 KaTeX 内部元素强行把父容器撑宽 */
|
2026-09-17 08:16:27 +00:00
|
|
|
|
.post-content :global(.katex-display > .katex) {
|
2026-06-01 18:35:05 +00:00
|
|
|
|
min-width: max-content;
|
2026-07-25 10:51:08 +00:00
|
|
|
|
}
|
2026-09-17 08:16:27 +00:00
|
|
|
|
|
|
|
|
|
|
.comments-section {
|
|
|
|
|
|
scroll-margin-top: 5rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:global(html.dark) .post-content {
|
|
|
|
|
|
--article-muted: #aab7c4;
|
|
|
|
|
|
--article-rule: rgba(170, 183, 196, 0.28);
|
|
|
|
|
|
--article-tint: rgba(170, 183, 196, 0.055);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:global(html.dark) .post-content :global(blockquote) {
|
|
|
|
|
|
border-left-color: #9ecbff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
|
|
|
|
#reading-progress {
|
|
|
|
|
|
transition: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-24 18:01:45 +00:00
|
|
|
|
</style>
|