## Context

`LoginView.js` 将 `frontend/img/black_hole.png` 导入为 CSS 自定义属性（CSS 变量，即可由页面传给样式的命名值），`app.css` 再将该图片与遮罩渐变合成为登录页背景。当前实现使用原图，因此静止画面是唯一可作为“一模一样”验收基准的版本；用 Canvas 或 SVG 重新绘制会改变纹理、光照和压缩细节。

本变更让图片的背景定位随鼠标小幅变化，并以同一图片创建只覆盖黑洞区域的遮罩动态层。该层低速旋转以模拟吸积盘自转；登录表单、遮罩与认证业务层保持固定，避免动画影响输入、点击或会话数据。

### 实施范围与文件用途注释

| 文件 | 文件用途注释（白话） | 关联逻辑 | 本次变化 |
| --- | --- | --- | --- |
| `frontend/src/modules/auth/LoginView.js` | 登录界面组件，负责把表单状态和页面交互交给 Vue。 | 指针事件 -> 坐标计算 -> CSS 变量；表单 -> `signIn` -> 路由。 | 仅新增背景偏移状态、事件处理与供样式定位局部旋转层的标记；不改变提交逻辑。 |
| `frontend/src/styles/app.css` | 登录页和后台页面共享样式表，其中 `login-` 前缀规则只作用于登录页。 | CSS 变量 -> 原图背景定位/过渡；遮罩层 -> 局部旋转；媒体查询 -> 无动画回退。 | 将背景图片层、局部旋转层与遮罩层分开，并新增视差、自转和减少动态效果规则。 |
| `frontend/tests/login-experience.spec.js` | 浏览器端登录体验回归测试，使用模拟认证接口而非真实账号。 | Playwright 指针事件/等待动画帧 -> 计算样式 -> 登录页背景。 | 新增验证背景变量、移动后偏移、离开后复位与局部旋转层的用例。 |

### 实施范围内方法的新手注释门禁

| 方法/回调 | 必须添加的注释内容 |
| --- | --- |
| `isBackgroundParallaxEnabled` | 代码作用（白话）：判断当前设备是否适合鼠标背景动画。关联文件：`LoginView.js`、`app.css`。关联逻辑（调用链/数据流）：系统动态偏好/精细指针能力 -> 指针处理是否写入 CSS 变量。 |
| `handleBackgroundPointerMove` | 代码作用（白话）：把鼠标相对登录区域的位置换算成小范围背景偏移。关联文件：`LoginView.js`、`app.css`。关联逻辑（调用链/数据流）：`pointermove` -> 坐标归一化 -> CSS 变量 -> 背景位置。 |
| `resetBackgroundParallax` | 代码作用（白话）：鼠标离开时让背景回到原图的默认裁切位置。关联文件：`LoginView.js`、`app.css`。关联逻辑（调用链/数据流）：`pointerleave`/组件卸载 -> 零偏移 CSS 变量 -> 平滑复位。 |
| 新增 Playwright 测试回调 | 代码作用（白话）：验证动画仅改变背景偏移而不替换原图。关联文件：`login-experience.spec.js`、`LoginView.js`。关联逻辑（调用链/数据流）：模拟鼠标 -> DOM 计算样式 -> 原图 URL 与偏移断言。 |

## Goals / Non-Goals

**Goals:**

- 静止状态继续使用同一张 Vite 处理的黑洞图片，保持既有构图、遮罩和登录面板位置。
- 在精细指针设备上，根据鼠标在登录区域的位置平滑改变背景定位，最大偏移受限且不会露出图片边缘。
- 以低速、无限循环的 CSS 动画（由浏览器样式表驱动的画面变化）旋转同源图片的局部遮罩层，形成仅黑洞吸积盘自转的视觉效果。
- 鼠标离开区域后复位；触摸/粗指针设备以及 `prefers-reduced-motion: reduce`（系统声明希望减少动画）保持静止。
- 覆盖可自动执行的浏览器验收，不触发真实登录或写入数据。

**Non-Goals:**

- 不用 Canvas、WebGL、SVG 或 AI 生成资源重画黑洞图；它们只能近似，不能保证与原图一致。
- 不修改登录接口、认证状态、DTO（前后端传递的数据格式）、数据库、路由或表单样式。
- 不为触摸设备加入陀螺仪、拖拽或其他背景交互。
- 不模拟真实的三维引力、粒子或光线追踪物理效果；自转是基于原图的二维视觉模拟。

## Decisions

### 1. 以原图背景定位替代代码重绘

背景继续引用 `black_hole.png`，代码只写入水平、垂直偏移的 CSS 变量；遮罩层与面板不参与移动。

- 选择原因：静止画面复用同一个图片资源，能保留视觉验收的全部像素细节；修改定位可以实现空间感而不更换内容。
- 替代方案：Canvas/WebGL 着色器（由程序计算每个像素颜色的渲染方式）。未采用，因为难以匹配原图纹理，且会增加浏览器兼容、性能与调色成本。

### 2. 使用 Pointer Events 与受限 CSS 变量

登录页根元素监听 `pointermove` 和 `pointerleave`，仅接受鼠标/精细指针；处理函数把相对坐标映射到有限像素区间，并通过 CSS 过渡平滑显示。CSS 自定义属性是浏览器原生传值机制，不需要新增依赖或全局状态。

- 选择原因：不会移动表单 DOM，也不会触碰登录请求数据；偏移上限可避免 `cover`（保持图片填满区域的裁切方式）出现空白边缘。
- 替代方案：直接 `transform` 整个 `.login-page`。未采用，因为这会让登录面板和遮罩一起移动，影响输入可用性与视觉稳定性。

### 3. 使用同源遮罩层模拟局部吸积盘自转

在背景图片上叠加一个全尺寸、同源图片图层；该图层通过径向遮罩（让图层只在黑洞附近可见、边缘渐隐的样式）限制影响范围，并围绕黑洞位置以约 30 秒一圈的速率旋转。基础背景、渐变遮罩与登录面板不参与该动画。

- 选择原因：静止时叠加层与原图像素相同；动画时只在黑洞区域产生变化，不会让整幅星空或表单旋转，也无需新增图片资源。
- 替代方案：旋转整个登录页背景。未采用，因为星空和构图会一起旋转，且视觉上不像黑洞本身自转。

### 4. 无动画优先的可访问性回退

JavaScript 在系统请求减少动态效果或设备没有精细指针时不写入偏移；CSS 同时提供 `prefers-reduced-motion` 规则取消过渡，形成双层保护。

- 选择原因：避免动画让触摸设备误触后产生不可预期的画面变化，也尊重用户的系统辅助设置。
- 替代方案：所有设备都启用动画。未采用，因为无法可靠取得触摸位置且会违背减少动态效果偏好。

## Risks / Trade-offs

- [不同屏幕比例下原图裁切不一样] → 保留当前各断点的基础背景位置，只在其周围做小幅偏移，并在桌面与移动视口测试。
- [高频鼠标事件增加样式更新] → 仅写入两个 CSS 变量，不创建网络请求或 DOM 节点；如测试发现掉帧，再使用 `requestAnimationFrame`（浏览器每帧合并更新的机制）合并更新。
- [浏览器不支持 Pointer Events] → 背景保持当前静态画面，登录功能完全不受影响。
- [遮罩边缘与不同视口下的黑洞位置不完全重合] → 复用现有响应式背景定位值，并将遮罩边缘渐隐；在桌面与小屏视口人工检查后再微调位置。
- [局部旋转造成 GPU 绘制压力] → 只创建一个伪元素/装饰层，采用低速 `transform` 动画；减少动态效果设置下关闭动画。
- [测试环境无法模拟系统动态偏好] → 自动测试验证默认鼠标流程和复位；减少动态效果作为手工 smoke 验收项记录。

## Migration Plan

1. 按范围文件逐组实现背景状态、样式和测试，保留原有图片导入与登录提交代码。
2. 执行前端单元/端到端测试与生产构建，并在桌面浏览器手工检查鼠标移动、离开复位、局部自转和登录表单。
3. 若视觉或性能不符合验收，仅撤回新增事件、变量和样式规则；原图背景与认证逻辑无需迁移或数据回滚。

## Open Questions

- 无阻塞问题；默认以当前已验收的 `black_hole.png` 为唯一视觉基准，并采用轻量、低位移的鼠标视差。
