本页与 docs/design.md 同步维护。令牌真值在 web/style.css :root 与 src/theme.ts,由 tests/theme.test.ts 守门。改设计:先改 design.md → 改代码令牌 → 更新本页样张。

1 · 设计原则

逻辑 puzzle 的盘面只回答三个问题:我走到哪了、哪错了、过没过。

板要干净

盘面无阴影、无纹理、无装饰。灰阶承担一切非路径信息。

一个主色

蓝紫只表示「已走 / 当前 / 可继续」。红只表示冲突,琥珀只表示提示。不每关换色。

数字优先

系统圆体、800 字重、等宽数字。其余文字都比数字轻。

动效四档

只用 120 / 200 / 320 / 500 ms 与四条缓动。新动效先归档再写。

反馈贴手指

落子、踩对、冲突、死路都发生在手指所在格子上。不弹窗、不撒纸片。

信息随手可见

关号、包名、本包进度、剩余格数常驻顶栏。

2 · 色彩

浅色单主题。DOM 用 CSS 变量,Canvas 用 THEME,同名同值。

语义

颜色只能用于不能用于
主色已走格、桥、起点 1、当前关、主按钮、进度装饰、背景、标题文字
冲突冲突格、「重置进度」任何常驻元素、警示以外的强调
提示提示描边、提示按钮脉冲任何常驻元素
主色·亮过关后的全盘提亮(唯一允许的换色)过关以外

对比度

组合对比度用途
白 on 主色5.2 : 1已走格数字、主按钮
墨 on 未走格12.6 : 1未走线索数字
白 on 冲突红4.5 : 1冲突格数字(角标另有墨底白字)
墨 2 on 白5.1 : 1副文案
墨 on 未走格12.6 : 1未走线索描边(与数字同色)
墨 3 on 白2.5 : 1仅非关键弱文案

3 · 字体与字阶

字体栈:ui-rounded, "SF Pro Rounded", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif。全局等宽数字。

display · 34 / 800
数字一笔 0123
选关页标题
title · 22 / 800
1-7 · 2-10 · 3-6
顶栏关号
heading · 17 / 700
入门 · 进阶 · 奇与偶 · 继续 · 2-1
包标题、主按钮
body · 15 / 500
从 1 开始,滑到旁边的格
副标题、字幕
label · 14 / 700
6 · 完成 · 10 / 10 · 下一步在这里
胶囊、包进度、toast
caption · 13 / 600
音效 · 振动 · 16 / 26
chip、总进度数字
micro · 12 / 600
入门 · 第 7 关
顶栏副标题

盘面字阶(相对单位格 u)

1
起点 0.60 u · 800
7
单位数 0.52 u · 800
14
两位数 0.46 u · 800
奇
奇偶 0.44 u · 700
6偶
小字 0.19 u · 700
68
角标 r=0.15 u · 字 1.25 r

4 · 间距 · 圆角 · 尺寸

间距 · 4pt 网格

4 / 8 / 12 / 16 / 20 / 24 / 28。页面左右 20,顶 12 + 安全区,底 16 + 安全区。

圆角

sm 10 · md 14(关卡格、toast)· lg 18(主按钮、底栏按钮)· xl 24 · 胶囊 999 · 桌面框 28。盘面格 0.18 u。

尺寸

点击区 ≥ 44。顶栏 52,胶囊 32,底栏按钮 56,主按钮 54,chip 34,关卡格 5 列间距 12。

10
14
18
24
关卡格 14
底栏按钮 18
盘面格 0.18 u

5 · 盘面

格圆角 0.18 u、缝 0.10 u、桥厚 0.46 u。整盘垂直居中后上提 3%。四周死区:触屏 8%,鼠标 14%。点任意已走格直接回退,可接着滑动。

格的状态

未走
8
未走线索
偶
未走奇偶
1
起点 1(未按下)
5
已走
8
已走线索
6偶
已走奇偶
68
冲突 + 角标
5
错位:红格 + 轻晃
5
补数字:1~9 补 5
4
提示目标
9
退回压暗
12
过关提亮

样张:1-7 半途(含大格、紫色连线、红色错格)

左:路径 1→2→3→4→5,6 踩到线索 8 冲突,只让冲突格变红,连接线始终紫色。右:2×2 大格只计一步,异形格由单位矩形 + 接缝同色拼成。桥保持路径色,与出错格的颜色分开。

6 · 组件

顶栏 · 本包进度条 · 字幕

1-7
入门 · 第 7 关
6
走错了,沿原路滑回去
12
完成
胶囊:默认 / 完成态

底栏按钮 · Toast

三个等宽按钮,高 56px,15px 字号;补数字保留在本局盘面,指路沿用下一步 / 回退高亮。Toast 距页面底边 128px + 安全区,长句换行,避开手势说明。

按住滑动连线 · 点已走格回退

下一步在这里

选关:总进度 · 关卡格四态 · 主按钮 · chip

16 / 26
进阶2 / 10

已过关 / 已过关 / 当前(呼吸)/ 未过关 / 锁定(点一下抖动)

7 · 页面

390 × 760 样机,桌面浏览器上以 480px 手机框居中,圆角 28 + 框阴影。

数字一笔

按数字顺序,一笔走遍每一格

16 / 26
1-7
入门 · 第 7 关
6

按住滑动连线 · 点已走格回退

8 · 动效

四档时长、四条缓动。Canvas 侧的弹簧与扫光在这里用 CSS 近似回放,参数以 src/theme.ts MOTION 为准。

档时长用途缓动
fast120ms按下反馈、步号淡入、桥生长ease-out cubic-bezier(.22,1,.36,1)
base200ms整屏切换、toast、胶囊 bump、进场单格ease-out / spring cubic-bezier(.34,1.56,.64,1)
slow320ms闪白衰减、过关扫光、抖动、进度条linear(衰减)/ ease-out
hold500ms过关停留–
循环0.9s / 2.4s提示按钮脉冲 / 当前关呼吸、提示描边ease-in-out cubic-bezier(.65,0,.35,1)

逐个回放

开局进场base · 每格 +14ms

缩放 0.92 → 1 + 淡入,按阅读顺序错落,延迟封顶 200ms。

落子弹簧≈200ms · k=260 c=18

当前格放大回 1,步号同时 120ms 淡入。

桥生长fast · ease-out

只长厚度,跨缝方向第一帧就盖满,不露白缝。

踩对线索闪白slow · 线性衰减

描边闪白 1 → 0。这是「推对了」的主奖励。

死路 / 非法起手抖动280ms · 6 个来回

幅度 0.06 u 递减,不弹「失败」。

过关扫光slow · 每格 250ms

全盘切亮色,按步序扫白光,320ms 内起完。

提示描边2.4s · ≈1.1Hz

琥珀外描边正弦脉冲,最后 0.4s 淡出。

整屏切换base · ease-out
选关 → 对局

淡入 + 上移 8px。关与关之间不切屏,只有盘面进退场。

冲突280ms · 单格轻晃
5

立刻红底 + 单格轻晃 + 闷音 + 40ms 振动。连接线始终紫色;步号错位不加叉号。撤销立即褪回并停止晃动。

过关时间线

扫光0 – 320ms · 和弦起、胶囊「完成」、按钮禁用
停留320 – 820ms
淡出820 – 980ms
下一关进场980ms 起 · 顶栏就地更新,盘面错落进场 ≤ 400ms

减弱动态

系统开启「减弱动态效果」时:CSS 动画与过渡全部关闭;Canvas 去掉进场错落、弹簧、扫光与淡出,只保留状态切换与提示描边。

9 · 声音与振动

事件音效振动
落子90ms 正弦短音,C5 起每步升半音,12 步循环8ms(踩对线索 18ms)
冲突160ms 方波 130Hz 闷音40ms
非法起手60ms 三角波 220Hz15ms
死路–10 · 30 · 10
过关C-E-G-C 三角波和弦,每音 220ms,间隔 70ms20 · 40 · 30

10 · 同步规则

  1. 先改 docs/design.md 的对应表格,并在「变更记录」加一行。
  2. 改 modes/01-number-stroke/web/style.css 的 :root 与 src/theme.ts。
  3. 更新本页顶部 :root 与相应样张。
  4. npm run check:tests/theme.test.ts 会比对 CSS 与 theme.ts 的颜色、动效时长与字体栈。
  5. npm run build:standalone 重新生成试玩版。