fix(visual): 修视觉终审的折行/豆腐块与灰阶纪律违规

视觉终审(glm-5.3-flash:max)判 BLOCK,逐条修完并复测。

P1 阻断:
- 瞬间页日期折成两行(`2026-` / `04-29`):日期列复用 var(--space-5)=40px,
  而 10 字符 mono 日期需 ≈75px 且缺 nowrap。抽 --tl-rail(5.4rem) 统一驱动
  轨道宽度与两处偏移,加 nowrap;实测日期单行(高度 20px)且圆点与卡片对齐

P2 交付可见破形:
- 关于页「关于我」行首 emoji 在无彩色 emoji 字体的环境渲染成黑方块:
  正文行首 emoji 全部去掉(改纯文字段落),并给 --font-serif/--font-sans
  链尾补 Apple/Segoe/Noto emoji 回退——用户内容里的 emoji(瞬间、书评)
  同样不再落豆腐块

移动端导航两字折行(开/源、文/章):
- ≤450px 的 overflow-x 内滚从未生效:flex 子项默认可压缩,中文词被压到就地
  折行。给 nav ul > li 加 flex:none + .nav-link nowrap;实测 360/390/430
  三档全部单行(Range.getClientRects 计数逐项验证)

灰阶纪律:
- 项目墙原来按 GitHub linguist 给每个仓染语言色点,开源页铺 15 个仓 = 15 种
  彩色,破「外壳灰阶、彩色只作正文强调」红线 → 统一改灰阶点,语言靠文字承载
- 语言占比并列(Python/TypeScript 各 36%)只有第一名着色,读起来像谁领先 →
  判定改为「百分比等于最大值者一并着色」

版式与文案细节:
- prose 标题到正文比 tracks 多一档(16+16=32 vs 16)→ .sec-title + .prose-body
  margin-top: 0
- 开源页 bio 破折号贴链接(`blog—— Astro`)→ 破折号前补空格
- 页脚 built from<hash> 缺空格(Astro 吃掉换行处空白)→ 显式 {' '}
- 新增一条真实瞬间(含青色楷体富文本)替代只有占位串的样本,让评论区与标签行
  的间距可在真实数据下验收

验证: 构建 51 页 exit 0;content-lint 51 页 0/0/0;E2E **46/46 PASS**;
      390px 四页 scrollWidth == innerWidth(无横向滚动);
      导航 360/390/430 全部单行;日期单行;config-check 全过

Spec: 2026-11-02_blog-5h-content-social (视觉修复)

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-02 20:56:00 +08:00
1 parent 0b0307b12f
commit d4fe273812
10 files changed
+56 -23

No files matched your search

+4
View File
@@ -154,6 +154,10 @@ const switchLabel = curLocale === 'zh' ? 'EN' : '中';
阈值 350→450(E 车道 6 项后 en 词长实测:360-430px 页溢 42-51px;zh 无感知) */
@media (max-width: 450px) {
nav ul { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
/* 视觉终审 P1:flex 子项默认可压缩,中文词被压到就地折成两行(开/源),
overflow-x 永远不触发。钉死不许压缩 + 不许换行,内滚才真正接管 */
nav ul > li { flex: none; }
.nav-link { white-space: nowrap; }
nav { min-width: 0; }
.header-inner { flex-wrap: nowrap; }
/* 中段再收一档地板(en 五词在 360-430 差 55-61px):字号 11px 下限仍可读,
+3
View File
@@ -27,6 +27,9 @@ const { block } = Astro.props;
margin-top: var(--space-3);
}
.prose-body.full { max-width: none; }
/* 标题下正文不再叠一档 margin:同级标题到内容统一 16px(tracks 块实测 16px,
prose 原来 16+16=32,两块相邻时节奏不齐——视觉终审) */
.sec-title + .prose-body { margin-top: 0; }
.prose-body :global(p) { margin-block: 0 var(--space-2); }
.prose-body :global(ul) {
margin: var(--space-1) 0 var(--space-2);
+1 -1
View File
@@ -7,7 +7,7 @@ const commitUrl = `https://git.wait4x.online/wait4x/blog/commit/${sha}`;
---
<p class="build-info">
built from
built from{' '}
{short === 'dev' ? <span>dev</span> : <a href={commitUrl} class="link mono-link">{short}</a>}
· {new Date(date).toISOString().slice(0, 16).replace('T', ' ')}Z · Astro
</p>
+5 -2
View File
@@ -45,6 +45,9 @@ try {
console.warn('[profile] 仓库数据不可用,语言占比与星标汇总已隐藏');
}
// 并列判定用百分比最大值(四舍五入后并列很常见:Python/TS 各 36%):
// 只给第一根上强调色会让并列者显得"落后",故并列者一并着色
const maxPct = langs.reduce((m, l) => Math.max(m, l.pct), 0);
const stats = await githubUserStats();
const L = {
zh: { followers: '关注者', repos: '公开仓库', stars: '总星标', langs: '语言占比' },
@@ -108,8 +111,8 @@ const L = {
<div class="pf-langs">
<p class="pf-langs-title mono">{L.langs}</p>
<ul>
{langs.map((l, i) => (
<li class:list={['pf-lang', { top: i === 0 }]}>
{langs.map((l) => (
<li class:list={['pf-lang', { top: l.pct === maxPct }]}>
<span class="pf-lang-name mono">{l.name}</span>
<span class="pf-bar" aria-hidden="true">
<span class="pf-bar-fill" style={`width:${Math.max(l.pct, 2)}%`} />
+12 -7
View File
@@ -23,11 +23,9 @@ interface Props {
}
const { limit = 6, locale = 'zh', pinned, options } = Astro.props;
const title = t('open_source_projects', locale);
const LANG_COLORS: Record<string, string> = {
Astro: '#ff5a03', TypeScript: '#3178c6', JavaScript: '#f1e05a',
Python: '#3572a5', Go: '#00add8', Rust: '#dea584', Shell: '#89e051',
HTML: '#e34c26', CSS: '#563d7c', Dockerfile: '#384d54',
};
// 2026-11-02 视觉终审:原先按 GitHub linguist 给每个仓染语言色点,开源页一次铺
// 15+ 个仓 = 15 种彩色,破「外壳灰阶、彩色只作正文强调(≤3 处/页)」红线。
// 改为统一灰阶点:语言信息靠文字承载,颜色不再做无意义的编码。
let projects: RepoCard[] = [];
try {
@@ -50,7 +48,7 @@ try {
<span class="repo-meta">
{p.language && (
<span class="lang">
<span class="dot" style={`background:${LANG_COLORS[p.language] ?? '#8b8f98'}`} />
<span class="dot" />
{p.language}
</span>
)}
@@ -87,5 +85,12 @@ try {
.repo-desc { font-size: 13px; color: var(--ink-3); }
.repo-meta { display: flex; gap: var(--space-3); font-size: 12px; color: var(--ink-3); margin-top: 4px; }
.lang { display: inline-flex; align-items: center; gap: 4px; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.dot {
width: 7px;
height: 7px;
border-radius: 50%;
display: inline-block;
background: var(--ink-4);
flex: none;
}
</style>
+7 -3
View File
@@ -165,8 +165,11 @@ const iso = (d: Date) => d.toISOString();
}
/* 时间线骨架:左 mono 日期 + 竖线 + --accent 节点 + 右侧内容卡 */
.tl-item {
/* 日期轨宽度集中一处:10 字符 mono 日期(2026-04-29)在 12.5px 下约 75px,
原来复用 var(--space-5)=40px 导致在「-」处折成两行(视觉终审 P1) */
--tl-rail: 5.4rem;
position: relative;
margin: 0 0 var(--space-4) calc(var(--space-5) + var(--space-4));
margin: 0 0 var(--space-4) calc(var(--tl-rail) + var(--space-4));
padding-left: var(--space-4);
border-left: 1px solid var(--line);
}
@@ -184,9 +187,10 @@ const iso = (d: Date) => d.toISOString();
}
.tl-date {
position: absolute;
left: calc(-1 * (var(--space-5) + var(--space-4)));
left: calc(-1 * (var(--tl-rail) + var(--space-4)));
top: 4px;
width: var(--space-5);
width: var(--tl-rail);
white-space: nowrap;
text-align: right;
font-family: var(--font-mono);
font-size: 12.5px;