99 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: yggdrasil-ui-design-taste
description: |
Yggdrasil 项目的专属 UI 设计规范与组件审美风格指南。
指导 AI 遵循项目最新的“现代化极简”与“卡片化”设计语言:
包含超大圆角2rem / 32px、无感阴影边框box-shadow
毛玻璃浮动导航栏、响应式表格单元格圆角、以及基于组件挂载key-based mount的路由切换动画
避免骨架屏截断动画等反模式。
metadata:
trigger: 编写或修改 CSS、input.css、主前台页面src/pages/、主布局src/components/frontend_layout.rs以及 Markdown 渲染表格等
source: 提炼自项目前台极简设计重构与动画渲染问题修复
---
# Yggdrasil 现代化极简与卡片化 UI 设计规范
本规范定义了 Yggdrasil 项目前台页面的核心视觉特征、设计系统 Token、组件样式标准以及动画机制。修改任何前台 UI、样式及相关组件时必须严格遵守本设计语言避免任何粗糙、不协调的 AI 默认样式。
## 核心设计哲学
1. **去实体边框化**:摒弃粗硬的 1px 实线边框,改用轻盈无感的阴影(如 `box-shadow: 0 0 0 1px var(--color-paper-border)`)或浮动卡片背景。
2. **大呼吸感圆角**:卡片和图片封面圆角统一为 `2rem` (`32px`),以形成圆润饱满的现代视觉张力。
3. **Catppuccin 语义配色**:基于 Catppuccin Latte/Mocha 调色,仅允许最大一个不饱和的强调色 `var(--color-paper-accent)`
4. **纯净流式的响应式排版**:内容区严格采用 max-width 限制,表头字号随视口尺寸 `clamp()` 响应收紧,不使用多余的修饰性元素。
---
## 核心视觉组件规范
### 1. 文章卡片布局Post Card
* **完美对称内边距**:文字区域包裹的 `div` 必须使用统一的 `p-8` (32px) 的内边距。不管有没有封面图片,文字四周的呼吸感应完全对称。
* **卡片封面**:大圆角与外侧卡片齐平,比例固定为 `21:9``4:3`。必须配合 `blur-img` 结构实现渐进式模糊加载。
* **悬浮动态反馈**:当卡片被 Hover 时,封面图进行轻微缓慢的缩放(`.group:hover .post-card-cover-blur img` 使用 `transform: scale(1.05)` 配合 0.3s transition并且卡片文字可以通过 `.post-card-accent` 下划线滑过进行视觉确认。
### 2. 浮动毛玻璃导航栏Navbar
* **悬浮质感**:不设底边线,采用浮动在页面上方的毛玻璃设计。
* **样式类**:包含 `backdrop-blur` 高强度模糊、高透明底色、充盈的内边距,确保背景内容滚过时若隐若现,增加层次感。
### 3. 极简现代表格Markdown Table
Markdown 渲染出来的表格默认很难看,本项目使用专门优化的 CSS 类。编写/修改表格样式或渲染逻辑时需遵循:
* **结构与对齐**:使用 `border-collapse: separate``border-spacing: 0`。**千万不要**对 `table` 本身使用 `display: block`,否则会破坏表格自带的对齐拉伸逻辑。
* **防背景溢出圆角(关键像素级处理)**:由于 `display: table` 无法被外层 `overflow: hidden` 完美截断,必须给四个角落的单元格设置对应的 `border-radius: 16px`,防止 `th` 的背景溢出大圆角:
- 左上:`table thead th:first-child { border-top-left-radius: 16px; }`
- 右上:`table thead th:last-child { border-top-right-radius: 16px; }`
- 左下:`table tbody tr:last-child td:first-child { border-bottom-left-radius: 16px; }`
- 右下:`table tbody tr:last-child td:last-child { border-bottom-right-radius: 16px; }`
* **无感边框与配色**
- 使用 `box-shadow: 0 0 0 1px var(--color-paper-border)` 代替 `border`
- 表头 (`th`) 使用 `var(--color-paper-code-block)` 软灰色底。
- 行间分割线为 `1px solid var(--color-paper-border)`,最后一行无下分割线。
- 悬浮时整行高亮 `background: var(--color-paper-entry)`
---
## 路由页面过渡动画规范
项目前台采用 WebAssembly 异步获取数据结构,页面切换时有骨架屏挂载。若动画配置不当,会被骨架屏“截断”导致真实页面显示时没有过渡。
### 1. 动画定义
`input.css` 中定义的平滑进场动画类 `.animate-page-enter`
```css
@keyframes page-enter {
0% {
opacity: 0;
transform: translateY(16px) scale(0.995);
}
100% {
opacity: 1;
transform: none;
}
}
.animate-page-enter {
animation: page-enter 400ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
```
### 2. 挂载时机(反模式避坑)
***错误的做法**:在 `frontend_layout.rs` 里的外层 `main``Outlet` 容器加上 `.animate-page-enter`。这会导致数据尚未就绪时骨架屏动画已播完,真实内容闪现出来。
***正确的做法**:直接将 `.animate-page-enter` 加在**每个具体页面组件(如 Home, Archives, Tags, PostDetail, About 等)的真实渲染内容的最外层 `div`(或 `article`)上**。
- 例(`about.rs`
```rust
pub fn About() -> Element {
rsx! {
div { class: "animate-page-enter",
// 页面具体真实内容...
}
}
}
```
这确保当且仅当异步数据加载完毕、真实的 DOM 元素挂载mount到浏览器时页面才独立触发一次平滑的淡入上滑进场。
---
## 违规自检清单
在提交前台 UI 修改前,请务必核对:
- [ ] 卡片内边距是否为统一的 `p-8`,是否有四周不对称的边距?
- [ ] 表格是否被设置成了 `display: block` 导致对齐失效?
- [ ] 表格的四个角落是否用 `border-*-radius` 对齐,是否存在表头直角溢出?
- [ ] 页面动画是否挂载到了具体页面组件的真实内容节点?是否会被骨架屏抢走?
- [ ] 颜色是否全部使用 Catppuccin 语义 token是否引入了过于鲜艳的 AI 渐变?