docs(polaris): 同步设计与部署文档现状

对齐深色玻璃样式、响应式布局、数据规模与配置生效范围。
明确仅由 polaris-v* 标签触发发布,并保留历史规格说明。
This commit is contained in:
2026-10-14 16:38:07 +08:00
parent d53dbac88e
commit 86f6eb39b2
6 changed files with 287 additions and 118 deletions
+27 -18
View File
@@ -2,10 +2,12 @@
本目录提供在服务器上以**独立 Compose 项目**运行 Polaris 的最小配置。 本目录提供在服务器上以**独立 Compose 项目**运行 Polaris 的最小配置。
第一阶段流程:CI(Gitea Actions)在校验(lint / typecheck / test / build / standalone 第一阶段流程:仅当推送 `polaris-v*` 标签时才运行 CI(Gitea Actions)整条验证+发布
冒烟)通过后,**自动构建并推送**镜像 `git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>` 工作流——`verify` job 通过校验(lint / typecheck / test / build / standalone 冒烟)后,
到 Gitea registry;宿主机(服务器)首次部署时用**只读**凭据 `docker login`,在 `.env` `publish` job 构建镜像 `git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>`(完整
中固定该镜像的 digest,再 `pull + up` 单服务运行。 commit SHA 作 tag)并**自动推送**到 Gitea registry,从 push 日志解析输出 digest;
分支/路径推送不触发 CI。宿主机(服务器)首次部署时用**只读**凭据 `docker login`,
在 `.env` 中以 digest 固定该镜像,再 `pull + up` 单服务运行。
## 文件说明 ## 文件说明
@@ -16,8 +18,9 @@
设计约束: 设计约束:
- 镜像来源:CI 按 commit sha tag 推送;部署侧用 `image: ${POLARIS_IMAGE:?...}` - 镜像来源:CI 仅在 `polaris-v*` 标签触发的发布中,以完整 commit SHA 为 tag 推送;
必填 + `sha256:<digest>` 固定,杜绝 latest 漂移 部署侧约定在 `.env` 写 `...@sha256:<digest>` 固定镜像,杜绝 latest 漂移;
`compose.yaml` 的 `image: ${POLARIS_IMAGE:?...}` 只校验变量非空,不校验 digest 格式
- 只加入外部网络 `net-public`(与 nginx 同网);**不连** `net-db` - 只加入外部网络 `net-public`(与 nginx 同网);**不连** `net-db`
- 不映射宿主机端口(无 `ports:`),仅通过 nginx 反代访问 - 不映射宿主机端口(无 `ports:`),仅通过 nginx 反代访问
- 无 DB/Redis、无 secrets、无源码/数据卷挂载 - 无 DB/Redis、无 secrets、无源码/数据卷挂载
@@ -41,8 +44,9 @@
## 待现场验证(不要假设,逐项落实) ## 待现场验证(不要假设,逐项落实)
- workflow 中 build/push 步骤的实际行为,以及 **digest 在 CI 运行日志中的输出形式** - workflow 的 build/push 与 digest 输出逻辑已定稿:推送步骤从 push 日志解析
(workflow 正在另行更新,本 lane 不改它;下文涉及处均以实际运行日志为准) `digest: sha256:<64 位十六进制>`,回显「镜像摘要」与手动部署引用,解析失败即 job 失败;
**待现场验证**的是真实 Gitea registry / runner 下 push 输出能否匹配该解析
- registry / runner 实际行为:登录、推送、按 digest 拉取 - registry / runner 实际行为:登录、推送、按 digest 拉取
- 生产 Nginx 行为(见「Nginx 反代」) - 生产 Nginx 行为(见「Nginx 反代」)
- 服务器上 `net-public` 网络名、既有 Compose 项目与目录布局 - 服务器上 `net-public` 网络名、既有 Compose 项目与目录布局
@@ -51,16 +55,19 @@
## 首次发布步骤 ## 首次发布步骤
### 1) 触发并等待 CI,记录镜像与 digest ### 1) 推送标签触发 CI,记录镜像与 digest
```bash ```bash
# 推送到触发分支/路径后,在 Gitea 网页打开 Actions 运行页,等待 job 全绿 # 推送 polaris-v* 标签触发整条工作流(分支/路径推送不触发 CI),例如:
git tag polaris-v0.1.0 && git push origin polaris-v0.1.0
# 在 Gitea 网页打开 Actions 运行页,等待 verify 与 publish job 全绿
``` ```
- 确认校验/构建/冒烟全部通过后,从该次运行日志的**推送步骤**记录: - 确认全部 job 通过后,从该次运行日志的**推送步骤**记录:
- 镜像:`git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>` - 镜像:`git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>`
- digest:`sha256:<digest>`(日志中的具体展示形式**待现场验证**; - digest:推送步骤解析成功时直接回显「镜像摘要:sha256:<digest>」与
若日志未直接给出,用下文「如何确认真实 digest」的方法在部署前核对) `docker pull ...@sha256:<digest>` 手动部署引用;实际输出以日志为准,
若未给出,用下文「如何确认真实 digest」的方法在部署前核对
- 记下对应 commit sha 与 run 编号,便于追溯。 - 记下对应 commit sha 与 run 编号,便于追溯。
### 2) 拷贝示例到服务器,并确认现状与项目路径 ### 2) 拷贝示例到服务器,并确认现状与项目路径
@@ -142,8 +149,9 @@ docker exec <nginx容器名> wget -qO- http://polaris:3000/ >/dev/null && echo o
## 升级与回退 ## 升级与回退
升级(**无零停机承诺**):新 commit 的 CI 运行**全绿**并取得新 digest 后, 升级(**无零停机承诺**):为要发布的新 commit 打新的 `polaris-v*` 标签触发 CI,
把新 digest 写入 `.env` 的 `POLARIS_IMAGE`,旧值保留为注释行,然后: 运行**全绿**并取得新 digest 后,把新 digest 写入 `.env` 的 `POLARIS_IMAGE`,
旧值保留为注释行,然后:
```bash ```bash
docker compose pull polaris && docker compose up -d polaris docker compose pull polaris && docker compose up -d polaris
@@ -162,7 +170,8 @@ docker compose pull polaris && docker compose up -d polaris
按可靠程度排序,最终以「按 digest 拉取成功」为准: 按可靠程度排序,最终以「按 digest 拉取成功」为准:
- **CI 运行日志**:推送步骤的输出通常包含 digest;具体展示形式取决于 workflow 写法, - **CI 运行日志**:workflow 已实现 digest 输出——推送步骤解析 push 日志后回显
「镜像摘要」与 `docker pull` 手动部署引用;真实 registry / runner 下输出是否符合预期
**待现场验证**,以实际日志为准。 **待现场验证**,以实际日志为准。
- **部署前交叉核对**(任一已登录该 registry、装有 buildx 的机器): - **部署前交叉核对**(任一已登录该 registry、装有 buildx 的机器):
`docker buildx imagetools inspect git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>` `docker buildx imagetools inspect git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>`
@@ -173,8 +182,8 @@ docker compose pull polaris && docker compose up -d polaris
- 已拉取过 tag 的机器可查本地记录的远端摘要: - 已拉取过 tag 的机器可查本地记录的远端摘要:
`docker image inspect --format '{{index .RepoDigests 0}}' git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>`。 `docker image inspect --format '{{index .RepoDigests 0}}' git.labmem.icu/<repo-owner>/polaris:<full-commit-sha>`。
- 注意:`.env` 固定的是 manifest(列表)digest;多架构镜像按 digest 拉取时由运行时 - 注意:`.env` 固定的是 manifest(列表)digest;多架构镜像按 digest 拉取时由运行时
选择本平台对应的 manifest。CI 采用单平台还是多平台构建取决于 workflow 选择本平台对应的 manifest。workflow 用单条 `docker build` 构建单平台镜像
(**待现场验证**),构建平台需覆盖服务器架构。 (平台取决于 runner 架构),是否覆盖服务器架构**待现场验证**。
- commit sha tag 正常不应被重复推送;若发现同名 tag 的 digest 变化, - commit sha tag 正常不应被重复推送;若发现同名 tag 的 digest 变化,
先排查 CI 再部署,不要直接沿用旧记录。 先排查 CI 再部署,不要直接沿用旧记录。
@@ -5,6 +5,17 @@
> 状态:用户已批准,可进入实施 > 状态:用户已批准,可进入实施
> >
> 实现分支:`feat/polaris-homepage` > 实现分支:`feat/polaris-homepage`
>
> 历史状态(2026-10-14 补记):本规格是首页阶段的实施依据,正文(含范围、视觉与验收要求)保留 2026-08-26 时点的决策原貌,不作逐行改写;后续开发已推进多项内容,部分条目不再代表现状,见下方「当前实现索引」。
## 当前实现索引(2026-10-14 补记,非原规格内容)
- **视觉**:深色玻璃主题为当前默认外观(无主题切换),设计 tokens 见 `src/app/globals.css`;第 8.1 节的「CSS 低饱和青蓝渐变背景」已由可替换的背景素材层 + 深色遮罩取代,样式由现有 CSS 管理,素材类型/路径/画面不作设计规范。
- **移动端**:第 2.2 节「本次不实现」中的「移动端与平板布局」已完成——≤767px 时侧边栏变为顶部横栏,其余断点适配见两份设计文档的第 0 章;「深色模式」以深色玻璃默认主题的形式落地(无切换开关)。
- **数据**:第 7.1 节的「7 个分类 / 20 条链接 / 8 条 pinned」为当时规模;当前为 8 个分类、51 条链接、6 条 pinned。
- **分类页**:第 2.2 节「正式分类页」与第 3 节「分类导航临时禁用」已被后续工作取代——分类页已在 `/categories/[categoryId]` 实现并启用导航。
- **设置**:`settings.theme`、`settings.background` 仍仅有数据模型与校验,不驱动样式;`settings.search` 与 `settings.sidebar` 已接入。
- 其余章节(目录结构、交互、测试与验收)保留原貌,作为首页阶段的历史验收依据。
## 1. 背景与目标 ## 1. 背景与目标
@@ -4,6 +4,17 @@
> [Polaris 项目说明文档](./Polaris%20项目说明文档.md) —— 项目定位、技术选型、数据结构、开发阶段 > [Polaris 项目说明文档](./Polaris%20项目说明文档.md) —— 项目定位、技术选型、数据结构、开发阶段
> [Polaris 首页设计文档](./Polaris%20首页设计文档.md) —— 首页布局与搜索交互 > [Polaris 首页设计文档](./Polaris%20首页设计文档.md) —— 首页布局与搜索交互
## 0. 当前实现状态(2026-10-14 校对)
本章为现状说明。第 1–23 章保留立项时的历史设计意图;其中浅色玻璃样式、白色大面板容器和数据示例均为历史方案,视觉细节以本章与 `src/app/globals.css` 为准。
- **路由**:`/categories/[categoryId]` 已实现,8 个分类全部静态预生成,未知分类返回 404。
- **布局**:左侧边栏与首页一致(桌面固定悬浮;≤767px 变为顶部横栏,折叠按钮隐藏、导航横向滚动)。主内容区**不再是一整块白色玻璃面板**——面板容器透明,使背景素材保持清晰,玻璃只压在承载文字的元素上:标题与描述带轻边框和文字投影,「全部工具」列表放在一层薄纱视口(rgba(5, 14, 29, 0.18)、圆角 20px)内,工具卡片为深色玻璃。
- **滚动**:桌面端页面高度固定为 `100svh`,工具列表在内部视口滚动(`overscroll-behavior: contain`、可聚焦);视口过矮(`max-height` 断点)或移动端回退为整页滚动。
- **网格现状**:工具网格基础为两列;≥1280px 升为三列,≤999px 降为单列,即 1000–1279px 保持两列。手机顶部横栏与单列已完成;平板/中等窗口的两列已实现,与历史计划(768px–1279px 两列)的差异仅剩 768px–999px 区间当前同为单列。
- **视觉**:深色玻璃主题,tokens 与首页共用(见[首页设计文档](./Polaris%20首页设计文档.md)第 0 章);背景素材可整体替换,背景层显示与遮罩样式由现有 CSS 管理,素材类型/路径/画面不作为设计规范。
- **数据现状**:全站 8 个分类共 51 条链接;本文以「开发工具」为例的数据(15 条)为立项期示意,当前该分类实际 12 条。
## 1. 页面定位 ## 1. 页面定位
Polaris 的分类页用于展示某一类导航资源,例如: Polaris 的分类页用于展示某一类导航资源,例如:
@@ -72,6 +83,8 @@ Figma
其他分类页面复用相同结构,只需要替换分类名称、描述和链接数据。 其他分类页面复用相同结构,只需要替换分类名称、描述和链接数据。
> 2026-10-14 说明:本节与第 12 节的链接清单、数量均为立项期示意数据,不代表当前 `src/data/` 内容。
--- ---
## 3. 与首页的关系 ## 3. 与首页的关系
@@ -198,6 +211,8 @@ background: rgba(99, 102, 241, 0.1);
color: #2563eb; color: #2563eb;
``` ```
> 2026-10-14 实现状态:上方浅蓝紫数值为历史方案。当前选中态为 `--primary-soft`(rgba(147, 190, 255, 0.15))底色 + `--primary-hover` 文字色 + 一圈淡色内描边,圆角 16px 不变。
图标和文字同时高亮。 图标和文字同时高亮。
选中项圆角: 选中项圆角:
@@ -279,6 +294,8 @@ border-radius: 24px;
box-shadow: 0 24px 80px rgba(15, 23, 42, 0.1); box-shadow: 0 24px 80px rgba(15, 23, 42, 0.1);
``` ```
> 2026-10-14 实现状态:上方白色玻璃面板为历史方案。当前面板容器已透明化(见第 0 章):`GlassPanel` 结构保留,但边框、背景、阴影与 backdrop-filter 均被覆盖为透明或无,背景素材直接可见。
容器与页面边距: 容器与页面边距:
```css ```css
@@ -482,7 +499,7 @@ grid-template-columns: repeat(2, minmax(0, 1fr));
} }
``` ```
> 移动端单列布局为后续阶段工作,第一版仅适配桌面端与桌面窗口缩窄场景。 > 历史说明:立项时移动端单列为后续阶段工作。当前状态(2026-10-14):两列为基础布局,≥1280px 升为三列,≤999px(含手机及 768px–999px 窗口)降为单列;历史计划的「768px–1279px 两列」已基本实现,仅 768px–999px 区间为单列。
--- ---
@@ -573,6 +590,8 @@ border-radius: 18px;
box-shadow: 0 14px 40px rgba(15, 23, 42, 0.08); box-shadow: 0 14px 40px rgba(15, 23, 42, 0.08);
``` ```
> 2026-10-14 实现状态:上方浅色样式为历史方案。当前工具卡为深色玻璃 rgba(12, 24, 42, 0.65) + blur(10px),高 82px、圆角 18px,hover 提亮为 rgba(25, 43, 65, 0.84) 并轻微上浮。
Hover 状态: Hover 状态:
```css ```css
@@ -678,6 +697,8 @@ JavaScript 包管理器
## 12. 开发工具页数据示例 ## 12. 开发工具页数据示例
> 2026-10-14 说明:本节数据为立项期示例(15 条),不代表当前 `src/data/`;当前全站 8 类 51 条链接,开发工具分类 12 条。字段结构与现行 `NavLink` 类型一致,仍可作为格式参考。
### 12.1 分类数据 ### 12.1 分类数据
```json ```json
@@ -955,11 +976,15 @@ Hover 时只做轻微反馈:
768px - 1279px:两列 768px - 1279px:两列
``` ```
当前实现(2026-10-14):两列为基础布局,≥1280px 三列、≤999px 单列;历史计划的「768px–1279px 两列」已基本实现,仅其中 768px–999px 区间当前为单列(见第 0 章)。
--- ---
### 14.2 平板与移动端(后续阶段) ### 14.2 平板与移动端
第一版仅适配桌面端。平板与移动端适配为后续阶段工作,届时参考以下方向: > 2026-10-14 实现状态:移动端适配已完成——≤767px 时侧边栏变为**常驻顶部横栏**(Logo + 横向滚动导航,非抽屉),工具卡片单列,短屏与移动端回退整页滚动;平板方向的「边栏宽度略小(220px)」与「工具卡片两列」已实现(两列覆盖 1000px–1279px,768px–999px 区间为单列),下列历史方向中的「抽屉式边栏」未采用。
立项时(仅适配桌面端)的参考方向:
```text ```text
平板端:边栏宽度略小(200px - 220px),工具卡片两列 平板端:边栏宽度略小(200px - 220px),工具卡片两列
@@ -1201,6 +1226,8 @@ type CategoryPageData = {
侧边栏移动端适配 侧边栏移动端适配
``` ```
> 2026-10-14 实现状态:「平板两列」(1000px–1279px 区间,768px–999px 除外)、「移动端一列」与「侧边栏移动端适配」已完成(见第 0 章)。
--- ---
### 第三阶段 ### 第三阶段
@@ -4,7 +4,9 @@
> [Polaris 首页设计文档](./Polaris%20首页设计文档.md) —— 首页布局、搜索交互、视觉规范 > [Polaris 首页设计文档](./Polaris%20首页设计文档.md) —— 首页布局、搜索交互、视觉规范
> [Polaris 分类页设计文档](./Polaris%20分类页设计文档.md) —— 分类页布局、卡片、状态设计 > [Polaris 分类页设计文档](./Polaris%20分类页设计文档.md) —— 分类页布局、卡片、状态设计
> >
> 配套资产:[占位 Logo](../../public/brand/logo.svg)(后续替换)、[Polaris 页面设计图](../assets/Polaris页面设计图.png) > 配套资产:[站点 Logo](../../public/brand/logo.svg)、[Polaris 页面设计图](../assets/Polaris页面设计图.png)
> 本文以当前代码实现为准(2026-10-14 对齐)。早期决策中已被后续实现取代的条目在第 4 节单独标注为「历史」,不再代表现状。
## 1. 项目名称 ## 1. 项目名称
@@ -20,15 +22,15 @@ Polaris 原意为“北极星”,具有方向、导航、定位、指引的含
Polaris 不是后台管理系统,也不是信息密集型 Dashboard。 Polaris 不是后台管理系统,也不是信息密集型 Dashboard。
> 一个具有个人审美、可自定义背景、可快速搜索和访问常用链接的浏览器起始页。 > 一个具有个人审美、可快速搜索和访问常用链接的浏览器起始页。
产品形态是**动态可配置的个人导航站**:第一版可以静态部署,数据写死在本地配置中,但页面具有动态交互(实时时钟、搜索、侧边栏折叠、快捷键等),后续将本地数据源替换为 Go 后端 API,不需要推翻前端整体结构。 产品形态是**个人导航站**:数据内置于本地 JSON 配置、随构建打包,页面具有动态交互(实时时钟、搜索、侧边栏折叠、快捷键等)。页面统一经 service 层取数,不依赖具体数据源形态;后续数据源迁移另行规划。
--- ---
## 3. 项目目标 ## 3. 项目目标
第一阶段目标: 第一阶段目标(已全部实现):
1. 提供一个美观的个人导航首页; 1. 提供一个美观的个人导航首页;
2. 支持快速访问常用链接; 2. 支持快速访问常用链接;
@@ -36,42 +38,49 @@ Polaris 不是后台管理系统,也不是信息密集型 Dashboard。
4. 支持搜索框(Google / Bing / GitHub / 本地); 4. 支持搜索框(Google / Bing / GitHub / 本地);
5. 支持当前时间与日期展示; 5. 支持当前时间与日期展示;
6. 支持左侧边栏折叠(状态持久化); 6. 支持左侧边栏折叠(状态持久化);
7. 支持背景自定义的设计预留; 7. 数据内置于本地 JSON 配置,结构由 Vitest 校验测试兜底;
8. 数据第一版写死在本地 JSON 数据配置中; 8. 页面组件统一经 service 层取数。
9. 代码结构预留未来接入 Go 后端接口的能力。
后续阶段目标: 背景自定义目前停留在数据模型与校验预留(`settings.background`),不驱动样式,见 6.3。
后续阶段目标(未实现):
1. 从 Go 后端 API 获取链接、分类、设置等数据; 1. 从 Go 后端 API 获取链接、分类、设置等数据;
2. 使用数据库持久化配置; 2. 使用数据库持久化配置;
3. 支持后台或隐藏入口管理链接; 3. 支持后台或隐藏入口管理链接;
4. 支持用户自定义背景; 4. 让 `settings.theme` / `settings.background` 真正驱动界面,支持自定义背景与主题切换;
5. 支持主题色、深色模式、导入导出、移动端适配等个性化能力。 5. 支持导入导出等个性化能力。
--- ---
## 4. 已确认的关键决策 ## 4. 已确认的关键决策
以下决策已于 2026-08-21 确认,作为实施基线: 以下决策于 2026-08-21 确认,是当时的实施基线;标注「历史」的条目已被后续实现取代,以当前实现为准:
| # | 决策项 | 结论 | | # | 决策项 | 结论 | 状态 |
| --- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | --- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---- |
| 1 | 技术栈 | 以本文档为准:Next.js + TypeScript + Tailwind CSS + shadcn/ui + lucide-react(早期 README 中 Astro 设想作废) | | 1 | 技术栈 | Next.js + TypeScript + Tailwind CSS + shadcn/ui + lucide-react(早期 README 中 Astro 设想作废) | 现行 |
| 2 | 渲染策略 | 静态导出(`output: 'export'`),时钟/搜索/侧边栏折叠为 client 岛屿 | | 2 | 渲染策略 | 静态导出(`output: 'export'`),时钟/搜索/侧边栏折叠为 client 岛屿 | 历史 |
| 3 | 包管理器 | pnpm | | 3 | 包管理器 | pnpm | 现行 |
| 4 | 项目位置 | `ts/web/nextjs/polaris/` | | 4 | 项目位置 | `ts/web/nextjs/polaris/` | 现行 |
| 5 | Logo | 现有 `logo.svg` 仅作占位,后续替换,不投入设计精力 | | 5 | Logo | `logo.svg` 不投入设计精力 | 现行 |
| 6 | 数据载体 | 本地 JSON 数据文件(`links.json` / `categories.json` / `settings.json`),结构以 Vitest 校验测试兜底 | | 6 | 数据载体 | 本地 JSON 数据文件(`links.json` / `categories.json` / `settings.json`),结构以 Vitest 校验测试兜底 | 现行 |
| 7 | 第一版数据范围 | 「开发工具」15 条 + 首页常用链接 8 条(跨分类条目归入真实分类,见首页设计文档 8.1);设计资源、学习资料、生活服务三个分类展示空状态 | | 7 | 第一版数据范围 | 「开发工具」15 条 + 首页常用链接 8 条;设计资源、学习资料、生活服务三个分类展示空状态 | 历史 |
| 8 | 默认背景 | CSS 低饱和青蓝渐变,不依赖图片资产;`settings.background.type` 预留 `image` | | 8 | 默认背景 | CSS 低饱和青蓝渐变,不依赖图片资产;`settings.background.type` 预留 `image` | 历史 |
| 9 | 深色模式 | 第一版不做;CSS 变量按双主题友好组织,后续以 `[data-theme="dark"]` 覆盖 | | 9 | 深色模式 | 第一版不做;CSS 变量按双主题友好组织,后续以 `[data-theme="dark"]` 覆盖 | 历史 |
| 10 | 移动端 | 第一版不适配,仅桌面端 | | 10 | 移动端 | 第一版不适配,仅桌面端 | 历史 |
| 11 | 快捷键 | Ctrl+K(macOS ⌘K)聚焦搜索框,仅首页生效;提示按平台检测显示 | | 11 | 快捷键 | Ctrl+K(macOS ⌘K)聚焦搜索框,仅首页生效;提示按平台检测显示 | 现行 |
| 12 | 图标方案 | 四级 fallback:自定义图标 → Simple Icons / 本地图标库 → favicon 自动抓取 → 文字占位(见 6.4) | | 12 | 图标方案 | 四级 fallback:自定义图标 → Simple Icons / 本地图标库 → favicon 自动抓取 → 文字占位(见 6.4) | 现行 |
| 13 | 后端数据库 | PostgreSQL(后续阶段);表结构不锁死 PG 特有语法(JSON 存通用 TEXT) | | 13 | 后端数据库 | PostgreSQL(后续阶段);表结构不锁死 PG 特有语法(JSON 存通用 TEXT) | 现行(未来项) |
| 14 | 搜索行为 | 按模式严格分离:选中哪个引擎就只用哪个引擎搜索(回车直跳);仅 Local 模式显示本地结果下拉 | | 14 | 搜索行为 | 按模式严格分离:选中哪个引擎就只用哪个引擎搜索(回车直跳);仅 Local 模式显示本地结果下拉 | 现行 |
2026-10-12 部署阶段将第 2 项由静态导出调整为 standalone 服务端输出;当前实现见第 5.2 节。初期内容仍在构建时从本地 JSON 生成,在线数据管理需后续接入后端。 历史决策的现行实现:
- **#2 渲染策略**:2026-10-12 部署阶段由静态导出改为 standalone 服务端输出,见 5.2。
- **#7 数据范围**:当前为 8 个分类共 51 条链接,全部分类均有内容,首页常用链接 6 条,见 9。
- **#8 默认背景**:当前视觉由 CSS 定义的深色玻璃表面与背景遮罩构成;背景素材为可替换内容,不作为设计规范,见 5.5。`settings.background` 未驱动样式。
- **#9 深色模式**:当前为固定深色玻璃(`color-scheme: dark`),无双主题切换,见 5.5。
- **#10 移动端**:移动端已适配,侧边栏在窄屏转为顶部横栏,见 5.5。
--- ---
@@ -90,14 +99,14 @@ simple-icons
说明: 说明:
1. **Next.js**:适合从静态页面起步,后续接入动态接口; 1. **Next.js**:以本地数据起步,后续接入动态接口;
2. **TypeScript**:适合维护链接、分类、配置等结构化数据; 2. **TypeScript**:适合维护链接、分类、配置等结构化数据;
3. **Tailwind CSS**:适合快速实现玻璃感、响应式、主题变量; 3. **Tailwind CSS**:配合 CSS 变量实现玻璃表面、响应式与视觉 token;
4. **shadcn/ui**:用于基础组件,例如 Button、Input、Dialog、Command; 4. **shadcn/ui**:用于基础组件(Button、DropdownMenu、Tooltip);
5. **lucide-react**:用于侧边栏和操作图标; 5. **lucide-react**:用于侧边栏和操作图标;
6. **simple-icons**:品牌图标库(npm 包,按 slug 引用)。 6. **simple-icons**:品牌图标库(npm 包,按 slug 引用)。
测试:Vitest + Testing Library,重点覆盖纯函数(问候语分段、本地搜索匹配排序、icon 解析、搜索 URL 模板)与核心交互组件。 测试:Vitest + Testing Library,覆盖静态数据结构校验、service 层行为、纯函数(时间格式化与问候语分段、本地搜索匹配排序、icon 候选解析、搜索 URL 模板、偏好读写)与核心交互组件。
### 5.2 渲染策略 ### 5.2 渲染策略
@@ -105,47 +114,46 @@ simple-icons
```ts ```ts
// next.config.ts // next.config.ts
const nextConfig = { output: "standalone" } const nextConfig: NextConfig = {
output: "standalone",
trailingSlash: true,
images: { unoptimized: true },
}
``` ```
- 首页与全部分类页在构建时从本地数据生成(`generateStaticParams`); - 首页与全部分类页为 server 组件,构建时经 service 层从本地数据生成;分类页通过 `generateStaticParams` 预生成,`dynamicParams = false`(未知分类统一 404);
- 时钟、搜索、侧边栏折叠等交互以 client 组件实现; - 时钟、搜索、侧边栏折叠等交互以 client 组件实现;
- 构建产物为 `.next/standalone` 下的最小 Node 服务器(`server.js`),`public` 与 `.next/static` 需按 Next 文档在部署时手动复制; - 构建产物为 `.next/standalone` 下的最小 Node 服务器(`server.js`),`public` 与 `.next/static` 需按 Next 文档在部署时手动复制。
- 后续接 Go 后端时,改造 service 层为 fetch,数据页面改为客户端获取。
### 5.3 数据访问层 ### 5.3 数据访问层(已实现)
**页面组件不直接依赖数据文件,一律通过 service 层获取数据。** **页面组件不直接依赖数据文件,一律通过 service 层获取数据。**
第一版: 当前 service 层已实现,页面与数据文件解耦:
```ts ```ts
import links from "@/data/links.json" // src/services/links.ts
export function getLinks(): NavLink[]
export function getLinksByCategory(categoryId: string): NavLink[] // 按 sort 排序
export function getPinnedLinks(limit = 8): NavLink[] // 按 pinnedSort 排序
export function getLinks(): NavLink[] { // src/services/categories.ts
return links export function getCategories(): Category[]
} export function getCategoryById(id: string): Category | null
// src/services/settings.ts
export function getSettings(): AppSettings // 解析时校验,非法数据直接抛错
``` ```
后续接 Go 后端时,只需要修改 service 层: 所有函数返回数据副本,避免调用方改动模块级数据。`settings.json` 在模块加载时经 `parseSettings` 逐字段校验,类型不符直接抛 `TypeError`,问题在构建/测试阶段即暴露。
```ts 数据源切换的迁移方案另行规划;当前已确保页面组件只依赖 service 接口,不直接依赖数据文件。
export async function getLinks() {
const res = await fetch("/api/links")
if (!res.ok) {
throw new Error("Failed to fetch links")
}
return res.json()
}
```
这样页面组件不用大规模重构。 JSON 缺少编译期类型检查,用 **Vitest 数据校验测试**兜底:`src/data/data.test.ts` 校验 `data/*.json` 满足 `Category[]` / `NavLink[]` / `AppSettings` 结构(必填字段齐全、类型正确、categoryId 存在于分类中、URL 唯一且不含会话参数等),`src/services/services.test.ts` 校验 service 行为。
JSON 缺少编译期类型检查,用 **Vitest 数据校验测试**兜底:校验 `data/*.json` 满足 `Category[]` / `NavLink[]` / `AppSettings` 结构(必填字段齐全、类型正确、categoryId 存在于分类中),字段拼错或漏填在测试阶段即报错。 ### 5.4 后端技术栈(未来阶段)
### 5.4 后端技术栈(后续阶段) 计划由 Go 实现,数据库选用 PostgreSQL(决策 #13,未实施)。
后端由 Go 实现,数据库 PostgreSQL。
候选组合: 候选组合:
@@ -154,6 +162,16 @@ Go + Chi + sqlc —— 结构清晰、SQL 可控(推荐)
Go + Gin + GORM —— 开发更快、上手成本低 Go + Gin + GORM —— 开发更快、上手成本低
``` ```
### 5.5 视觉与布局现状
界面为**固定深色玻璃**风格,不提供主题切换。视觉描述以 `src/app/globals.css` 中的设计 token 与表面为准:
- **全局基调**:`:root` 声明 `color-scheme: dark`,底色为深蓝夜色(`--background: #101a2a`),文字为亮色系(`--text-primary` / `--text-secondary` / `--text-muted`),强调色为浅蓝(`--primary` 系列);
- **背景与遮罩**:背景素材为可替换内容,用户可不定期更换,其具体文件、类型与画面不作为设计规范;背景层的显示方式由 CSS 定义(居中、覆盖、固定附着),其上由 `body::before` 叠加全屏深色渐变遮罩,保证文字对比度;
- **玻璃表面 token**:侧边栏、搜索框、卡片分别使用 `--surface-sidebar` / `--surface-search` / `--surface-card`(及 `--surface-card-hover`)半透明渐变,配 `--border-glass` 描边、`--shadow-*` 阴影与 `backdrop-filter: blur()` 毛玻璃效果;圆角与栏宽由 `--radius-*` / `--sidebar-*` token 控制;
- **桌面布局**:左侧固定玻璃侧边栏(展开 240px / 折叠 72px,`localStorage` 持久化),内容区随侧边栏宽度偏移;首页为纵向排列、水平居中的时钟、搜索框、常用链接;分类页仅文字元素挂玻璃效果,保持背景清晰;分类页网格默认 2 列,≥1280px 时 3 列;
- **移动端适配(≤767px)**:侧边栏转为固定顶部横栏(品牌行 + 横向滚动的分类导航),折叠按钮隐藏,首页与分类页顶部留白相应加大;≤420px 时常用链接降为单列、快捷键提示隐藏;分类页网格在 ≤999px 时降为 1 列;低视口高度时分类页从固定高度回退为整页滚动;全局支持 `prefers-reduced-motion`。
--- ---
## 6. 数据结构 ## 6. 数据结构
@@ -180,6 +198,8 @@ icon: 图标名称(侧边栏,lucide 图标名)
sort: 排序值 sort: 排序值
``` ```
当前数据共 8 个分类:AI 工具、开发工具、设计资源、学习资料、效率工具、娱乐媒体、游戏资料、生活服务。
### 6.2 链接数据 ### 6.2 链接数据
```ts ```ts
@@ -212,6 +232,8 @@ keywords: 本地搜索关键词
sort: 分类内排序值 sort: 分类内排序值
``` ```
当前数据共 51 条链接,各分类均有内容。首页常用链接 6 条(按 `pinnedSort`):GitHub、ChatGPT、Gmail、Notion、YouTube、Bilibili;`getPinnedLinks` 默认上限 8 条,取 `min(pinned 数量, 8)`。
### 6.3 设置数据 ### 6.3 设置数据
```ts ```ts
@@ -234,6 +256,8 @@ sort: 分类内排序值
} }
``` ```
> **注意**:`theme` 与 `background` 目前仅作为数据模型与校验存在(`services/settings.ts` 解析校验,`theme` 当前仅接受 `"light-glass"`),页面未消费这两个字段,**不驱动样式**。界面视觉为固定深色玻璃,见 5.5。页面实际消费的字段是 `siteName`、`search.*` 与 `sidebar.defaultCollapsed`。
### 6.4 统一图标方案 ### 6.4 统一图标方案
链接卡片与搜索结果的图标按以下顺序解析,逐级 fallback: 链接卡片与搜索结果的图标按以下顺序解析,逐级 fallback:
@@ -245,11 +269,11 @@ sort: 分类内排序值
4. 文字占位 以上全部失败 → 标题首字符 + 圆角玻璃底兜底 4. 文字占位 以上全部失败 → 标题首字符 + 圆角玻璃底兜底
``` ```
侧边栏分类导航图标使用 lucide-react(如 `home` / `code` / `palette`),不参与此 fallback 链。 侧边栏分类导航图标使用 lucide-react(如 `home` / `code` / `sparkles`),不参与此 fallback 链。
--- ---
## 7. 未来 Go 后端 API 设计 ## 7. 未来 Go 后端 API 设计(未实现)
后续接入 Go 后端时,推荐 API: 后续接入 Go 后端时,推荐 API:
@@ -284,7 +308,7 @@ PUT /api/settings/background
--- ---
## 8. 数据库表设计草案 ## 8. 数据库表设计草案(未来)
> 草案使用跨数据库通用语法;JSON 以 TEXT 存储。PostgreSQL 下可将 `TEXT`(存 JSON)字段替换为 `JSONB` 以获得索引与查询能力。 > 草案使用跨数据库通用语法;JSON 以 TEXT 存储。PostgreSQL 下可将 `TEXT`(存 JSON)字段替换为 `JSONB` 以获得索引与查询能力。
@@ -339,41 +363,45 @@ CREATE TABLE settings (
## 9. 开发阶段 ## 9. 开发阶段
### 第一阶段:前端静态版(当前阶段) 第一至第三阶段已实现(以当前代码为准),第四、五阶段为未来规划。
### 第一阶段:前端基础版(已完成)
目标:完成首页与分类页基础体验。 目标:完成首页与分类页基础体验。
```text ```text
页面背景(CSS 渐变)与背景遮罩 背景层与遮罩(样式由 CSS 定义,素材可替换)
左侧边栏 + 折叠(localStorage 持久化)+ 导航选中态 左侧边栏 + 折叠(localStorage 持久化)+ 导航选中态
时间 / 日期 / 问候语 时间 / 日期 / 问候语
搜索框(Google / Bing / GitHub / 本地搜索)+ Ctrl+K 快捷键 搜索框(Google / Bing / GitHub / 本地搜索)+ Ctrl+K 快捷键
常用链接(pinned,8 个) 常用链接(pinned,6 个)
分类页路由 + 卡片网格 + 空状态 分类页路由 + 卡片网格 + 空状态组件
桌面端响应式 桌面端响应式
``` ```
数据范围:开发工具 15 个链接 + 首页 8 个常用链接(跨分类条目归入真实分类:ChatGPT → AI 工具,Gmail / Notion → 效率工具,YouTube / Bilibili → 娱乐媒体);设计资源、学习资料、生活服务三个分类展示空状态。 数据范围:8 个分类共 51 条链接,全部分类均有内容;空状态组件保留为数据缺失时的兜底展示。首页常用链接 6 条:GitHub、ChatGPT、Gmail、Notion、YouTube、Bilibili。
### 第二阶段:数据补全与体验完善 ### 第二阶段:数据补全与视觉定型(已完成)
```text ```text
补全其余 6 个分类的链接数据 补全全部分类的链接数据 → 已完成(8 个分类均有内容)
深色玻璃主题 深色玻璃主题 → 已完成(固定深色玻璃,见 5.5)
移动端 / 平板适配 移动端 / 平板适配 → 移动端已完成(顶部横栏,见 5.5);
平板沿用断点降级,未做专项设计
``` ```
### 第三阶段:数据访问层抽象 ### 第三阶段:数据访问层抽象(已完成)
```text ```text
封装 links / categories / settings service 封装 links / categories / settings service → 已实现(src/services/)
统一 TypeScript 类型 统一 TypeScript 类型 → 已实现(src/types/)
统一错误处理与 loading 状态 统一错误处理与 loading 状态 → 数据解析校验失败即抛错;
loading 状态针对远程数据,当前本地数据不涉及
``` ```
此阶段完成后,页面组件不直接关心数据来自本地配置还是 API。 此阶段完成后,页面组件不直接关心数据来自本地配置还是 API——当前已达成:页面只依赖 service 接口。
### 第四阶段:Go 后端 API ### 第四阶段:Go 后端 API(未来)
```text ```text
Go API 服务 Go API 服务
@@ -383,7 +411,7 @@ links / categories / settings 查询接口
Docker 部署预留 Docker 部署预留
``` ```
### 第五阶段:管理能力 ### 第五阶段:管理能力(未来)
```text ```text
新增 / 编辑 / 删除链接 新增 / 编辑 / 删除链接
@@ -398,33 +426,49 @@ Docker 部署预留
## 10. 项目目录结构 ## 10. 项目目录结构
实际目录按 feature-first 组织:
```text ```text
polaris/ polaris/
public/ public/
backgrounds/ # 背景素材(可随时替换,不作为设计基线)
brand/ # 站点 Logo
icons/ # 自定义 SVG 图标(icon: "local:xxx" 引用) icons/ # 自定义 SVG 图标(icon: "local:xxx" 引用)
logo.svg
src/ src/
app/ app/
layout.tsx # 背景层 + 字体 layout.tsx # 根布局、元信息、viewport(深色)
page.tsx # 首页 page.tsx # 首页(server 组件,经 service 取数)
categories/ categories/[categoryId]/page.tsx # 分类页(generateStaticParams,未知分类 404)
[categoryId]/ globals.css # Tailwind + 深色玻璃设计 token 与组件样式(见 5.5)
page.tsx # 分类页(generateStaticParams 生成)
globals.css # Tailwind + CSS 变量(浅色值,深色预留覆盖位) features/ # 按功能域组织
home/ # 首页
components/ # home-content / clock-greeting / search-box /
# search-provider-menu / local-search-results / quick-links
hooks/ # use-clock
lib/ # date-time / search-providers / provider-preference /
# local-search(纯函数 + 测试)
category/ # 分类页
components/ # category-content / category-header /
# category-section-header / tool-grid / tool-card /
# category-empty-state
navigation/ # 外壳与侧边栏
components/ # app-shell / sidebar / category-icon
lib/ # sidebar-preference
components/ components/
layout/ # AppShell / Sidebar / SidebarNavItem shared/ # site-icon(四级 fallback)/ icon-candidates /
home/ # ClockGreeting / SearchBox / SearchResults / QuickLinks # simple-icon-map / glass-panel
category/ # CategoryHeader / ToolGrid / ToolCard ui/ # button / dropdown-menu / tooltip(shadcn/ui)
common/ # SiteIcon(四级 fallback)/ GlassPanel
data/ # links.json / categories.json / settings.json data/ # links.json / categories.json / settings.json
services/ # links.ts / categories.ts / settings.ts / search.ts # + data.test.ts(结构校验)
types/ # navigation.ts / settings.ts / search.ts services/ # links.ts / categories.ts / settings.ts + services.test.ts
lib/ # cn.ts / greeting.ts / local-search.ts / search-providers.ts / icon.ts(纯函数) types/ # navigation.ts / settings.ts / search.ts
lib/ # utils.ts(cn)
next.config.ts # output: 'standalone' next.config.ts # output: 'standalone'
vitest.config.ts vitest.config.ts
``` ```
@@ -432,4 +476,4 @@ polaris/
## 11. 最终目标 ## 11. 最终目标
> 打开 Polaris 后,用户可以立刻搜索、立刻访问常用网站,也可以通过侧边栏进入分类页面。页面具有个人氛围,但保持干净、高效、克制。第一版数据本地配置,后续平滑切换到 Go 后端。 > 打开 Polaris 后,用户可以立刻搜索、立刻访问常用网站,也可以通过侧边栏进入分类页面。页面具有个人氛围,但保持干净、高效、克制。当前数据内置于本地 JSON 配置,页面统一经 service 层取数。
@@ -6,6 +6,43 @@
> >
> 配套设计图:[Polaris 页面设计图](../assets/Polaris页面设计图.png)(示意图,视觉细节以本文档文字规范为准) > 配套设计图:[Polaris 页面设计图](../assets/Polaris页面设计图.png)(示意图,视觉细节以本文档文字规范为准)
## 0. 当前实现状态(2026-10-14 校对)
本章为现状说明。第 1–13 章保留立项时的历史设计意图,其中「浅色玻璃」「CSS 渐变背景」「仅适配桌面端」等表述均为历史方案,不代表当前实现;样式细节以本章与 `src/app/globals.css` 为准。
**视觉主题**:当前为深色玻璃主题(`color-scheme: dark`),没有浅色/深色切换。稳定的设计 tokens:
```css
--background: #101a2a;
--text-primary: #f4f7fc;
--text-secondary: #d7e2f0;
--text-muted: #bfd0e4;
--primary: #a9c9ff;
--primary-hover: #d3e3ff;
--primary-soft: rgba(147, 190, 255, 0.15);
--border-glass: rgba(222, 234, 255, 0.17);
--radius-card: 20px;
--radius-panel: 24px;
```
**玻璃表面**:侧边栏、搜索框、常用链接卡片均为深色半透明渐变(`--surface-sidebar` / `--surface-search` / `--surface-card` / `--surface-card-hover`),配合 `backdrop-filter: blur(16px - 20px) saturate(108% - 134%)` 与带内描边高光的软阴影,形成悬浮玻璃面板感。
**背景**:背景素材可整体替换(用户会不定期更换),背景层的显示与遮罩样式由现有 CSS 管理——`body` 背景层(fixed + cover)之上叠加一层固定的深色渐变遮罩保证前景可读;素材的类型、路径与画面内容**不属于设计规范**。`settings.theme` 与 `settings.background` 目前仅有数据模型与校验逻辑,不驱动任何样式。
**响应式(已实现)**:
```text
桌面默认:侧栏展开 240px / 折叠 72px,常用链接 4 列
≤1199px:侧栏展开宽度 220px,常用链接 2 列
≤767px:侧边栏变为顶部横栏(Logo + 横向滚动导航,折叠按钮隐藏),
首页与分类页改为顶部横栏下方的常规滚动布局
≤420px:常用链接 1 列,搜索快捷键提示隐藏
```
另已支持 `prefers-reduced-motion` 降低动效。
**数据现状**:8 个分类(含后增的「游戏资料」)、51 条链接、6 条 pinned 常用链接。
## 1. 页面定位 ## 1. 页面定位
Polaris 首页是一个**浏览器起始页**,不是后台管理系统,也不是信息密集型 Dashboard。 Polaris 首页是一个**浏览器起始页**,不是后台管理系统,也不是信息密集型 Dashboard。
@@ -40,6 +77,8 @@ Polaris 首页是一个**浏览器起始页**,不是后台管理系统,也
> 轻量玻璃感 + 极简浏览器起始页 + 柔和个人空间感 > 轻量玻璃感 + 极简浏览器起始页 + 柔和个人空间感
> 2026-10-14 实现状态:该方向已落地,但配色从浅色玻璃改为**深色玻璃**(深蓝底、冷白文字,见第 0 章);关键词中「玻璃感、低饱和、可换背景、安静」依然成立。
设计关键词: 设计关键词:
```text ```text
@@ -136,6 +175,8 @@ AI 工具
生活服务 生活服务
``` ```
> 2026-10-14 实现状态:当前侧边栏为「首页 + 8 个分类」,新增了「游戏资料」分类,上表为立项时的 7 分类历史列表;折叠时导航项只显示图标并提供 Tooltip,移动端顶部横栏下不显示折叠按钮。
「首页」指向 `/`,各分类指向 `/categories/{categoryId}`。当前路由对应的导航项处于选中态,选中样式见[分类页设计文档](./Polaris%20分类页设计文档.md) 6.2 节。 「首页」指向 `/`,各分类指向 `/categories/{categoryId}`。当前路由对应的导航项处于选中态,选中样式见[分类页设计文档](./Polaris%20分类页设计文档.md) 6.2 节。
暂时不展示: 暂时不展示:
@@ -204,6 +245,8 @@ box-shadow: 0 24px 80px rgba(15, 23, 42, 0.1);
border-radius: 24px; border-radius: 24px;
``` ```
> 2026-10-14 实现状态:上方浅色样式为历史方案。当前侧边栏为深色渐变玻璃(`--surface-sidebar`,blur(20px) saturate(108%),`--shadow-panel` 阴影),悬浮边距仍为 20px;宽度见第 0 章响应式。
边栏与页面边缘保持一定距离,形成悬浮玻璃面板感。 边栏与页面边缘保持一定距离,形成悬浮玻璃面板感。
推荐边距: 推荐边距:
@@ -245,6 +288,8 @@ font-weight: 700;
color: #0f172a; color: #0f172a;
``` ```
> 2026-10-14 实现状态:当前问候语字号为 clamp(44px, 4.2vw, 56px)、冷白色(rgba(248, 250, 252, 0.98))并带文字投影,日期为 rgba(241, 245, 249, 0.86);上方 #0f172a / #64748b 为历史浅色方案。
日期样式: 日期样式:
```css ```css
@@ -311,7 +356,7 @@ height: 68px;
高度:64px - 72px 高度:64px - 72px
``` ```
> 移动端尺寸第一版不定义,移动端整体适配为后续阶段工作。 > 历史说明:立项时移动端尺寸未定义。当前移动端已适配:搜索框宽度随容器收缩,≤420px 时隐藏快捷键提示(见第 0 章)。
### 6.4 搜索框视觉样式 ### 6.4 搜索框视觉样式
@@ -325,6 +370,8 @@ border-radius: 24px;
box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12); box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12);
``` ```
> 2026-10-14 实现状态:上方浅色样式为历史方案。当前搜索框为深色玻璃(`--surface-search` 渐变 + blur(20px) saturate(108%)),聚焦时出现 rgba(147, 197, 253, 0.17) 的 focus 环;尺寸仍为最大 760px × 68px。
placeholder 统一为: placeholder 统一为:
```text ```text
@@ -480,6 +527,8 @@ border-radius: 20px;
box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12); box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12);
``` ```
> 2026-10-14 实现状态:上方浅色样式为历史方案。当前结果面板为更实的深色玻璃 rgba(19, 31, 49, 0.95),最大高度 min(520px, 100vh − 220px),选中项使用 `--primary-soft` 底色。
列表项内容: 列表项内容:
```text ```text
@@ -525,6 +574,8 @@ Bilibili
实际项目中根据个人习惯调整。 实际项目中根据个人习惯调整。
> 2026-10-14 实现状态:当前 pinned 链接为 6 条,按 `pinnedSort` 排序展示:GitHub、ChatGPT、Gmail、Notion、YouTube、Bilibili;服务层默认上限仍为 8 条(`getPinnedLinks(limit = 8)`)。下文「第一版展示 8 个常用链接」及 8 条 pinned 的数据构成为立项时的历史方案。
数据来源:`pinned: true` 的链接,按 `pinnedSort` 排序取前 8 个;超出 8 个时按 4 列网格换行展示。`sort` 仅用于分类内排序,避免首页顺序与分类页顺序相互约束。 数据来源:`pinned: true` 的链接,按 `pinnedSort` 排序取前 8 个;超出 8 个时按 4 列网格换行展示。`sort` 仅用于分类内排序,避免首页顺序与分类页顺序相互约束。
第一版数据构成(8 条 pinned 分布于各分类,归入真实分类): 第一版数据构成(8 条 pinned 分布于各分类,归入真实分类):
@@ -576,6 +627,8 @@ border-radius: 20px;
box-shadow: 0 14px 40px rgba(15, 23, 42, 0.1); box-shadow: 0 14px 40px rgba(15, 23, 42, 0.1);
``` ```
> 2026-10-14 实现状态:上方浅色样式为历史方案。当前卡片为深色玻璃(`--surface-card` + blur(16px) saturate(134%)),高 76px、圆角 20px,hover 上浮与过渡不变。
推荐尺寸: 推荐尺寸:
```text ```text
@@ -622,6 +675,8 @@ Polaris 支持背景自定义的设计预留。
**第一版默认背景为 CSS 低饱和青蓝渐变**(模拟晨雾 / 天空氛围),不依赖图片资产。 **第一版默认背景为 CSS 低饱和青蓝渐变**(模拟晨雾 / 天空氛围),不依赖图片资产。
> **2026-10-14 实现状态(重要)**:背景已不再是 CSS 渐变,改为可替换的背景素材层 + 深色遮罩(由 `body` 背景层加载,见第 0 章);背景层显示与遮罩样式由现有 CSS 管理,素材的类型、路径、画面与题材由用户自行选择、不定期更换,**不写入设计规范**。下方「图片背景建议」仅作当时的设计联想,不构成约束。`settings.background.type` 目前仅有数据模型与校验,未接入渲染;「CSS 低饱和青蓝渐变」为历史方案。
后续支持: 后续支持:
```text ```text
@@ -650,6 +705,8 @@ Polaris 支持背景自定义的设计预留。
由于用户未来可能更换任意背景,因此需要增加背景遮罩层,保证内容可读。 由于用户未来可能更换任意背景,因此需要增加背景遮罩层,保证内容可读。
> 2026-10-14 实现状态:遮罩已实现,但形态与下方两侧历史值不同——当前为固定深色渐变(顶部 rgba(5, 12, 25, 0.43) → 中部 0.37 → 底部 0.47,无 backdrop blur);浅色遮罩值为历史方案,「深色主题(后续阶段预留)」未按该形式落地。
浅色主题: 浅色主题:
```css ```css
@@ -668,9 +725,9 @@ backdrop-filter: blur(8px);
## 10. 配色系统 ## 10. 配色系统
默认采用浅色玻璃主题。 > 2026-10-14 实现状态:当前默认为**深色玻璃主题**(无主题切换),tokens 直接定义在 `globals.css` 的 `:root`,未使用 `[data-theme]` 覆盖;`settings.theme` 未接入样式。现行值见第 0 章;下方「推荐 CSS 变量」为立项时的浅色方案,仅作历史参考。
推荐 CSS 变量: 历史方案(浅色玻璃)推荐 CSS 变量:
```css ```css
:root { :root {
@@ -694,7 +751,7 @@ backdrop-filter: blur(8px);
} }
``` ```
变量按双主题友好方式组织:第一版只实现浅色值;深色玻璃主题为后续阶段,届时以 `[data-theme="dark"]` 覆盖同名变量,组件无需改动。 > 历史说明:上段为立项时的双主题规划。实际实现未走 `[data-theme]` 覆盖路线,深色值自当前版本起直接作为默认主题(见第 0 章与 `globals.css`)。
--- ---
@@ -716,6 +773,8 @@ font-family:
sans-serif; sans-serif;
``` ```
> 2026-10-14 实现状态:当前字体栈以 Avenir Next / Avenir 开头,未引入 Inter;中文回退与上方一致。
字体原则: 字体原则:
```text ```text
@@ -775,6 +834,8 @@ font-family:
第一版仅实现浅色主题、仅适配桌面端 第一版仅实现浅色主题、仅适配桌面端
``` ```
> 历史说明:末行「仅浅色主题、仅适配桌面端」为第一版约束,已被后续实现取代——当前为深色玻璃默认主题,移动端适配已完成。
最终目标: 最终目标:
> 打开 Polaris 后,用户可以立刻搜索、立刻访问常用网站,也可以通过侧边栏进入分类页面。页面具有个人氛围,但保持干净、高效、克制。 > 打开 Polaris 后,用户可以立刻搜索、立刻访问常用网站,也可以通过侧边栏进入分类页面。页面具有个人氛围,但保持干净、高效、克制。
@@ -0,0 +1,17 @@
# Polaris 文档与当前实现对齐(2026-10-14)
状态:用户已确认调整后的方案;设计文档和部署说明已更新(2026-10-14)。未修改产品代码、配置或 CI 工作流。
## 范围
1. 更新 `docs/design/Polaris 项目说明文档.md`:将当前部署方式统一为 standalone;依据现有 CSS 描述深色玻璃视觉、移动端布局、8 类 51 条链接及 6 条常用链接;更正阶段清单与目录结构;明确 `settings.theme`、`settings.background` 仅有数据模型与校验,未驱动样式。背景素材属于可更换内容,不写死图片路径、画面类型或具体背景外观。
2. 更新 `docs/design/Polaris 首页设计文档.md`、`Polaris 分类页设计文档.md`:在保留历史设计意图的同时,按现有代码描述深色玻璃风格和移动端顶部横栏;区分尚未实现的双主题、背景配置生效与已实现的分类网格三档断点(≥1280px 三列、1000–1279px 两列、≤999px 单列),不规定具体背景素材及其内容。
3. 对日期命名的 `docs/design/2026-08-26-Polaris-首页实现规格.md` 增加历史规格状态说明和现状索引,不逐行重写历史验收要求;历史 `docs/superpowers/plans/` 保持原貌。
4. 修订 `deploy/README.md` 的触发方式和镜像摘要说明:仅推送 `polaris-v*` 标签才运行 CI;验证通过后发布带完整 commit SHA 的镜像;workflow 已实现摘要输出,但 registry、runner 与服务器行为仍待现场验证。明确 Compose 目前只要求镜像变量非空,digest 固定是部署操作约定而非自动校验。
## 边界与验证
- 不修改应用代码、配置数据、工作流或标签触发条件;不处理未来 Go API。
- 不以当前背景文件或壁纸内容作为设计基线;用户可不定期替换背景素材,视觉描述以现有 CSS 中稳定的色彩、表面与交互样式为准。
- 不碰仓库 `note/` 中已有的删除/新增改动,亦不处理仓库外或已删除的历史笔记。
- 编辑前检查目标文件缩进和换行形式;完成后检查文档差异、搜索剩余过时表述并核对 Git 工作树。纯文档更新不要求构建或测试。