# Huein Lightfield UI Style

> 把一套「悬浮岛 + 光场」的暗色后台界面风格完整复刻到任意项目上。**给 AI 这一个技能就够** —— 入口是本文件，做法细节在同目录的 `references/` 里按需读取。覆盖：三层光场的焦点镜像模型、距离驱动的边缘光（鼠标即一盏灯）、跟着光走的面具点阵、两个互不接触的悬浮岛外壳、收起 / 展开与首帧状态、导航选中项「滑过去」、`<details>` 与折叠面板的展开过渡、内容依次浮入，以及一整套「都写成断言、不靠肉眼看」的验收手法。当用户说「复刻这种前端风格、照这套风格做个新后台、想要悬浮岛 / 边缘光 / 光场 / 点阵背景 / 呼吸感 / 高级感后台、这套设计的规则是什么、把绘影工作台那套 UI 搬过来」时使用。

- Skill: `codes233/huein-lightfield-ui-style` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add codes233/huein-lightfield-ui-style`
- Raw SKILL.md: https://api.skillmd.com/api/skills/codes233/huein-lightfield-ui-style/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: CODES233 (https://skillmd.com/u/codes233)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/codes233/huein-lightfield-ui-style

---


# 悬浮岛 + 光场 · 后台 UI 风格复刻

**设计语言一句话**：

> **光是指示注意力的工具，不是装饰。**

每当你想再叠一处光，先问一句「它在提示什么？」——答不上来就别加。
这条判据能挡掉九成的「花哨但廉价」。

---

## 零、怎么用这份技能（先读完这一节）

这份技能的正文是**入口与地图**，具体做法在 `references/` 下按需读取。
**不要凭记忆写代码 —— 每一步动手之前，先读那一步指定的文件。**

```
huein-lightfield-ui-style/
├── SKILL.md                  ← 你正在读的：原则 · 七步流程 · 骨架 · 地图
├── references/
│   ├── 01-tokens.md          设计 token 全表与色相派生推导
│   ├── 02-shell.md           悬浮岛外壳：几何 / 收起展开 / 窄屏 / 首帧 / 滚动 / 缓存
│   ├── 03-light.md           光：边缘光 / 光柱 / 点阵 / 三层光场 / 开场动画
│   ├── 04-motion.md          导航飞行 · 展开过渡 · 内容浮入
│   └── 05-verify.md          验收与取证手法（怎么写断言 · 测试脚本的坑）
├── assets/
│   ├── tokens.css            ← 可直接改用（MIT，见 LICENSE）
│   └── lightfield.js         光场引擎，851 行，可直接改用
├── PROMPT.md                 给 AI 的一键复用提示词（复制粘贴用）
└── README.md
```

**硬规则（不遵守会做错）**

1. **按顺序做，不要跳步。** 七步的顺序是设计过的 —— 后一步假设前一步已经就位。
2. **每一步动手前读对应 reference**，尤其是 `01-tokens.md` 和 `05-verify.md`。
3. **每一步做完就自检**，不要攒到最后一起验。断言怎么写见 `references/05-verify.md`。
4. **一次只改一小块。** 这种风格几乎全是动效与光，一次性铺开改，
   出问题时无法定位是哪一步引入的。
5. **`.standalone.md`（如果仓库里有 `SKILL.full.md`）是所有文件的拼接版** ——
   只有在「只能粘贴一个文件、读不到 `references/`」时才用它。
   能用 `references/` 就一定用，按需读取比全文照读省得多。

**如果你读不到 `references/`**（只拿到了这一份文本）：
信息量仍然够开始第 1、2、4、5 步 —— 本文件里有原则、流程、骨架、和三处最贵的坑。
动手写 `light()` 之前先说明「缺了光场那部分的细节，我按骨架里描述的三层镜像模型实现」，
不要硬编。

---

## 一、三条原则

1. **光有方向。** 所有光层对**同一个**「光场焦点」做响应（桌面 = 指针，触摸 = 漂移的虚拟点）。
   绝不要出现两个各自为政的光源 —— 那是「装饰」的味道。
2. **深色是主场景，浅色不是反色。** 两套**独立调校**：
   浅色下光场 chroma 降一档、玻璃换实色、文字加粗。
   直接反相或简单换亮度会立刻露出廉价感。
3. **动效只动 `transform` 与 `opacity`，绝不回弹。**
   「呼吸感」来自**错峰 + 时长**，不是来自花哨的曲线。会弹的缓动一律不用。

## 二、从零复刻 · 七步

| # | 做什么 | 读哪一份 | 做完的样子 |
|---|---|---|---|
| 1 | **定 token**：色相派生、间距、圆角、字号、动效阶梯 | `references/01-tokens.md` | 改一个 `--brand-hue` 能派生整套协调配色 |
| 2 | **搭外壳骨架**：`grid` + 一圈等宽留白，做出两个互不接触的悬浮岛 | `references/02-shell.md` §一 | 侧栏与顶栏之间有一条等宽缝，四周留白相等 |
| 3 | **收起 / 展开**：侧栏收成图标栏、顶栏浮走并把纵向空间还回来 | `references/02-shell.md` §四 | 两个方向都能收，且收起来真的省出了空间 |
| 4 | **首屏入场 + 解析期状态 + 动画残留清理** | `references/02-shell.md` §二 §三 §五 §八 | 刷新后第一帧就是正确状态，静置后无残留 transform |
| 5 | **导航切换的「滑过去」+ 可展开内容的过渡** | `references/04-motion.md` | 选中项从旧项滑到新项，中途没有暗缝 |
| 6 | **光**：先边缘光（距离驱动），再光标光柱，最后点阵的面具 | `references/03-light.md` | 指针不碰卡片也能点亮它的边 |
| 7 | **内容依次浮入** | `references/04-motion.md` 后半 | 内容一块块从雾里凝出来，错峰不挤在一起 |

> 第 4 步的「解析期状态」和第 6 步的「开场动画」是最容易被跳过、也最容易返工的两处 ——
> 它们都涉及「第一帧长什么样」，**事后补的代价很高**。

## 三、页面骨架（照抄，顺序都不要改）

```html
<body>
  <!-- ① 底色：三层光 + 点阵。fixed，最底，不吃事件 -->
  <div class="lightfield">…</div>

  <!-- ② 侧栏的边光：因为侧栏是滚动容器，光不能挂在它自己身上 -->
  <div class="island-glow"></div>

  <!-- ③ 光标光柱：fixed + mix-blend-mode: screen -->
  <div class="cursor-light"></div>

  <div class="shell">
    <aside class="sidebar">…</aside>
    <div class="shell__main">
      <header class="topbar">…</header>
      <main class="shell__content">…</main>
    </div>
  </div>
</body>
```

### 三条铁律（这三条是这套风格里最贵的知识）

**① 所有 `fixed` 层必须在内容区之外。**
`animation-fill-mode: both` 的终态**不是 `none`** —— computed 的 `transform` 是矩阵、
`filter` 是 `blur(0px)`，**两者都会让元素成为 `position: fixed` 后代的包含块**。
把遮罩、ghost、toast 放进内容区，它们会塌成一条横条贴在页面下半部分。
→ 推论：**动画播完必须撤掉 `animation`**。

**② 滚动容器上的光要另开 `fixed` 层。**
挂在滚动容器自己身上会跟着内容一起滚走，而且**不滚动的时候看不出问题**。

**③ 解析期状态一律用内联脚本。**
主题、折叠状态、导航起手、滚动位置这些「来自 localStorage / sessionStorage」的状态，
必须在 `<head>` 或 body 末尾的内联脚本里就应用 ——
模块脚本是 **deferred**，跑到之前浏览器已经画过几帧，用户会看到「先闪一下再变」。

## 四、这套风格里最容易做错的三个地方

先记住这三条，能省掉一整轮返工。细节见对应 reference。

1. **三层光场是「围绕焦点做镜像」，不是三个固定锚点。**
   主光（品红）在焦点 · 补光（琥珀）对角镜像 · 冷光（靛紫）垂直镜像。
   ⚠️ 写错成「三个固定锚点 + 微视差」的后果是：三团光全挤在屏幕上方一条横带、下半屏纯黑。
   **参数都在、不报错、注释还理直气壮 —— 看代码根本看不出错。** → `references/03-light.md`
2. **光由「距离」决定，不是「碰到才亮」。**
   距离要用「到**矩形本身**的精确距离」（矩形内 = 0），
   不是「到中心距离 − 外接圆半径」（那会让指针在下半个屏幕都被判成贴着顶栏）。
   → `references/03-light.md`
3. **生硬通常出在「时序」，不在曲线。**
   凡是「A 已经到位、B 还在路上」，调 B 的曲线永远调不好 —— 要把 **A 按住**。
   → `references/04-motion.md`

## 五、做完的样子（Definition of Done）

全部按 `references/05-verify.md` 的方式写成**断言**，不靠肉眼看。至少要能证明：

- [ ] 四周留白相等、两个岛不接触（缝 = gap）
- [ ] 收起态刷新后，**第一帧**就是收起态（不是先展开再折一下）
- [ ] 首次加载有入场动画；**第二次加载没有**，且静置后 `transform` / `clipPath` 都是 `none`
- [ ] 导航切换：滑块起点贴着旧项（< 16px）、终点贴着新项（< 16px）
- [ ] 落地过程**逐帧采样**「两层 opacity 的叠加」恒为 1（没有暗缝）
- [ ] 指针**不碰**卡片时 `--gle` 也 > 0（距离驱动），且随距离单调递减
- [ ] 点阵面具的第一个圆的位置 == 光场写出的 `--lf-fx / --lf-fy`
- [ ] 刷新 / 换页时，光场起点接的是**上一页的位置**
- [ ] 全站没有「引用了但不存在的 CSS 变量」（这个坑会让边框变成白框，且**不报错**）
- [ ] 控制台无 `pageerror`

---

## 附：这份技能的来历

从 [绘影工作台 hueinbench](https://github.com/CODES233)（自媒体工作室管理系统，AGPL-3.0）
里把这套界面风格抽出来的一份复刻手册。原项目里这套设计已经跑过 13 个版本迭代，
下面每一条「⚠️」基本都是真实踩过的坑，不是推演出来的。

本仓库以 **MIT** 开源，见 `LICENSE`。作者同为绘影工作台的作者，
故本仓库中的 `assets/`（与该项目同源）在此按 MIT 另行授权。

