修改页面风格
This commit is contained in:
Generated
+269
-5534
File diff suppressed because it is too large
Load Diff
+3
-38
@@ -9,44 +9,9 @@
|
||||
"preview": "astro preview",
|
||||
"server": "astro dev"
|
||||
},
|
||||
"hexo": {
|
||||
"version": "8.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/rss": "^4.0.12",
|
||||
"@astrojs/sitemap": "^3.6.0",
|
||||
"astro": "^5.13.0",
|
||||
"axios": "^1.15.0",
|
||||
"cheerio": "^1.2.0",
|
||||
"hexo": "^8.1.1",
|
||||
"hexo-abbrlink": "^2.2.1",
|
||||
"hexo-ai-summary-liushen": "^2.0.0",
|
||||
"hexo-butterfly-swiper-lyx": "^1.0.2",
|
||||
"hexo-deployer-git": "^4.0.0",
|
||||
"hexo-douban": "^2.3.6",
|
||||
"hexo-filter-mathjax": "^0.9.1",
|
||||
"hexo-generator-archive": "^2.0.0",
|
||||
"hexo-generator-category": "^2.0.0",
|
||||
"hexo-generator-index": "^4.0.0",
|
||||
"hexo-generator-search": "^2.4.3",
|
||||
"hexo-generator-searchdb": "^1.5.0",
|
||||
"hexo-generator-sitemap": "^3.0.1",
|
||||
"hexo-generator-tag": "^2.0.0",
|
||||
"hexo-indexnow": "^1.2.0",
|
||||
"hexo-pretty-feed": "^2.1.0",
|
||||
"hexo-renderer-ejs": "^2.0.0",
|
||||
"hexo-renderer-marked": "^7.0.1",
|
||||
"hexo-renderer-pug": "^3.0.0",
|
||||
"hexo-renderer-stylus": "^3.0.1",
|
||||
"hexo-safego": "^2.3.0",
|
||||
"hexo-server": "^3.0.0",
|
||||
"hexo-spoiler": "^1.7.4",
|
||||
"hexo-wordcount": "^6.0.1",
|
||||
"moment": "^2.30.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"p-limit": "^7.3.0",
|
||||
"typesense": "^3.0.5",
|
||||
"vite-plugin-require-transform": "^1.0.21",
|
||||
"xml2js": "^0.6.2"
|
||||
"@astrojs/rss": "^4.0.18",
|
||||
"@astrojs/sitemap": "^3.7.3",
|
||||
"astro": "^6.4.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
import type { BlogPost } from '@/lib/posts';
|
||||
|
||||
type TocItem = {
|
||||
depth: number;
|
||||
text: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
interface Props {
|
||||
post: BlogPost;
|
||||
toc: TocItem[];
|
||||
relatedPosts: BlogPost[];
|
||||
}
|
||||
|
||||
const { post, toc, relatedPosts } = Astro.props;
|
||||
const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
|
||||
---
|
||||
|
||||
<aside class="article-sidebar" aria-label="文章侧边栏">
|
||||
<section class="sidebar-card article-author-card">
|
||||
<img class="profile-avatar" src={avatar} alt="biss" loading="lazy" />
|
||||
<div class="profile-name">biss</div>
|
||||
<div class="article-author-meta">
|
||||
<span>{post.dateText}</span>
|
||||
{post.categories[0] && <a href={`/categories/${encodeURIComponent(post.categories[0])}/`}>{post.categories[0]}</a>}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{toc.length > 0 && (
|
||||
<section class="sidebar-card toc-card">
|
||||
<h2>
|
||||
<span aria-hidden="true">☰</span>
|
||||
文章目录
|
||||
<em>{toc.length}</em>
|
||||
</h2>
|
||||
<nav class="toc-list" aria-label="文章目录">
|
||||
{toc.map((item) => (
|
||||
<a class={`toc-depth-${item.depth}`} href={`#${item.id}`}>{item.text}</a>
|
||||
))}
|
||||
</nav>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section class="sidebar-card same-category-card">
|
||||
<h2>
|
||||
<span aria-hidden="true">▣</span>
|
||||
同类文章
|
||||
<em>{relatedPosts.length}</em>
|
||||
</h2>
|
||||
{relatedPosts.length > 0 ? (
|
||||
<div class="same-category-list">
|
||||
{relatedPosts.map((item) => (
|
||||
<a href={item.href}>
|
||||
<strong>{item.title}</strong>
|
||||
<time datetime={item.date.toISOString()}>{item.dateText}</time>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p class="sidebar-empty">这个分类下暂时没有其他文章。</p>
|
||||
)}
|
||||
</section>
|
||||
</aside>
|
||||
@@ -0,0 +1,207 @@
|
||||
---
|
||||
import type { BlogPost } from '@/lib/posts';
|
||||
|
||||
interface Props {
|
||||
posts: BlogPost[];
|
||||
tags: string[];
|
||||
categories: string[];
|
||||
}
|
||||
|
||||
const { posts, tags, categories } = Astro.props;
|
||||
const avatar = 'https://free.picui.cn/free/2025/08/10/689845496a283.png';
|
||||
const recentPosts = posts.slice(0, 5);
|
||||
---
|
||||
|
||||
<aside class="home-sidebar" aria-label="首页侧边栏">
|
||||
<section class="sidebar-card profile-card">
|
||||
<img class="profile-avatar" src={avatar} alt="biss" loading="lazy" />
|
||||
<div class="profile-name">biss</div>
|
||||
<div class="profile-stats">
|
||||
<a href="/archives/">
|
||||
<span>文章</span>
|
||||
<strong>{posts.length}</strong>
|
||||
</a>
|
||||
<a href="/tags/">
|
||||
<span>标签</span>
|
||||
<strong>{tags.length}</strong>
|
||||
</a>
|
||||
<a href="/categories/">
|
||||
<span>分类</span>
|
||||
<strong>{categories.length}</strong>
|
||||
</a>
|
||||
</div>
|
||||
<a class="follow-button" href="https://github.com/bishshi" target="_blank" rel="noreferrer">
|
||||
<span class="github-mark" aria-hidden="true">GitHub</span>
|
||||
<span>Follow Me</span>
|
||||
</a>
|
||||
<div class="profile-links" aria-label="联系方式">
|
||||
<a href="https://github.com/bishshi" target="_blank" rel="noreferrer" aria-label="GitHub">GitHub</a>
|
||||
<a href="mailto:bishsh2006@gmail.com" aria-label="Email">Email</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sidebar-card notice-card">
|
||||
<h2><span aria-hidden="true">!</span> 公告</h2>
|
||||
<p>欢迎来自 <strong id="visitor-location">远方</strong> 的小友。</p>
|
||||
<p>烧烤三件套,灵魂蘸料。</p>
|
||||
<p id="visitor-distance">当前位置距离主约 <strong>473</strong> 公里!</p>
|
||||
<p id="aside-weather">当前天气加载中...</p>
|
||||
</section>
|
||||
|
||||
<div class="sticky-sidebar">
|
||||
<section class="sidebar-card calendar-card">
|
||||
<h2>日历</h2>
|
||||
<div class="calendar-widget">
|
||||
<div class="calendar-summary">
|
||||
<strong id="calendar-week">第--周 周--</strong>
|
||||
<span id="calendar-date">--</span>
|
||||
<small id="calendar-solar">----年--月 第--天</small>
|
||||
<small id="calendar-lunar">今天也很好</small>
|
||||
</div>
|
||||
<div class="calendar-grid" id="calendar-grid" aria-label="本月日历"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sidebar-card schedule-card">
|
||||
<h2>剩余时间</h2>
|
||||
<div class="schedule-widget">
|
||||
<div class="schedule-left">
|
||||
<strong>距离除夕</strong>
|
||||
<span id="new-year-days">--</span>
|
||||
<small id="new-year-date">---- -- --</small>
|
||||
</div>
|
||||
<div class="schedule-bars">
|
||||
<div class="schedule-row">
|
||||
<span>本年</span>
|
||||
<progress id="year-progress" max="100" value="0"></progress>
|
||||
<em id="year-left">--天</em>
|
||||
</div>
|
||||
<div class="schedule-row">
|
||||
<span>本月</span>
|
||||
<progress id="month-progress" max="100" value="0"></progress>
|
||||
<em id="month-left">--天</em>
|
||||
</div>
|
||||
<div class="schedule-row">
|
||||
<span>本周</span>
|
||||
<progress id="week-progress" max="100" value="0"></progress>
|
||||
<em id="week-left">--天</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sidebar-card recent-card">
|
||||
<h2>最新文章</h2>
|
||||
<div class="sidebar-posts">
|
||||
{recentPosts.map((post) => (
|
||||
<a class="sidebar-post" href={post.href}>
|
||||
{post.cover ? (
|
||||
<img src={post.cover} alt="" loading="lazy" />
|
||||
) : (
|
||||
<span class="post-thumb-fallback" aria-hidden="true"></span>
|
||||
)}
|
||||
<span>
|
||||
<strong>{post.title}</strong>
|
||||
<time datetime={post.date.toISOString()}>{post.dateText}</time>
|
||||
</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||
const pad = (value) => String(value).padStart(2, '0');
|
||||
const percent = (used, total) => Math.min(100, Math.max(0, (used / total) * 100));
|
||||
const setText = (id, value) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = value;
|
||||
};
|
||||
|
||||
function dayOfYear(date) {
|
||||
const start = new Date(date.getFullYear(), 0, 1);
|
||||
return Math.floor((date - start) / 86400000) + 1;
|
||||
}
|
||||
|
||||
function weekOfYear(date) {
|
||||
const firstDay = new Date(date.getFullYear(), 0, 1);
|
||||
const pastDays = Math.floor((date - firstDay) / 86400000);
|
||||
return Math.ceil((pastDays + firstDay.getDay() + 1) / 7);
|
||||
}
|
||||
|
||||
function renderCalendar(now) {
|
||||
setText('calendar-week', `第${weekOfYear(now)}周 ${dayNames[now.getDay()]}`);
|
||||
setText('calendar-date', pad(now.getDate()));
|
||||
setText('calendar-solar', `${now.getFullYear()}年${now.getMonth() + 1}月 第${dayOfYear(now)}天`);
|
||||
setText('calendar-lunar', '万千风景,五历如一');
|
||||
|
||||
const grid = document.getElementById('calendar-grid');
|
||||
if (!grid) return;
|
||||
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth();
|
||||
const first = new Date(year, month, 1).getDay();
|
||||
const days = new Date(year, month + 1, 0).getDate();
|
||||
const previousDays = new Date(year, month, 0).getDate();
|
||||
const cells = [];
|
||||
|
||||
for (let i = 0; i < 42; i += 1) {
|
||||
const dayNumber = i - first + 1;
|
||||
const isCurrent = dayNumber >= 1 && dayNumber <= days;
|
||||
const displayDay = isCurrent
|
||||
? dayNumber
|
||||
: dayNumber < 1
|
||||
? previousDays + dayNumber
|
||||
: dayNumber - days;
|
||||
const isToday = isCurrent && displayDay === now.getDate();
|
||||
cells.push(`<span class="${isCurrent ? '' : 'muted'} ${isToday ? 'today' : ''}">${displayDay}</span>`);
|
||||
}
|
||||
|
||||
grid.innerHTML = cells.join('');
|
||||
}
|
||||
|
||||
function renderSchedule(now) {
|
||||
const year = now.getFullYear();
|
||||
const nextEve = new Date(year + 1, 1, 16);
|
||||
const daysToEve = Math.max(0, Math.ceil((nextEve - now) / 86400000));
|
||||
const yearStart = new Date(year, 0, 1);
|
||||
const yearEnd = new Date(year + 1, 0, 1);
|
||||
const monthStart = new Date(year, now.getMonth(), 1);
|
||||
const monthEnd = new Date(year, now.getMonth() + 1, 1);
|
||||
const weekStart = new Date(year, now.getMonth(), now.getDate() - ((now.getDay() + 6) % 7));
|
||||
const weekEnd = new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 7);
|
||||
|
||||
setText('new-year-days', String(daysToEve));
|
||||
setText('new-year-date', `${nextEve.getFullYear()}-${pad(nextEve.getMonth() + 1)}-${pad(nextEve.getDate())}`);
|
||||
|
||||
const rows = [
|
||||
['year', yearStart, yearEnd],
|
||||
['month', monthStart, monthEnd],
|
||||
['week', weekStart, weekEnd],
|
||||
];
|
||||
|
||||
rows.forEach(([name, start, end]) => {
|
||||
const total = end - start;
|
||||
const used = now - start;
|
||||
const left = Math.max(0, Math.ceil((end - now) / 86400000));
|
||||
const bar = document.getElementById(`${name}-progress`);
|
||||
if (bar) bar.value = percent(used, total);
|
||||
setText(`${name}-left`, `还剩${left}天`);
|
||||
});
|
||||
}
|
||||
|
||||
function initSidebar() {
|
||||
const now = new Date();
|
||||
renderCalendar(now);
|
||||
renderSchedule(now);
|
||||
}
|
||||
|
||||
initSidebar();
|
||||
})();
|
||||
</script>
|
||||
<script is:inline src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
|
||||
<script is:inline src="https://cdn.jsdmirror.com/gh/bishshi/welcomemessage/txmap.js"></script>
|
||||
<script is:inline src="/js/weather.js"></script>
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
}
|
||||
|
||||
const { title, subtitle } = Astro.props;
|
||||
---
|
||||
|
||||
<header class="page-header-card">
|
||||
<p class="page-header-eyebrow">Bi's Blog</p>
|
||||
<h1>{title}</h1>
|
||||
{subtitle && <p class="page-header-subtitle">{subtitle}</p>}
|
||||
</header>
|
||||
@@ -13,6 +13,7 @@ export type BlogPost = MarkdownModule & {
|
||||
tags: string[];
|
||||
categories: string[];
|
||||
summary: string;
|
||||
cover?: string;
|
||||
href: string;
|
||||
};
|
||||
|
||||
@@ -79,6 +80,7 @@ export function getAllPosts(): BlogPost[] {
|
||||
tags: asArray(module.frontmatter.tags),
|
||||
categories: asArray(module.frontmatter.categories),
|
||||
summary: makeSummary(module),
|
||||
cover: typeof module.frontmatter.cover === 'string' ? module.frontmatter.cover : undefined,
|
||||
href: `/posts/${slug}/`,
|
||||
};
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import { getSitePages } from '@/lib/pages';
|
||||
|
||||
export function getStaticPaths() {
|
||||
@@ -14,10 +15,10 @@ const { Content } = page;
|
||||
---
|
||||
|
||||
<BaseLayout title={page.title}>
|
||||
<article class="article">
|
||||
<header class="article-header">
|
||||
<h1>{page.title}</h1>
|
||||
</header>
|
||||
<section class="content-wrap narrow page-with-card">
|
||||
<PageHeaderCard title={page.title} />
|
||||
</section>
|
||||
<article class="article page-article">
|
||||
<div class="prose">
|
||||
<Content />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import { getAllPosts } from '@/lib/posts';
|
||||
|
||||
const posts = getAllPosts();
|
||||
@@ -7,7 +8,7 @@ const posts = getAllPosts();
|
||||
|
||||
<BaseLayout title="归档">
|
||||
<section class="content-wrap narrow">
|
||||
<h1>归档</h1>
|
||||
<PageHeaderCard title="归档" subtitle={`共 ${posts.length} 篇文章`} />
|
||||
<div class="archive-list">
|
||||
{posts.map((post) => (
|
||||
<a href={post.href}>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import PostCard from '@/components/PostCard.astro';
|
||||
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
||||
|
||||
@@ -16,7 +17,7 @@ const posts = getAllPosts().filter((post) => post.categories.includes(category))
|
||||
|
||||
<BaseLayout title={category}>
|
||||
<section class="content-wrap">
|
||||
<h1>{category}</h1>
|
||||
<PageHeaderCard title={category} subtitle={`共 ${posts.length} 篇文章`} />
|
||||
<div class="post-list">
|
||||
{posts.map((post) => <PostCard post={post} />)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
||||
|
||||
const posts = getAllPosts();
|
||||
@@ -8,7 +9,7 @@ const categories = getAllCategories();
|
||||
|
||||
<BaseLayout title="分类">
|
||||
<section class="content-wrap narrow">
|
||||
<h1>分类</h1>
|
||||
<PageHeaderCard title="分类" subtitle={`共 ${categories.length} 个分类`} />
|
||||
<div class="term-grid">
|
||||
{categories.map((category) => (
|
||||
<a href={`/categories/${encodeURIComponent(category)}/`}>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import HomeSidebar from '@/components/HomeSidebar.astro';
|
||||
import PostCard from '@/components/PostCard.astro';
|
||||
import { getAllPosts } from '@/lib/posts';
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/posts';
|
||||
|
||||
const posts = getAllPosts();
|
||||
const tags = getAllTags();
|
||||
const categories = getAllCategories();
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
@@ -14,7 +17,8 @@ const posts = getAllPosts();
|
||||
<p>把折腾、学习和生活片段安静地收在这里。</p>
|
||||
</div>
|
||||
</section>
|
||||
<section class="content-wrap">
|
||||
<section class="content-wrap home-layout">
|
||||
<div class="home-main">
|
||||
<div class="section-heading">
|
||||
<h2>最新文章</h2>
|
||||
<a href="/archives/">查看全部</a>
|
||||
@@ -22,5 +26,7 @@ const posts = getAllPosts();
|
||||
<div class="post-list">
|
||||
{posts.slice(0, 16).map((post) => <PostCard post={post} />)}
|
||||
</div>
|
||||
</div>
|
||||
<HomeSidebar posts={posts} tags={tags} categories={categories} />
|
||||
</section>
|
||||
</BaseLayout>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
import ArticleSidebar from '@/components/ArticleSidebar.astro';
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import { getAllPosts } from '@/lib/posts';
|
||||
|
||||
@@ -11,10 +12,62 @@ export function getStaticPaths() {
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { Content } = post;
|
||||
const allPosts = getAllPosts();
|
||||
|
||||
function slugifyHeading(value: string): string {
|
||||
return value
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/<[^>]+>/g, '')
|
||||
.replace(/[`*_~[\]()]/g, '')
|
||||
.replace(/[^\p{Letter}\p{Number}\s-]/gu, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '');
|
||||
}
|
||||
|
||||
function makeToc(raw: string) {
|
||||
const used = new Map<string, number>();
|
||||
let inFence = false;
|
||||
|
||||
return raw
|
||||
.split(/\r?\n/)
|
||||
.flatMap((line) => {
|
||||
if (/^\s*```/.test(line)) {
|
||||
inFence = !inFence;
|
||||
return [];
|
||||
}
|
||||
|
||||
if (inFence) return [];
|
||||
|
||||
const match = /^(#{1,3})\s+(.+?)\s*#*$/.exec(line);
|
||||
if (!match) return [];
|
||||
|
||||
const text = match[2].replace(/<[^>]+>/g, '').trim();
|
||||
if (!text) return [];
|
||||
|
||||
const baseId = slugifyHeading(text) || 'section';
|
||||
const count = used.get(baseId) ?? 0;
|
||||
used.set(baseId, count + 1);
|
||||
|
||||
return [{
|
||||
depth: match[1].length,
|
||||
text,
|
||||
id: count === 0 ? baseId : `${baseId}-${count}`,
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
const toc = makeToc(post.rawContent?.() ?? '');
|
||||
const relatedPosts = allPosts
|
||||
.filter((item) => item.slug !== post.slug)
|
||||
.filter((item) => item.categories.some((category) => post.categories.includes(category)))
|
||||
.slice(0, 8);
|
||||
---
|
||||
|
||||
<BaseLayout title={post.title} description={post.summary}>
|
||||
<article class="article">
|
||||
<section class="post-layout">
|
||||
<article class="article post-article">
|
||||
<header class="article-header">
|
||||
<time datetime={post.date.toISOString()}>{post.dateText}</time>
|
||||
<h1>{post.title}</h1>
|
||||
@@ -23,8 +76,29 @@ const { Content } = post;
|
||||
{post.tags.map((tag) => <a href={`/tags/${encodeURIComponent(tag)}/`}>#{tag}</a>)}
|
||||
</div>
|
||||
</header>
|
||||
<div class="prose">
|
||||
<div class="prose" data-toc={JSON.stringify(toc)}>
|
||||
<Content />
|
||||
</div>
|
||||
</article>
|
||||
<ArticleSidebar post={post} toc={toc} relatedPosts={relatedPosts} />
|
||||
</section>
|
||||
</BaseLayout>
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const prose = document.querySelector('.prose[data-toc]');
|
||||
if (!prose) return;
|
||||
|
||||
let toc = [];
|
||||
try {
|
||||
toc = JSON.parse(prose.dataset.toc || '[]');
|
||||
} catch {
|
||||
toc = [];
|
||||
}
|
||||
|
||||
prose.querySelectorAll('h1, h2, h3').forEach((heading, index) => {
|
||||
const item = toc[index];
|
||||
if (item?.id && !heading.id) heading.id = item.id;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import PostCard from '@/components/PostCard.astro';
|
||||
import { getAllPosts, getAllTags } from '@/lib/posts';
|
||||
|
||||
@@ -16,7 +17,7 @@ const posts = getAllPosts().filter((post) => post.tags.includes(tag));
|
||||
|
||||
<BaseLayout title={tag}>
|
||||
<section class="content-wrap">
|
||||
<h1>#{tag}</h1>
|
||||
<PageHeaderCard title={`#${tag}`} subtitle={`共 ${posts.length} 篇文章`} />
|
||||
<div class="post-list">
|
||||
{posts.map((post) => <PostCard post={post} />)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||
import { getAllPosts, getAllTags } from '@/lib/posts';
|
||||
|
||||
const posts = getAllPosts();
|
||||
@@ -8,7 +9,7 @@ const tags = getAllTags();
|
||||
|
||||
<BaseLayout title="标签">
|
||||
<section class="content-wrap narrow">
|
||||
<h1>标签</h1>
|
||||
<PageHeaderCard title="标签" subtitle={`共 ${tags.length} 个标签`} />
|
||||
<div class="term-grid">
|
||||
{tags.map((tag) => (
|
||||
<a href={`/tags/${encodeURIComponent(tag)}/`}>
|
||||
|
||||
+620
-17
@@ -8,6 +8,11 @@
|
||||
--accent: #0f766e;
|
||||
--accent-strong: #14532d;
|
||||
--shadow: 0 14px 45px rgba(58, 51, 38, 0.1);
|
||||
--page-gutter: clamp(20px, 4vw, 64px);
|
||||
--wide-width: 1440px;
|
||||
--content-width: 1280px;
|
||||
--article-width: 1080px;
|
||||
--narrow-width: 1000px;
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -33,45 +38,106 @@ a {
|
||||
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
top: 12px;
|
||||
z-index: 10;
|
||||
border-bottom: 1px solid rgba(222, 216, 204, 0.8);
|
||||
background: rgba(255, 253, 248, 0.88);
|
||||
backdrop-filter: blur(14px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: min(1120px, calc(100% - 32px));
|
||||
min-height: 64px;
|
||||
position: relative;
|
||||
width: min(var(--wide-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
min-height: 58px;
|
||||
margin: 0 auto;
|
||||
padding: 0 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.56);
|
||||
border-radius: 999px;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.52), rgba(255, 255, 255, 0.2)),
|
||||
rgba(255, 255, 255, 0.28);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.82),
|
||||
inset 0 -18px 38px rgba(255, 255, 255, 0.16),
|
||||
0 18px 54px rgba(44, 55, 63, 0.18);
|
||||
backdrop-filter: blur(22px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(22px) saturate(180%);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.nav::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.72), transparent 30%),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.42), transparent 38%, rgba(255, 255, 255, 0.22));
|
||||
opacity: 0.74;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nav::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 16px;
|
||||
left: 16px;
|
||||
height: 1px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.brand {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
gap: 6px;
|
||||
color: var(--muted);
|
||||
font-size: 0.94rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 999px;
|
||||
padding: 7px 12px;
|
||||
transition:
|
||||
color 0.2s ease,
|
||||
background-color 0.2s ease,
|
||||
border-color 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-links a:hover,
|
||||
.site-footer a:hover,
|
||||
.section-heading a:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
border-color: rgba(255, 255, 255, 0.62);
|
||||
background: rgba(255, 255, 255, 0.38);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.72),
|
||||
0 8px 18px rgba(15, 118, 110, 0.1);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.hero {
|
||||
width: min(1120px, calc(100% - 32px));
|
||||
width: min(var(--wide-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
min-height: 360px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
@@ -99,12 +165,96 @@ a {
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
width: min(980px, calc(100% - 32px));
|
||||
width: min(var(--content-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
margin: 0 auto 72px;
|
||||
}
|
||||
|
||||
.content-wrap.narrow {
|
||||
width: min(780px, calc(100% - 32px));
|
||||
width: min(var(--narrow-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
}
|
||||
|
||||
.page-header-card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 40px 0 26px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.58);
|
||||
border-radius: 8px;
|
||||
padding: clamp(26px, 5vw, 44px);
|
||||
background:
|
||||
radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.78), transparent 36%),
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.58), rgba(238, 250, 243, 0.36)),
|
||||
rgba(255, 253, 248, 0.72);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.82),
|
||||
0 18px 48px rgba(58, 51, 38, 0.12);
|
||||
backdrop-filter: blur(18px) saturate(165%);
|
||||
-webkit-backdrop-filter: blur(18px) saturate(165%);
|
||||
}
|
||||
|
||||
.page-header-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 18px;
|
||||
left: 18px;
|
||||
height: 1px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.76);
|
||||
}
|
||||
|
||||
.page-header-eyebrow {
|
||||
margin: 0 0 8px;
|
||||
color: var(--accent);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.page-header-card h1,
|
||||
.content-wrap .page-header-card h1 {
|
||||
margin: 0;
|
||||
color: #20242a;
|
||||
font-size: clamp(2rem, 5vw, 3.6rem);
|
||||
line-height: 1.08;
|
||||
}
|
||||
|
||||
.page-header-subtitle {
|
||||
max-width: 620px;
|
||||
margin: 12px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.page-with-card {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.page-article {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.post-layout {
|
||||
width: min(var(--wide-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
margin: 40px auto 84px;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 320px;
|
||||
align-items: start;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.post-layout .article {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.home-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 320px;
|
||||
align-items: start;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.home-main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
@@ -150,6 +300,396 @@ a {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.home-sidebar {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.sticky-sidebar {
|
||||
position: sticky;
|
||||
top: 84px;
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(222, 216, 204, 0.72);
|
||||
border-radius: 8px;
|
||||
padding: 18px;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.72), rgba(242, 251, 237, 0.78)),
|
||||
rgba(255, 253, 248, 0.76);
|
||||
box-shadow: var(--shadow);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.sidebar-card h2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0 0 14px;
|
||||
color: #4d5258;
|
||||
font-size: 1.08rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.sidebar-card h2 em {
|
||||
margin-left: auto;
|
||||
min-width: 28px;
|
||||
border-radius: 999px;
|
||||
padding: 2px 8px;
|
||||
color: #6d9cc2;
|
||||
font-size: 0.78rem;
|
||||
font-style: normal;
|
||||
text-align: center;
|
||||
background: rgba(102, 200, 245, 0.18);
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.profile-avatar {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
margin: 0 auto 14px;
|
||||
border-radius: 999px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 12px 30px rgba(15, 118, 110, 0.18);
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
margin-bottom: 16px;
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
color: #585b5e;
|
||||
font-size: 1.9rem;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.profile-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.profile-stats a {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.profile-stats strong {
|
||||
color: #2f4358;
|
||||
font-size: 1.22rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.profile-stats a:first-child strong,
|
||||
.notice-card strong,
|
||||
.schedule-left span,
|
||||
.calendar-summary span {
|
||||
color: #66c8f5;
|
||||
}
|
||||
|
||||
.follow-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
min-height: 44px;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
background: #3eb8be;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.follow-button:hover {
|
||||
color: #fff;
|
||||
transform: translateY(-1px);
|
||||
background: #279fa5;
|
||||
}
|
||||
|
||||
.github-mark {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.profile-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
margin-top: 16px;
|
||||
color: #3f5368;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.notice-card p {
|
||||
margin: 0.65em 0;
|
||||
color: #596068;
|
||||
line-height: 1.9;
|
||||
}
|
||||
|
||||
.calendar-widget,
|
||||
.schedule-widget {
|
||||
display: grid;
|
||||
grid-template-columns: 0.9fr 1.1fr;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.calendar-summary,
|
||||
.schedule-left {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calendar-summary strong,
|
||||
.schedule-left strong {
|
||||
color: #4b5560;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.calendar-summary span,
|
||||
.schedule-left span {
|
||||
font-size: 2.25rem;
|
||||
line-height: 1.1;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.calendar-summary small,
|
||||
.schedule-left small {
|
||||
color: var(--muted);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
gap: 5px 7px;
|
||||
color: #8aa6be;
|
||||
font-size: 0.78rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calendar-grid span {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 20px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.calendar-grid .muted {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.calendar-grid .today {
|
||||
color: #fff;
|
||||
background: #66c8f5;
|
||||
}
|
||||
|
||||
.schedule-bars {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.schedule-row {
|
||||
display: grid;
|
||||
grid-template-columns: 34px 1fr 64px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--muted);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.schedule-row progress {
|
||||
width: 100%;
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: rgba(102, 200, 245, 0.18);
|
||||
}
|
||||
|
||||
.schedule-row progress::-webkit-progress-bar {
|
||||
background: rgba(102, 200, 245, 0.18);
|
||||
}
|
||||
|
||||
.schedule-row progress::-webkit-progress-value {
|
||||
background: rgba(102, 200, 245, 0.58);
|
||||
}
|
||||
|
||||
.schedule-row progress::-moz-progress-bar {
|
||||
background: rgba(102, 200, 245, 0.58);
|
||||
}
|
||||
|
||||
.schedule-row em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.sidebar-posts {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.sidebar-post {
|
||||
display: grid;
|
||||
grid-template-columns: 70px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-top: 1px dashed rgba(104, 111, 120, 0.28);
|
||||
}
|
||||
|
||||
.sidebar-post:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.sidebar-post img,
|
||||
.post-thumb-fallback {
|
||||
width: 70px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 6px;
|
||||
object-fit: cover;
|
||||
background: linear-gradient(135deg, rgba(62, 184, 190, 0.32), rgba(102, 200, 245, 0.34));
|
||||
}
|
||||
|
||||
.sidebar-post strong {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
color: #4d5258;
|
||||
font-size: 0.94rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.45;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.sidebar-post time {
|
||||
display: block;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.article-sidebar {
|
||||
position: sticky;
|
||||
top: 90px;
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.article-author-card {
|
||||
text-align: center;
|
||||
background:
|
||||
radial-gradient(circle at 50% 0%, rgba(102, 200, 245, 0.32), transparent 42%),
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.58), rgba(214, 238, 255, 0.3)),
|
||||
rgba(255, 253, 248, 0.62);
|
||||
}
|
||||
|
||||
.article-author-card .profile-avatar {
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
}
|
||||
|
||||
.article-author-card .profile-name {
|
||||
margin-bottom: 8px;
|
||||
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
font-size: 1.45rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.article-author-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
color: var(--muted);
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
.article-author-meta a {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.toc-list,
|
||||
.same-category-list {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.toc-list {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.toc-list::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: 5px;
|
||||
border-radius: 999px;
|
||||
background-image: radial-gradient(circle, rgba(102, 200, 245, 0.72) 2px, transparent 2px);
|
||||
background-size: 14px 5px;
|
||||
}
|
||||
|
||||
.toc-list a,
|
||||
.same-category-list a {
|
||||
border-radius: 8px;
|
||||
padding: 9px 11px;
|
||||
color: #50637a;
|
||||
line-height: 1.45;
|
||||
transition:
|
||||
color 0.2s ease,
|
||||
background-color 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.toc-list a:hover,
|
||||
.same-category-list a:hover {
|
||||
color: #1f618d;
|
||||
background: rgba(102, 200, 245, 0.16);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.toc-depth-2 {
|
||||
padding-left: 22px !important;
|
||||
}
|
||||
|
||||
.toc-depth-3 {
|
||||
padding-left: 34px !important;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.same-category-list a {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
border-top: 1px dashed rgba(104, 111, 120, 0.22);
|
||||
}
|
||||
|
||||
.same-category-list a:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.same-category-list strong {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
font-size: 0.94rem;
|
||||
font-weight: 600;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.sidebar-empty {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
time {
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
@@ -172,13 +712,20 @@ time {
|
||||
}
|
||||
|
||||
.article {
|
||||
width: min(820px, calc(100% - 32px));
|
||||
width: min(var(--article-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
margin: 64px auto 84px;
|
||||
border: 1px solid var(--line);
|
||||
border: 1px solid rgba(255, 255, 255, 0.58);
|
||||
border-radius: 8px;
|
||||
padding: clamp(24px, 5vw, 48px);
|
||||
background: rgba(255, 253, 248, 0.93);
|
||||
box-shadow: var(--shadow);
|
||||
background:
|
||||
radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.72), transparent 34%),
|
||||
linear-gradient(145deg, rgba(255, 255, 255, 0.62), rgba(226, 248, 241, 0.35)),
|
||||
rgba(255, 253, 248, 0.68);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.82),
|
||||
0 24px 64px rgba(44, 55, 63, 0.16);
|
||||
backdrop-filter: blur(18px) saturate(165%);
|
||||
-webkit-backdrop-filter: blur(18px) saturate(165%);
|
||||
}
|
||||
|
||||
.article-header {
|
||||
@@ -194,6 +741,7 @@ time {
|
||||
}
|
||||
|
||||
.prose :where(h2, h3, h4) {
|
||||
scroll-margin-top: 110px;
|
||||
margin-top: 2em;
|
||||
line-height: 1.35;
|
||||
}
|
||||
@@ -256,7 +804,7 @@ time {
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
width: min(1120px, calc(100% - 32px));
|
||||
width: min(var(--wide-width), calc(100% - (var(--page-gutter) * 2)));
|
||||
margin: 0 auto;
|
||||
padding: 32px 0 44px;
|
||||
display: flex;
|
||||
@@ -265,25 +813,80 @@ time {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.post-list {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.post-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.article-sidebar {
|
||||
position: static;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.toc-card {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.home-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.home-sidebar {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sticky-sidebar {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
:root {
|
||||
--page-gutter: 16px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
min-height: auto;
|
||||
padding: 14px 0;
|
||||
padding: 12px 14px;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
gap: 14px;
|
||||
gap: 6px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.hero {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.home-sidebar {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.calendar-widget,
|
||||
.schedule-widget {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.article-sidebar {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.archive-list a {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 2px;
|
||||
|
||||
Reference in New Issue
Block a user