feat(5f): reader 模式+版式基底+首屏 tagline+图库质感(T4/T7/T8)

- T4 reader:html.reader 单 class(去装饰非去内容:隐辉光/图标
  钮/pv 行,ICP 合规底线永留;正文字号+1px 行宽 56ch;入场动效
  关);命令面板 reader 命令+r 键+localStorage;ThemeScript 预绘
  防闪
- T7 基底:--flow-* 五流距变量双轨应用;暗色 hairline 降档;
  页面标题 700→600(裁定 #6 减字重不减号);focus-visible ring
  统一;列表行距 +2px;--paper/--radius-img/--ease-out 入库
- T8:首页 IdCard slot 落 tagline「写作者 · 读者 · 快门按压者,
  拥抱开源。」;图库暗色 4% 轻衬底+圆角统一(裁定 #4 双模式分判)

验证: E2E 33/33;reader r 键触发+辉光 none+刷新保持实测;流距
      computed 0.6em 实算;tagline 渲染实测

Spec: 2026-10-26_blog-5f

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-01 09:09:27 +08:00
1 parent 22930cfffd
commit 8ec1712135
8 files changed
+80 -3

No files matched your search

+10
View File
@@ -39,6 +39,10 @@ const navItems = [
<div id="cmd-commands" class="cmd-commands">
<p class="cmd-group" role="presentation" id="cmd-h-actions">{t('cmd_group_actions', locale)}</p>
<ul class="cmd-ul" role="group" aria-labelledby="cmd-h-actions">
<li class="cmd-item" role="option" aria-selected="false" data-cmd="reader">
<span class="cmd-label">{t('cmd_reader', locale)}</span>
<span class="cmd-kbd" aria-hidden="true">r</span>
</li>
<li class="cmd-item" role="option" aria-selected="false" data-cmd="theme">
<span class="cmd-label">{t('cmd_toggle_theme', locale)}</span>
<span class="cmd-kbd" aria-hidden="true">t</span>
@@ -134,6 +138,12 @@ const navItems = [
}
switch (item.dataset.cmd) {
// 复用 Header 主题钮的现成切换(同一 localStorage key),不另起第二套实现
case 'reader': {
const root = document.documentElement;
root.classList.toggle('reader');
localStorage.setItem('reader', root.classList.contains('reader') ? '1' : '0');
break;
}
case 'theme': {
const btn = document.querySelector('[data-theme-toggle]') as HTMLElement | null;
if (btn) {
+3 -1
View File
@@ -13,5 +13,7 @@
? saved
: (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.dataset.theme = theme;
})();
})();
// reader 模式预绘(5f T4):与主题同点位读取,避免可交互前闪装饰
if (localStorage.getItem('reader') === '1') document.documentElement.classList.add('reader');
</script>
+7
View File
@@ -65,6 +65,13 @@ const routes: Record<string, string> = {
if (inField() || e.metaKey || e.ctrlKey || e.altKey) return;
if (e.key === 't') { toggleTheme(); return; }
if (e.key === 'r') {
// reader 纯文本模式(5f T4):与命令面板/持久化同源
const root = document.documentElement;
root.classList.toggle('reader');
localStorage.setItem('reader', root.classList.contains('reader') ? '1' : '0');
return;
}
if (e.key === '?') {
(document.getElementById('kbd-help') as HTMLDialogElement | null)?.showModal();
return;
+9
View File
@@ -429,3 +429,12 @@ const first = cards[0];
.lb-meta { order: 3; flex-basis: 100%; }
}
</style>
<style>
/* 5f T8(视觉裁定 §6-4):亮色直贴不动;暗色 4% 轻衬底救夜景融底;衬底圆角≤照片防框中框 */
:global([data-theme='dark']) .stage {
background: rgba(255, 255, 255, 0.04);
border-radius: 6px;
}
.shot img, .thumb img { border-radius: var(--radius-img); }
</style>
+1
View File
@@ -10,6 +10,7 @@ const dict = {
nav_posts: { zh: '文章', en: 'Posts' },
nav_gallery: { zh: '图库', en: 'Gallery' },
nav_about: { zh: '关于', en: 'About' },
cmd_reader: { zh: '阅读模式(纯文本)', en: 'Reader mode (plain text)' },
nav_opensource: { zh: '开源', en: 'Projects' }, // en 用短词:390-430px 尾部主题钮免内滚(用户拍板)
nav_books: { zh: '书架', en: 'Books' },
kbd_gs_books: { zh: '书架', en: 'Books' },
+8 -1
View File
@@ -19,7 +19,8 @@ const heartbeat = await fetchHeartbeat();
<BaseLayout title="wait4x">
<IdCard>
<div class="socials">
<p class="tagline">写作者 · 读者 · 快门按压者,拥抱开源。</p>
<div class="socials">
<a
class="tap social"
href="https://github.com/wait4xx"
@@ -110,6 +111,12 @@ const heartbeat = await fetchHeartbeat();
</BaseLayout>
<style>
.tagline {
font-size: 14px;
color: var(--ink-3);
margin-top: 4px;
letter-spacing: 0.01em;
}
.heartbeat {
font-family: var(--font-mono);
font-size: 12.5px;
+26
View File
@@ -219,3 +219,29 @@ hr { border: none; border-top: 1px solid var(--line); margin-block: var(--space-
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 备案链接永不隐藏(合规底线);分隔点号随之保留必要最小集 */
+16 -1
View File
@@ -27,6 +27,20 @@
/* ---- 书评情绪色(frontmatter mood 覆盖,此处为缺省五档) ---- */
--mood: var(--ink-3);
/* ===== Phase 5f 版式基底(T7,08 文档 K/L 卡 + 视觉裁定) ===== */
/* 正文流距(rauno 式节奏:标题前后距变量化,双轨共用) */
--flow-p: 0.9em;
--flow-h2-pre: 1.8em;
--flow-h2-post: 0.6em;
--flow-h3-pre: 1.5em;
--flow-h3-post: 0.45em;
/* 纸面板(Q 卡/T6 书评轨:亮米灰/暗暖棕——视觉裁定 §6-2 夜灯感已验) */
--paper: #f4f4f2;
/* 图片圆角统一(N 卡:现 8/8/8/10 混用) */
--radius-img: 10px;
/* 微交互曲线统一(O 卡:rauno 全站唯一曲线) */
--ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
--mood-1: #b45309; /* 琥珀 */
--mood-2: #0f766e; /* 松绿 */
--mood-3: #7c3aed; /* 紫晶 */
@@ -89,8 +103,9 @@
--ink-1: #f5f5f7;
--ink-2: #c9ccd4;
--ink-3: #8b8f98;
--paper: #201d18; /* 暖棕夜灯(Q 卡视觉裁定) */
--ink-4: #5c6066;
--line: #2c313a;
--line: #262b33; /* 5f 降一档:暗色切分感偏强(裁定 #7) */
--accent: #8ea2ff;
--accent-soft: rgba(142, 162, 255, 0.18);