/* ============================================================ 全局样式 —— 建立在 tokens.css 之上 约束:零运行时框架;动效全部包 prefers-reduced-motion ============================================================ */ @import "./tokens.css"; /* ---------- 轻量 reset ---------- */ *, *::before, *::after { box-sizing: border-box; } * { margin: 0; } html { -webkit-text-size-adjust: 100%; } body { font-family: var(--font-sans); font-size: 16px; line-height: 1.6; color: var(--ink-2); background: var(--bg); } img, svg, video { display: block; max-width: 100%; height: auto; } input, button, textarea, select { font: inherit; color: inherit; } /* 键盘焦点可见但克制 */ :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } /* 跳过导航(无障碍动线) */ .skip-link { position: absolute; left: -9999px; top: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg); z-index: 100; } .skip-link:focus { left: var(--space-2); } /* ---------- 链接(全站唯一强调色纪律) ---------- */ a { color: inherit; text-decoration: none; } .link, .prose a { color: var(--accent); text-decoration: underline; text-decoration-color: color-mix(in oklab, var(--accent) 40%, transparent); text-underline-offset: 0.2em; transition: text-decoration-color var(--dur) var(--ease), color var(--dur) var(--ease); } .link:hover, .prose a:hover { text-decoration-color: var(--accent); } /* ---------- 版心 ---------- */ .container { max-width: var(--measure); margin-inline: auto; padding-inline: var(--space-3); } .container-wide { max-width: calc(var(--measure) + 200px); margin-inline: auto; padding-inline: var(--space-3); } /* ============================================================ 正文分轨(丙路线核心:书评纸墨 × 技术灰阶) ============================================================ */ /* ---- 书评轨:纸面板 + 衬线 + 20/1.75 ---- */ .prose-reading { font-family: var(--font-serif); font-size: var(--prose-size-reading); line-height: var(--leading-reading); color: var(--paper-ink); background: var(--paper); max-width: var(--measure); padding: var(--space-5) var(--space-4); border-block: 1px solid var(--paper-line); overflow-wrap: break-word; } .prose-reading p + p { margin-top: 0.9em; } /* 段间距制,无首行缩进 */ .prose-reading h2, .prose-reading h3 { line-height: var(--leading-heading); text-wrap: balance; } .prose-reading h2 { font-size: var(--text-h2); margin-top: 1.8em; } .prose-reading h3 { font-size: var(--text-h3); margin-top: 1.5em; } /* ---- 技术轨:无衬线 + 19/1.7 ---- */ .prose-tech { font-family: var(--font-sans); font-size: var(--prose-size-tech); line-height: var(--leading-tech); color: var(--ink-2); max-width: var(--measure); overflow-wrap: break-word; /* 移动端审计 M1:裸长 URL 曾撑破 88px(只给了书评轨) */ } .prose-tech p + p { margin-top: 0.9em; } .prose-tech h2 { font-size: var(--text-h2); margin-top: 1.8em; line-height: var(--leading-heading); text-wrap: balance; } .prose-tech h3 { font-size: var(--text-h3); margin-top: 1.5em; line-height: var(--leading-heading); } /* ---------- 引文组件(报告 §3:A 墨线长书摘 / D 金句) ---------- */ /* 裸 blockquote(markdown 原生输出无类名)默认即模式 A;显式类可覆盖 */ .prose-reading blockquote, blockquote.quote-block { border-left: 1px solid var(--paper-line); border-left-width: 2px; padding-left: 1.35em; margin-block: 1.2em; color: color-mix(in oklab, var(--paper-ink) 72%, transparent); font-size: 1em; font-style: normal; /* 反例修正:higan 整段加粗弃用 */ font-weight: 400; } .quote-cite { display: block; margin-top: 0.6em; font-size: 0.875rem; font-family: var(--font-sans); color: var(--ink-3); } /* 模式 D:金句(62px 巨型引号水印) */ .pull-quote { font-family: var(--font-kai); position: relative; margin-block: 1.6em; padding-left: 2.2em; font-size: 0.96em; } .pull-quote::before { content: "\201C"; position: absolute; left: 0; top: -0.12em; font-family: Georgia, serif; font-size: 62px; line-height: 1; opacity: 0.18; color: var(--mood); } /* ---------- 代码(终端风,亮暗同底) ---------- */ code, kbd, samp { font-family: var(--font-mono); } :not(pre) > code { font-size: 0.875em; background: var(--bg-soft); padding: 0.15em 0.4em; border-radius: 4px; border: 1px solid var(--line); } pre { background: var(--code-bg); color: var(--code-ink); font-size: 16px; line-height: 1.6; padding: var(--space-3) var(--space-4); border-radius: 8px; overflow-x: auto; /* 禁 break-all:正文横向滚动绝不发生 */ tab-size: 2; } pre code { background: none; border: none; padding: 0; font-size: inherit; } /* 终端窗点缀(圆点由组件层加,此处只管字色纪律) */ .term-dots { display: flex; gap: 6px; margin-bottom: var(--space-2); } .term-dots span { width: 10px; height: 10px; border-radius: 50%; background: #30363d; } /* ---------- 正文媒体(图/视频/音频,Phase 5 媒体支持) ---------- */ /* 图片:markdown 相对路径经 Astro 图片服务优化;版心内圆角限宽 */ .prose-reading img, .prose-tech img { border-radius: 10px; margin-block: 1.2em; max-width: 100%; height: auto; } /* 图注:**显式类驱动**(`

说明

`)。此前按 `p > em:only-child` 自动命中, 把正文里任何独占成段的斜体都变成块级居中——用户实测的排版 bug(斜体单独一行并居中)由此而来。 */ .prose-reading p.fig-cap, .prose-tech p.fig-cap, .prose-reading p.fig-cap em, .prose-tech p.fig-cap em { display: block; text-align: center; font-size: 0.85em; font-family: var(--font-sans); color: var(--ink-3); margin-top: -0.6em; margin-bottom: 1.2em; font-style: normal; } /* 行内斜体基线:不换行、不居中(正常强调语义) */ .prose-reading em, .prose-tech em, .prose-reading i, .prose-tech i { display: inline; font-style: italic; } /* ── 受限排版类(文章内通过 使用;rehype 白名单只放行这些类名) ── 颜色一律走 tokens,亮暗双态都可读;禁任意 hex/内联样式(保持灰阶骨架)。 */ .prose-reading .ink-1, .prose-tech .ink-1 { color: var(--ink-1); } .prose-reading .ink-2, .prose-tech .ink-2 { color: var(--ink-2); } .prose-reading .ink-3, .prose-tech .ink-3 { color: var(--ink-3); } .prose-reading .ink-muted, .prose-tech .ink-muted { color: var(--ink-4); } .prose-reading .ink-accent, .prose-tech .ink-accent { color: var(--accent); } .prose-reading .ink-accent-soft, .prose-tech .ink-accent-soft { color: var(--accent-soft-text); } .prose-reading .ink-warm, .prose-tech .ink-warm { color: var(--ink-warm); } .prose-reading .ink-cool, .prose-tech .ink-cool { color: var(--ink-cool); } .prose-reading .ink-faint, .prose-tech .ink-faint { color: var(--ink-faint); } /* 语义色板:彩色只作用于正文强调(站点外壳保持灰阶)。 每色相两档:标准 / soft(阈值内最淡);亮暗各取独立值,均实测 ≥4.5:1。 */ .prose-reading .c-blue, .prose-tech .c-blue { color: var(--c-blue); } .prose-reading .c-blue-soft, .prose-tech .c-blue-soft { color: var(--c-blue-soft); } .prose-reading .c-teal, .prose-tech .c-teal { color: var(--c-teal); } .prose-reading .c-teal-soft, .prose-tech .c-teal-soft { color: var(--c-teal-soft); } .prose-reading .c-green, .prose-tech .c-green { color: var(--c-green); } .prose-reading .c-green-soft, .prose-tech .c-green-soft { color: var(--c-green-soft); } .prose-reading .c-yellow, .prose-tech .c-yellow { color: var(--c-yellow); } .prose-reading .c-yellow-soft, .prose-tech .c-yellow-soft { color: var(--c-yellow-soft); } .prose-reading .c-orange, .prose-tech .c-orange { color: var(--c-orange); } .prose-reading .c-orange-soft, .prose-tech .c-orange-soft { color: var(--c-orange-soft); } .prose-reading .c-red, .prose-tech .c-red { color: var(--c-red); } .prose-reading .c-red-soft, .prose-tech .c-red-soft { color: var(--c-red-soft); } .prose-reading .c-pink, .prose-tech .c-pink { color: var(--c-pink); } .prose-reading .c-pink-soft, .prose-tech .c-pink-soft { color: var(--c-pink-soft); } .prose-reading .c-purple, .prose-tech .c-purple { color: var(--c-purple); } .prose-reading .c-purple-soft, .prose-tech .c-purple-soft { color: var(--c-purple-soft); } .prose-reading .font-serif, .prose-tech .font-serif { font-family: var(--font-serif); } .prose-reading .font-kai, .prose-tech .font-kai { font-family: var(--font-kai); } .prose-reading .font-sans, .prose-tech .font-sans { font-family: var(--font-sans); } .prose-reading .font-mono, .prose-tech .font-mono { font-family: var(--font-mono); font-size: 0.92em; } /* 系统字族回退类:不下载字体,命中访客本机字体——跨设备不保证一致(docs 已注明) */ /* 自托管优先 + 系统兜底(2026-11-02 口径):跨设备一致性由站内 webfont 保证, 系统字族只作最后兜底;font-fangsong 暂无 OFL 自托管包,仍为纯系统回退(docs 已注明)。 */ .prose-reading .font-song, .prose-tech .font-song { font-family: "Noto Serif SC Variable", "Noto Serif SC", "Songti SC", SimSun, serif; } .prose-reading .font-kai-sys, .prose-tech .font-kai-sys { font-family: "LXGW WenKai Screen", "Kaiti SC", STKaiti, KaiTi, serif; } .prose-reading .font-hei-sys, .prose-tech .font-hei-sys { font-family: "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif; } .prose-reading .font-fangsong, .prose-tech .font-fangsong { font-family: FangSong, STFangsong, "FangSong_GB2312", serif; } /* 霞鹜文楷 Light(自托管 @fontsource,OFL-1.1):更轻的金句字重 */ .prose-reading .font-kai-light, .prose-tech .font-kai-light { font-family: 'LXGW WenKai', var(--font-kai); font-weight: 300; } /* 文学常用:首字下沉(书评开篇)与金句块(引文式的独立强调段) */ .prose-reading p.drop-cap::first-letter, .prose-tech p.drop-cap::first-letter { float: left; font-family: var(--font-serif); font-size: 3.1em; line-height: 1; padding-right: 0.08em; margin-top: 0.05em; color: var(--paper-ink); } .prose-reading .quote-line, .prose-tech .quote-line { display: block; font-family: var(--font-kai); color: var(--paper-ink); border-left: 2px solid var(--paper-line); padding-left: 0.9em; margin: 1.4em 0; } /* 视频与音频:原生标签,markdown raw HTML 直书(指南有模板) */ .prose-reading video, .prose-tech video, .prose-reading audio, .prose-tech audio { display: block; width: 100%; margin-block: 1.2em; } .prose-reading video, .prose-tech video { border-radius: 10px; background: #000; max-height: 72dvh; } .prose-reading audio, .prose-tech audio { border-radius: 999px; } /* ---------- 列表/分隔 ---------- */ hr { border: none; border-top: 1px solid var(--line); margin-block: var(--space-4); } /* ---------- 选区(半透明强调,避免刺眼实心) ---------- */ ::selection { background: var(--accent-soft); } /* ---------- 触屏与安全区(§4e:交互组件显式 .tap 类达 44px 目标) ---------- */ .tap { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; } .safe-area { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } /* ---------- 移动端排版降档(≤560px:书评 20→18) ---------- */ @media (max-width: 560px) { :root { --prose-size-reading: 18px; --prose-size-tech: 18px; --text-h1: 24px; } .prose-reading { padding: var(--space-4) var(--space-3); } } /* ---------- 动效总闸(唯一曲线已入 tokens) ---------- */ /* ===== 动效层(Phase 5e):背景辉光 + 入场 + 微交互 ===== */ :root { --mx: 50%; --my: 30%; } .bg-glow { position: fixed; inset: 0; z-index: -1; pointer-events: none; background: radial-gradient(600px circle at var(--mx) var(--my), color-mix(in oklab, var(--ink-1) 4%, transparent), transparent 70%); opacity: 0; transition: opacity 0.6s ease; } @media (pointer: fine) { .bg-glow { opacity: 1; } @media (prefers-reduced-motion: reduce) { .bg-glow { opacity: 0; } } } /* 正文入场:一次性轻上浮(VT 换页内容替换自然重放,克制 12px/0.4s) */ #main > * { animation: rise-in 0.4s ease both; } @keyframes rise-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } } @media (prefers-reduced-motion: reduce) { #main > * { animation: none; } } /* 列表行微交互(桌面悬停语言:ink 系已有变色,补 1px 上浮) */ @media (pointer: fine) { .postlist .row { transition: transform 0.15s ease; } .postlist .row:hover { transform: translateY(-1px); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* ===== Phase 5f T7:流距变量应用(标题前后距/p+p 统一双轨) ===== */ .prose-reading h2, .prose-tech h2 { margin-top: var(--flow-h2-pre); margin-bottom: var(--flow-h2-post); } .prose-reading h3, .prose-tech h3 { margin-top: var(--flow-h3-pre); margin-bottom: var(--flow-h3-post); } .prose-reading p + p, .prose-tech p + p { margin-top: var(--flow-p); } /* 页面标题字重 700→600(视觉裁定 #6:要轻减字重不减号;!important 压组件 scoped 默认) */ h1.page-title { font-weight: 600 !important; } /* focus ring 收尾(O 卡:统一可键盘巡览性) */ a:focus-visible, button:focus-visible, summary:focus-visible { outline: 2px solid var(--ink-3); outline-offset: 2px; border-radius: 4px; } /* 列表行距微增(裁定 #7:行距 +2~4px 优先于删线) */ .postlist .row { padding-block: calc(var(--space-2) + 2px); } /* ===== Phase 5f T4:reader 纯文本模式(08 文档 §4.4 清单,视觉语义=去装饰非去内容) ===== */ html.reader .bg-glow { display: none !important; } html.reader .site-header .nav-actions { display: none; } /* 收图标钮:保品牌+导航词 */ html.reader .site-footer .fine > *:not(a[href*="beian"]):not(.icp-sep) { display: none; } html.reader .atk-pv-line { display: none; } /* 元信息让位正文 */ html.reader .prose-reading, html.reader .prose-tech { font-size: calc(var(--prose-size-reading, 1.05rem) + 0.0625rem); max-width: 56ch; /* 行宽收窄 */ } html.reader #main > * { animation: none; } /* 入场动效关闭 */ /* ICP 备案链接永不隐藏(合规底线);分隔点号随之保留必要最小集 */