浅色改为暖纸底 + 纸纹底 + 移动端分类胶囊条

浅色配色(global.css,暗色未动)
- 纯白底在屏幕上偏刺眼、大面积纯色没有视觉落点,整套浅色 token
  压到 L*≈96 并给暖黄彩度(oklch hue 84),墨色换成暖褐而非纯黑
- background #f8f3e9 / surface-subtle #f4eee3 / card #fcf8f0(比页面底亮,
  靠明度差拉层次)/ foreground #221d18 / border #dfd9ce
- 对比度仍留足:正文 15:1、content-secondary 7.5:1、muted-foreground 5.3:1、
  主色链接 4.9:1(AA 要求 4.5:1)
- secondary / sidebar / popover 等原来偏中性的 token 一并转暖,避免冷暖打架

纸纹底
- --paper-noise 用内联 SVG feTurbulence 分形噪声,无需图片文件;
  feColorMatrix saturate=0 去饱和得到带随机 alpha 的灰颗粒,
  因此不需要 mix-blend-mode 就能亮暗通用
- body::before 铺成 position:fixed 整屏颗粒,z-index:1(压在正文上、
  页眉 z-50 / 菜单 z-60 之下),pointer-events:none
- 颗粒浓度:亮色 0.2 / 暗色 0.22。实测亮度标准差 0.05→0.7、0.2→1.9、
  0.3→2.9(0=完全平整),选 2 左右这个「看得出是纸但不觉得脏」的档位
- 顺带让 backdrop-filter 有细节可模糊,此前纯色底上磨砂等于不存在

移动端分类胶囊条(article-list.tsx + sidebar.tsx)
- 移动端侧栏被排在文章列表下面(实测首篇 y=999、侧栏 y=3212),
  分类筛选基本摸不到;现在列表顶部多一条吸附胶囊条
- 复用同一份 categories / activeCategory / handleCategoryChange,不写第二套;
  末尾胶囊在「分类 / 标签」间切换;两端渐隐提示可横向滑;滚动条藏掉
- 把当前项自动滚到中间,只操作这条横向容器,不动页面纵向位置
- sidebar.tsx 的分类/标签块加 hidden lg:block,避免同页出现两份

其他
- 新增 --header-h: 69px(页眉实测高度),移动端菜单面板和吸附胶囊条
  都改用它定位,不再各处硬编码 69/76
- README 补「浅色配色」「纸纹底」「移动端分类胶囊条」三节

验证(headless Chrome 131)
- 390px:胶囊条可见、侧栏两块 display:none;点「思考」→ ?category=思考、
  列表 10→4 条、当前项高亮;切到标签模式列出 35 个标签;无横向溢出
- 1280px:胶囊条隐藏、侧栏分类恢复显示(display:block)
- 亮/暗两套截图正常,书架、文章页均无异常
This commit is contained in:
dsh
2026-09-15 09:37:14 +08:00
parent 9d9f87a013
commit 5532c35064
5 changed files with 244 additions and 27 deletions
+46 -1
View File
@@ -176,8 +176,42 @@ epigraph: 题记 # 可选
代码风格:Astro/TS/TSX 一律 2 空格缩进。组件命名 `PascalCase` 与 `kebab-case` 混用,跟着所在目录的既有风格走即可。项目没有配 formatter,改动尽量贴合周围代码。
### 移动端字号
### 浅色配色:暖纸底,不用亮白
浅色模式**刻意不用纯白**。纯白(L\*≈99)在屏幕上偏刺眼,而且大面积纯色没有视觉落点,看久了发死。整套浅色 token 压到 L\*≈96 并给了一点暖黄彩度(oklch hue 84 ≈ 米黄),墨色也换成暖褐而非纯黑:
| token | 值 | 说明 |
|---|---|---|
| `--background` | `oklch(0.964 0.014 84)` | 页面底 `#f8f3e9` |
| `--surface-subtle` | `oklch(0.952 0.016 84)` | 区块底 `#f4eee3`,比页面底再深一档 |
| `--card` | `oklch(0.98 0.011 84)` | 卡片**比页面底亮**,靠明度差拉出层次 `#fcf8f0` |
| `--foreground` | `oklch(0.235 0.013 68)` | 暖墨 `#221d18`,不是 `#000` |
| `--muted-foreground` | `oklch(0.505 0.012 70)` | 元信息,对比度 5.3:1 |
| `--border` / `--input` | `oklch(0.888 0.016 84)` | |
对比度都还留得很足(正文 15:1、次要文字 7.5:1、主色链接 4.9:1,WCAG AA 要求 4.5:1),所以是「柔和」不是「发灰」。**暗色模式没动。**
调暖 / 调冷就改这几个数字的**色相**(84 = 米黄,70 更偏橙,95 更偏柠檬);想更白就把 L 往上推、彩度往下压。
### 纸纹底
`--paper-noise` 是一段内联 SVG 的 `feTurbulence` 分形噪声,不需要任何图片文件:
```css
--paper-noise: url("data:image/svg+xml,...feTurbulence baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'...");
--paper-noise-opacity: 0.2; /* 暗色 0.22 */
```
由 `body::before` 铺成一层 `position: fixed` 的整屏颗粒(`z-index: 1`、`pointer-events: none`)。它有两个作用:给纯色底一点纸的质感;让 `backdrop-filter` 有细节可模糊 —— 背后是纯色时磨砂等于不存在。
调参:
- **颗粒粗细**看 `baseFrequency`,越大越细(0.7–0.9 是细砂纸,0.3 会变成明显斑块)
- **浓淡**看 `--paper-noise-opacity`。实测颗粒亮度标准差:0.05 → 0.7,0.2 → 1.9,0.3 → 2.9(0 = 完全平整)。2 左右是「看得出是纸、但不觉得脏」的档位
- `stitchTiles='stitch'` 不能删,否则平铺有接缝
- 伪元素用的是**灰阶 alpha 噪点**(`feColorMatrix saturate=0`),所以不需要 `mix-blend-mode`,亮暗通用
### 移动端字号
移动端(<768px)的字号比桌面端小一档,用 Tailwind 的移动优先写法表达 —— 基础值是手机用的,`md:` 前缀是桌面恢复值:
```html
@@ -188,6 +222,17 @@ prose-p:leading-[1.78] md:prose-p:leading-[1.85]
改动集中在 `ArticleContent.astro`(正文、标题、引用、列表)和 `article-list.tsx`(列表区标题)。**不要动 `html` 的根字号**,那会连带缩放所有 rem 间距,容易连锁出问题。
### 移动端分类胶囊条
手机端侧栏(`sidebar.tsx`)被排在文章列表**下面**(实测第一篇文章 y=999、侧栏 y=3212),分类筛选基本摸不到。所以 `article-list.tsx` 在列表顶部额外渲染了一条吸附胶囊条:
- `sticky top-[var(--header-h)]`,跟在固定页眉下面;`-mx-6` 拉通全宽,内部再 `px-6` 对齐正文
- 左端第一个胶囊是当前模式,末尾一个胶囊用来在「分类 / 标签」之间切换
- 两端渐隐提示可以横向滑(靠 `filterEdges` 状态控制显隐),滚动条用 `.no-scrollbar` 藏掉
- **复用同一份** `categories` / `activeCategory` / `handleCategoryChange`,不写第二套逻辑;同时把 `sidebar.tsx` 里那两个块加了 `hidden lg:block`,避免同页出现两份
`--header-h: 69px` 是固定页眉的实测高度,移动端菜单和这条胶囊条都靠它定位。**改页眉内边距或头像尺寸时记得同步改它**,否则吸附位置会错。
### 磨砂玻璃
`global.css` 里有四个 token: