feat(design): add the Macaron (07) art direction and land the Signpost (06) package files

- 07 macaron, referenced from Meowdoku: cream worlds, a white tray with
  gutters, candy tokens with white arrows, two-column 关卡/待解 HUD, white
  elevated tool discs (macaron-only exception to the flat rule), full-screen
  dark result overlay, a brick ripple on board clear, an eased glide-out and
  dot-lattice dissolve on exit; Resource Han Rounded subset fonts (SIL OFL)
  in assets/fonts with the charset and regeneration note
- 06 signpost: the design.md, tokens and preview directory that earlier
  commits left untracked
- design docs, catalog, manifest, showcase and base spec updated to seven
  directions; the analysis and proposal live in docs/art-proposal-macaron.html
- the renderer, app, geometry and CSS sources for both directions were
  already carried by the level commits made from this working tree

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
cabinw
2026-09-15 15:43:25 +08:00
co-authored by Claude Fable 5.1
parent 7607f48cb1
commit e447d1f807
31 changed files with 1415 additions and 60 deletions
+97 -3
View File
File diff suppressed because one or more lines are too long
+4 -2
View File
@@ -109,7 +109,7 @@
旋转操作为放大的生成箭头,下方分别写“左转”“右转”,不加矩形底板。文字用主文字色;白色箭头允许轻微蓝灰轮廓阴影增强边缘识别,不能改写原图轮廓。它们须保留至少 44×44 的触摸区域。 旋转操作为放大的生成箭头,下方分别写“左转”“右转”,不加矩形底板。文字用主文字色;白色箭头允许轻微蓝灰轮廓阴影增强边缘识别,不能改写原图轮廓。它们须保留至少 44×44 的触摸区域。
撤销、重来、提示使用独立彩色底座:原版为蓝、紫、金;高彩为青、荧粉、亮黄;玩具为蓝、红、黄圆角积木键;动物为绿、棕、麦黄徽章;轻线纸境为雾蓝、陶橙、赭金平面底座。五套方案的底部道具均采用纯色平面,不使用投影、内阴影、立体底边或渐变高光;图标和未来次数/广告角标同样不加阴影。普通底座 64px,大屏 68px,短屏 56px;图标 32px、标签 13px。整体点击区至少 80×96px,短屏 80×84px。禁用时确实停止操作,道具透明度为 50%;不得只有颜色变化却仍可点击。 撤销、重来、提示使用独立彩色底座:原版为蓝、紫、金;高彩为青、荧粉、亮黄;玩具为蓝、红、黄圆角积木键;动物为绿、棕、麦黄徽章;轻线纸境为雾蓝、陶橙、赭金平面底座。五套方案的底部道具均采用纯色平面,不使用投影、内阴影、立体底边或渐变高光;图标和未来次数/广告角标同样不加阴影。第 07 套「马卡龙」的白色圆钮带柔和投影是用户于 2026-09-14 确认的唯一例外,只允许该套使用。普通底座 64px,大屏 68px,短屏 56px;图标 32px、标签 13px。整体点击区至少 80×96px,短屏 80×84px。禁用时确实停止操作,道具透明度为 50%;不得只有颜色变化却仍可点击。
右上角预留 27px 次数角标或 42px 广告角标,距底座上缘 -5px;广告使用播放符号 + AD,不能只有模糊的加号。两种角标互斥,不遮挡图标与标签。设计稿仅展示“撤销 3 次”和“广告获取提示”的外观,不接入库存、扣次数、广告播放或奖励。实际次数、定价与获取方式待产品确定。 右上角预留 27px 次数角标或 42px 广告角标,距底座上缘 -5px;广告使用播放符号 + AD,不能只有模糊的加号。两种角标互斥,不遮挡图标与标签。设计稿仅展示“撤销 3 次”和“广告获取提示”的外观,不接入库存、扣次数、广告播放或奖励。实际次数、定价与获取方式待产品确定。
@@ -207,8 +207,10 @@ Agent 接入先读 [design/README.md](design/README.md),共用规则见 [desig
| 03 | 积木轨道屋 | 塑胶高光、分层厚度、圆角积木 | [积木轨道屋](design/directions/toy/index.html) | | 03 | 积木轨道屋 | 塑胶高光、分层厚度、圆角积木 | [积木轨道屋](design/directions/toy/index.html) |
| 04 | 动物弯弯镇 | 猫、熊、兔、蛙造型与独立箭头 | [动物弯弯镇](design/directions/animals/index.html) | | 04 | 动物弯弯镇 | 猫、熊、兔、蛙造型与独立箭头 | [动物弯弯镇](design/directions/animals/index.html) |
| 05 | 轻线纸境 | 浅色细轨道、微小格缝、细白边六角与线条箭头 | [轻线纸境](design/directions/paper/index.html) | | 05 | 轻线纸境 | 浅色细轨道、微小格缝、细白边六角与线条箭头 | [轻线纸境](design/directions/paper/index.html) |
| 06 | 路标 | 奶白卡片棋盘、双层轨道、路标棋子、压痕式旋转按钮 | [路标](design/directions/signpost/index.html) |
| 07 | 马卡龙 | 白托盘、带白缝的糖砖格、糖果色棋子与白色粗箭头、果糖色反馈动效,参考 Meowdoku | [马卡龙](design/directions/macaron/index.html) |
在 [设计总览](design/index.html) 并排比较各套画法、切换统一主题,完整编号与 25 种主题见 [方案目录](design/README.md)。最新是第 05 套「轻线纸境」,五套方案均可并列保留。 在 [设计总览](design/index.html) 并排比较各套画法、切换统一主题,完整编号与 25 种主题见 [方案目录](design/README.md)。最新是第 07 套「马卡龙」,七套方案均可并列保留。
在 [统一审核页](design-showcase.html) 切换设计及主题,可同时保留多套、逐套记录意见并导出 JSON。意见保存在当前浏览器。设计稿由 `scripts/build-art-directions.mjs` 生成,颜色及造型规则来自 `src/art-directions.js`、`src/token-art.js`。 在 [统一审核页](design-showcase.html) 切换设计及主题,可同时保留多套、逐套记录意见并导出 JSON。意见保存在当前浏览器。设计稿由 `scripts/build-art-directions.mjs` 生成,颜色及造型规则来自 `src/art-directions.js`、`src/token-art.js`。
+1 -1
View File
@@ -29,7 +29,7 @@ npm run dev
- [千关审核页](http://localhost:4173/labs/campaign-review/index.html):按章看布局,检查制作证据,逐步回放和导出本章总览。 - [千关审核页](http://localhost:4173/labs/campaign-review/index.html):按章看布局,检查制作证据,逐步回放和导出本章总览。
- [花形轨道测试](http://localhost:4173/labs/flower/index.html):双层十二瓣与三重环带编织成花,包含 10 枚棋子的独立可玩实验,详见 [设计说明](docs/flower-study.md)。 - [花形轨道测试](http://localhost:4173/labs/flower/index.html):双层十二瓣与三重环带编织成花,包含 10 枚棋子的独立可玩实验,详见 [设计说明](docs/flower-study.md)。
- [交互设计规范](http://localhost:4173/Design.html):色板、图标、组件状态与动效示例。 - [交互设计规范](http://localhost:4173/Design.html):色板、图标、组件状态与动效示例。
- [设计方案总览](http://localhost:4173/design/index.html):01–05 五套设计、25 种主题、完整设计稿与多选审核入口;最新为「轻线纸境」。[方案目录](design/README.md)记录各套特点与共用规则。 - [设计方案总览](http://localhost:4173/design/index.html):01–07 七套设计、35 种主题、完整设计稿与多选审核入口;最新为「马卡龙」(参考 Meowdoku),主游戏用 `?design=macaron` 查看。[方案目录](design/README.md)记录各套特点与共用规则。
- 修改端口:`PORT=4174 npm run dev`。 - 修改端口:`PORT=4174 npm run dev`。
## 游戏规则 ## 游戏规则
+13
View File
@@ -0,0 +1,13 @@
# 资源圆体子集(Resource Han Rounded)
来源:[CyanoHao/Resource-Han-Rounded](https://github.com/CyanoHao/Resource-Han-Rounded) v0.990,CN 版 Medium 与 Bold,SIL Open Font License 1.1。用户于 2026-09-14 指定,用于第 07 套「马卡龙」的界面文字。
`ResourceHanRoundedCN-Medium.subset.woff2` / `ResourceHanRoundedCN-Bold.subset.woff2` 是按 `macaron-charset.txt` 裁剪的子集(游戏界面、弹窗与 v0.1–v0.5 关卡数据中出现的 1001 个字符,含 ASCII 与常用标点),每个约 170 KB。子集里没有的字符由浏览器按字形回落到 PingFang 等系统字体。
重新生成(fonttools + brotli):
```sh
pyftsubset ResourceHanRoundedCN-Medium.ttf --text-file=macaron-charset.txt --flavor=woff2 --layout-features='*' --no-hinting --desubroutinize --output-file=ResourceHanRoundedCN-Medium.subset.woff2
```
新增大量界面文字或关卡文案后,把新字符加入 `macaron-charset.txt` 再重新裁剪。原生端可直接使用完整 TTF。
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~°±·×÷–—‘’“”…←↑→↓↖↗↘↙○●★☆✓ 、。《》「」『』一七三上下不与世丢两个中丰临为主义之乎乐也习了二于互五些交享亮人仁仅仍从他以们件价任份优会估伴似位低住体余作你使例供依侧保信倒偶储像允充先光克免兔入全六兰共关其具典内再冒冰冲决冷准减几凸出击分切则刚创初判别到制刷刺刻剂前剩力功加动助励包化匹区十千午华单占卡印即压厚原去参又叉及双反发取受变叠口另只可台右叶号各合同名后向否启告周命和咪品响哑哪喜嘉器回因园困围图圆圈土在地场均坊坐块型垫城域基塑境增墨声处备复外多夜大天太央失头奏奖套奶好始姜嫩子字存学它安完定实审家容宽密富察寸对寻导封将小少尚尝就尽尾局层屋展岸峰川巡工左巧差已布带常平年并广庆序库应底度座廊廓延建开式引张弯弹强归当录形彩影往径待得循微心必快态思性总恢悉情惊意感慢懂戏成我或战房所手打托扣扩扫找承把投折报抹担拉拖拥择拼拿持挂指按挑挡挤捉换据排探接控推描提插搜搭撒撞撤播操擦支收改放效教散数整文断新方旅旋无日旧时明星映是显晨普景晰晴暂暖暮曲更替最有朝木未末本札术朱朵机杂李杏束条来松板极构林枚果架柑染柔柜柠查标栗校样核格桃案桌档检棋棕森楚榛槛模橘橙橡檬次欢正此步段每比毛毯气氛水求沙没油沿法波注洁洋派浅测浏浪浮海消润深清渐温渲游湖湾源溪滑滚满漂演激火灯灰灵点烈烟烧热然照熊熟爆片版牛物特状独猜猫玩玫环现玻珀珊理琥瑚瑰璃瓣甜生用由电画畅界留白百的盈益盐盒盘盛目直相看真眼着睛短石砂砖破础硬确碎碰磨示祝离秋种秒秩积称移程空穿突窗立章端笔符第等签简算箭粉粗糖系索紧紫红约纯纷纸线练组细织终经结绕绘给统继续绿编缘缝缤缩置美翼考而耳肩背胶能脑脸腾自至致舍舒舞航船色节芋花芽苔范茶草荧荷莓获萄萤落葡蓝薄藏藕藤蛙蜂蜜螺行衍衔衡补表被装要见观规视览觉角解触言警计认让议记许设证评识试话该详语说请读课谁调负败质贯贴费资赖赠赤赭走起超足跟跨路跳轨转轮软轻载较辅辑输辨边达过运近返还这进远连述迷迹退送选逐途通速造逢遇遍道避邻部都配释里重野量金针钢钮钴铁铅铺销锁错键镇长门闭间闸阔队阴阶阻际降限除险陪陶随隔隙难集雪零雾需露青静靛靠面音韵页顶项顺预领题颜额风飞餐饰饱馈首香马验高鲜鸢麦黄黑默鼠齐龙!(),/:;?
+2 -2
View File
@@ -2,11 +2,11 @@
<html lang="zh-CN"> <html lang="zh-CN">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>HEX TRAILS · 五套设计审核</title><link rel="stylesheet" href="design/showcase.css"><link rel="stylesheet" href="design/notifications.css"><link rel="stylesheet" href="design/art-directions.css"><link rel="stylesheet" href="design/game-tools.css"></head> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>HEX TRAILS · 五套设计审核</title><link rel="stylesheet" href="design/showcase.css"><link rel="stylesheet" href="design/notifications.css"><link rel="stylesheet" href="design/art-directions.css"><link rel="stylesheet" href="design/game-tools.css"></head>
<body> <body>
<header class="masthead"><a href="index.html">HEX TRAILS<span>转转六角</span></a><span>DESIGN REVIEW / 05</span><a class="game-link" id="game-link" href="index.html">进入游戏 ↗</a></header> <header class="masthead"><a href="index.html">HEX TRAILS<span>转转六角</span></a><span>DESIGN REVIEW / 07</span><a class="game-link" id="game-link" href="index.html">进入游戏 ↗</a></header>
<nav class="quick-review" aria-label="快速切换设计与主题"><label>设计 <select id="quick-design"></select></label><label>主题 <select id="quick-theme"></select></label><a href="#direction-picker">多选与审核 ↑</a><a href="#item-study">道具设计 ↓</a></nav> <nav class="quick-review" aria-label="快速切换设计与主题"><label>设计 <select id="quick-design"></select></label><label>主题 <select id="quick-theme"></select></label><a href="#direction-picker">多选与审核 ↑</a><a href="#item-study">道具设计 ↓</a></nav>
<main> <main>
<section class="direction-review" aria-label="设计方案审核"> <section class="direction-review" aria-label="设计方案审核">
<div class="review-heading"><div><span class="eyebrow">ART DIRECTIONS / 5 × 5</span><h1>五种性格,同一段旅程。</h1><p>每套设计都有轻松、进阶、烧脑、挑战和每周挑战五种主题。切换查看,也可以同时保留多套。</p></div><a href="design/index.html">查看 01–05 设计总览 ↗</a></div> <div class="review-heading"><div><span class="eyebrow">ART DIRECTIONS / 7 × 5</span><h1>七种性格,同一段旅程。</h1><p>每套设计都有轻松、进阶、烧脑、挑战和每周挑战五种主题。切换查看,也可以同时保留多套。</p></div><a href="design/index.html">查看 01–07 设计总览 ↗</a></div>
<div id="direction-picker" class="direction-picker"></div> <div id="direction-picker" class="direction-picker"></div>
<div class="review-summary-bar"><p id="review-summary" aria-live="polite"></p><button id="export-review">导出审核记录 ↓</button></div> <div class="review-summary-bar"><p id="review-summary" aria-live="polite"></p><button id="export-review">导出审核记录 ↓</button></div>
<div id="direction-detail" class="direction-detail"></div> <div id="direction-detail" class="direction-detail"></div>
+2 -2
View File
@@ -2,9 +2,9 @@
这是主游戏五套并列设计的入口。先读 [README.md](README.md),再读 [shared.md](shared.md) 和本次指定方案的 `directions/<id>/design.md`。可通过 [manifest.json](manifest.json) 发现全部 ID、规范、配色和预览路径;不必依赖先前会话。 这是主游戏五套并列设计的入口。先读 [README.md](README.md),再读 [shared.md](shared.md) 和本次指定方案的 `directions/<id>/design.md`。可通过 [manifest.json](manifest.json) 发现全部 ID、规范、配色和预览路径;不必依赖先前会话。
- 设计 ID 固定为 `calm`、`vivid`、`toy`、`animals`、`paper`;方案编号为 01–05。每套都有相同的五个主题 ID。不得把设计、主题、关卡版本混成同一个参数。 - 设计 ID 固定为 `calm`、`vivid`、`toy`、`animals`、`paper`、`signpost`、`macaron`;方案编号为 01–07。每套都有相同的五个主题 ID。不得把设计、主题、关卡版本混成同一个参数。
- 使用方案时复用 `src/art-directions.js` 的 `artDirection` / `directionTheme` 和 `src/renderer.js` 的 `drawScene`。样式接入、颜色映射和跨引擎限制见 shared.md。 - 使用方案时复用 `src/art-directions.js` 的 `artDirection` / `directionTheme` 和 `src/renderer.js` 的 `drawScene`。样式接入、颜色映射和跨引擎限制见 shared.md。
- 修改指定方案时,先核对该方案的 design.md。遵循用户已确认的共用规则:通知在步数下方、居中棋盘、大尺寸扁平道具、金色发光星星。`paper` 不画外围色标或棋子编号。 - 修改指定方案时,先核对该方案的 design.md。遵循用户已确认的共用规则:通知在步数下方、居中棋盘、大尺寸扁平道具、金色发光星星。`paper` 不画外围色标或棋子编号。道具带投影只是 `macaron` 一套获准的例外(2026-09-14),不向其他方案放开。
- `README.md`、`shared.md`、本文件及各套 `design.md` 是人工维护的文档源。`manifest.json`、各套 `tokens.json`、预览 HTML 由脚本生成;修改源 JS/CSS 和设计规则后重新构建,不手改生成结果。 - `README.md`、`shared.md`、本文件及各套 `design.md` 是人工维护的文档源。`manifest.json`、各套 `tokens.json`、预览 HTML 由脚本生成;修改源 JS/CSS 和设计规则后重新构建,不手改生成结果。
- 每套仍是可单独使用、可同时保留的设计方向。除非任务明确选择默认方案,不因新增方案而替换 `calm` 默认值或其他审核选择。 - 每套仍是可单独使用、可同时保留的设计方向。除非任务明确选择默认方案,不因新增方案而替换 `calm` 默认值或其他审核选择。
- UI 任务以用户本次授权为边界。仅使用设计不需要改关卡、玩法、碰撞数学、存档或原生工程。不要为文档整理顺便改这些模块。 - UI 任务以用户本次授权为边界。仅使用设计不需要改关卡、玩法、碰撞数学、存档或原生工程。不要为文档整理顺便改这些模块。
+3 -1
View File
@@ -1,6 +1,6 @@
# HEX TRAILS · 设计系统入口 # HEX TRAILS · 设计系统入口
这是给设计审核者和 Agent 共用的主游戏设计入口。当前有 5 套并列方案,每套 5 个主题,共 25 种组合。默认方案是 01「柔和原色」,最新候选是 05「轻线纸境」;可同时保留多套。 这是给设计审核者和 Agent 共用的主游戏设计入口。当前有 7 套并列方案,每套 5 个主题,共 35 种组合。默认方案是 01「柔和原色」,最新候选是 07「马卡龙」;可同时保留多套。
人看 [设计总览](index.html) 与 [可操作审核页](../design-showcase.html)。Agent 从本文、[共用接入约定](shared.md) 和本次指定方案的 design.md 开始;可直接读 [manifest.json](manifest.json) 发现全部文件。根目录 [AGENTS.md](../AGENTS.md) 与本目录 [AGENTS.md](AGENTS.md) 提供路由和维护要求。 人看 [设计总览](index.html) 与 [可操作审核页](../design-showcase.html)。Agent 从本文、[共用接入约定](shared.md) 和本次指定方案的 design.md 开始;可直接读 [manifest.json](manifest.json) 发现全部文件。根目录 [AGENTS.md](../AGENTS.md) 与本目录 [AGENTS.md](AGENTS.md) 提供路由和维护要求。
@@ -23,6 +23,8 @@
| 03 | toy | 积木轨道屋:塑胶积木 | [design.md](directions/toy/design.md) | [tokens.json](directions/toy/tokens.json) | [查看](directions/toy/index.html) | | 03 | toy | 积木轨道屋:塑胶积木 | [design.md](directions/toy/design.md) | [tokens.json](directions/toy/tokens.json) | [查看](directions/toy/index.html) |
| 04 | animals | 动物弯弯镇:动物角色 | [design.md](directions/animals/design.md) | [tokens.json](directions/animals/tokens.json) | [查看](directions/animals/index.html) | | 04 | animals | 动物弯弯镇:动物角色 | [design.md](directions/animals/design.md) | [tokens.json](directions/animals/tokens.json) | [查看](directions/animals/index.html) |
| 05 | paper | 轻线纸境:细线纸面 | [design.md](directions/paper/design.md) | [tokens.json](directions/paper/tokens.json) | [查看](directions/paper/index.html) | | 05 | paper | 轻线纸境:细线纸面 | [design.md](directions/paper/design.md) | [tokens.json](directions/paper/tokens.json) | [查看](directions/paper/index.html) |
| 06 | signpost | 路标:线路图棋盘与压痕控件 | [design.md](directions/signpost/design.md) | [tokens.json](directions/signpost/tokens.json) | [查看](directions/signpost/index.html) |
| 07 | macaron | 马卡龙:白托盘糖砖棋盘,参考 Meowdoku | [design.md](directions/macaron/design.md) | [tokens.json](directions/macaron/tokens.json) | [查看](directions/macaron/index.html) |
设计 ID、主题 ID 和关卡版本各自独立。每套都支持 `lagoon`(轻松)、`apricot`(进阶)、`lavender`(烧脑)、`rose`(挑战)、`midnight`(每周挑战);显示名可以不同,ID 不变。各主题名称、色值与有序色板从 tokens.json 读取。 设计 ID、主题 ID 和关卡版本各自独立。每套都支持 `lagoon`(轻松)、`apricot`(进阶)、`lavender`(烧脑)、`rose`(挑战)、`midnight`(每周挑战);显示名可以不同,ID 不变。各主题名称、色值与有序色板从 tokens.json 读取。
+8 -1
View File
@@ -1,5 +1,5 @@
.direction-review{padding:52px 0 24px}.review-heading{display:flex;align-items:end;justify-content:space-between;gap:30px}.review-heading h1{font-size:clamp(30px,4vw,48px);letter-spacing:-1.5px;margin:14px 0}.review-heading p{max-width:730px;color:#56687A}.review-heading>a{font-size:12px;white-space:nowrap;padding-bottom:22px} .direction-review{padding:52px 0 24px}.review-heading{display:flex;align-items:end;justify-content:space-between;gap:30px}.review-heading h1{font-size:clamp(30px,4vw,48px);letter-spacing:-1.5px;margin:14px 0}.review-heading p{max-width:730px;color:#56687A}.review-heading>a{font-size:12px;white-space:nowrap;padding-bottom:22px}
.direction-picker{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px;margin:28px 0 18px}.direction-card{border:1px solid #273b5020;border-radius:18px;overflow:hidden;background:white}.direction-switch{display:block;background:none;padding:0;width:100%;text-align:left;color:#273B50}.direction-switch canvas{display:block;width:100%;height:auto}.direction-switch[aria-pressed=true]{box-shadow:inset 0 -3px #6652B8}.direction-card:has([aria-pressed=true]){outline:2px solid #6652B8;outline-offset:3px}.direction-card-title{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:14px 12px;font-weight:650;font-size:13px}.direction-card-title small{font-weight:400;font-size:10px;color:#56687A}.keep-design{display:flex;align-items:center;gap:8px;border-top:1px solid #273b5010;padding:12px;font-size:12px;cursor:pointer}.keep-design input{width:17px;height:17px;accent-color:#6652B8}.review-summary-bar{display:flex;align-items:center;justify-content:space-between;gap:20px;font-size:12px}.review-summary-bar p{font-size:12px}.review-summary-bar button,.sheet-link{background:#273B50;color:white;border-radius:10px;padding:12px 16px;font-size:12px;display:inline-block}.direction-detail{margin-top:24px;border-top:1px solid #273b5020;border-bottom:1px solid #273b5020;padding:30px 0;display:grid;grid-template-columns:1.25fr 1fr;gap:60px}.direction-detail h2{font-size:28px;margin:10px 0}.direction-detail p,.direction-detail li{font-size:13px;line-height:1.9}.direction-detail ul{padding-left:18px;color:#56687A;margin-bottom:22px}.review-note{font-size:13px;display:flex;flex-direction:column;gap:12px;padding-top:4px}.review-note textarea{resize:vertical;width:100%;min-height:110px;border:1px solid #273b5030;border-radius:12px;padding:14px;background:white;font:inherit;color:#273B50}.review-note small{font-size:11px;color:#56687A}.intro{padding-top:30px}.intro h1{font-size:34px}.direction-review~.intro .intro-note{max-width:520px} .direction-picker{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:16px;margin:28px 0 18px}.direction-card{border:1px solid #273b5020;border-radius:18px;overflow:hidden;background:white}.direction-switch{display:block;background:none;padding:0;width:100%;text-align:left;color:#273B50}.direction-switch canvas{display:block;width:100%;height:auto}.direction-switch[aria-pressed=true]{box-shadow:inset 0 -3px #6652B8}.direction-card:has([aria-pressed=true]){outline:2px solid #6652B8;outline-offset:3px}.direction-card-title{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:14px 12px;font-weight:650;font-size:13px}.direction-card-title small{font-weight:400;font-size:10px;color:#56687A}.keep-design{display:flex;align-items:center;gap:8px;border-top:1px solid #273b5010;padding:12px;font-size:12px;cursor:pointer}.keep-design input{width:17px;height:17px;accent-color:#6652B8}.review-summary-bar{display:flex;align-items:center;justify-content:space-between;gap:20px;font-size:12px}.review-summary-bar p{font-size:12px}.review-summary-bar button,.sheet-link{background:#273B50;color:white;border-radius:10px;padding:12px 16px;font-size:12px;display:inline-block}.direction-detail{margin-top:24px;border-top:1px solid #273b5020;border-bottom:1px solid #273b5020;padding:30px 0;display:grid;grid-template-columns:1.25fr 1fr;gap:60px}.direction-detail h2{font-size:28px;margin:10px 0}.direction-detail p,.direction-detail li{font-size:13px;line-height:1.9}.direction-detail ul{padding-left:18px;color:#56687A;margin-bottom:22px}.review-note{font-size:13px;display:flex;flex-direction:column;gap:12px;padding-top:4px}.review-note textarea{resize:vertical;width:100%;min-height:110px;border:1px solid #273b5030;border-radius:12px;padding:14px;background:white;font:inherit;color:#273B50}.review-note small{font-size:11px;color:#56687A}.intro{padding-top:30px}.intro h1{font-size:34px}.direction-review~.intro .intro-note{max-width:520px}
body[data-design=vivid] .phone{border:3px solid #30264C;box-shadow:8px 8px #30264C;border-radius:18px}body[data-design=vivid] .icon-button{background:#4A24E8;border:2px solid #30264C;border-radius:8px;box-shadow:3px 3px #30264C}body[data-design=vivid] .phone-top strong{font-weight:900;letter-spacing:-.6px}body[data-design=vivid] .game-notice{border:2px solid #30264C;border-radius:8px;box-shadow:3px 3px #30264C} body[data-design=vivid] .phone{border:3px solid #30264C;box-shadow:8px 8px #30264C;border-radius:18px}body[data-design=vivid] .icon-button{background:#4A24E8;border:2px solid #30264C;border-radius:8px;box-shadow:3px 3px #30264C}body[data-design=vivid] .phone-top strong{font-weight:900;letter-spacing:-.6px}body[data-design=vivid] .game-notice{border:2px solid #30264C;border-radius:8px;box-shadow:3px 3px #30264C}
body[data-design=toy] .phone{border:8px solid #F9EDCF;border-radius:42px;box-shadow:0 12px 0 #B5A68D,0 20px 30px #273b501f,inset 0 3px 3px #FFFFFF90}body[data-design=toy] .icon-button{background:#4279B7;border-radius:15px;box-shadow:0 4px #244F80,inset 0 2px #82ACD2}body[data-design=toy] .game-notice{background:#FFF9EB;border:2px solid #D8CBB0;box-shadow:0 3px #C4B598} body[data-design=toy] .phone{border:8px solid #F9EDCF;border-radius:42px;box-shadow:0 12px 0 #B5A68D,0 20px 30px #273b501f,inset 0 3px 3px #FFFFFF90}body[data-design=toy] .icon-button{background:#4279B7;border-radius:15px;box-shadow:0 4px #244F80,inset 0 2px #82ACD2}body[data-design=toy] .game-notice{background:#FFF9EB;border:2px solid #D8CBB0;box-shadow:0 3px #C4B598}
body[data-design=animals] .phone{border:3px solid #718763;border-radius:40px 40px 28px 28px;box-shadow:0 6px 0 #71876330}body[data-design=animals] .icon-button{background:#54795C;border-radius:16px 16px 12px 12px;box-shadow:0 3px #36523C}body[data-design=animals] .game-notice{background:#FFFCED;border:1px solid #71876380;border-radius:18px}.phone canvas{min-width:0} body[data-design=animals] .phone{border:3px solid #718763;border-radius:40px 40px 28px 28px;box-shadow:0 6px 0 #71876330}body[data-design=animals] .icon-button{background:#54795C;border-radius:16px 16px 12px 12px;box-shadow:0 3px #36523C}body[data-design=animals] .game-notice{background:#FFFCED;border:1px solid #71876380;border-radius:18px}.phone canvas{min-width:0}
@@ -13,6 +13,13 @@ body[data-design=animals]:not(.editing) .game-shell .game-icon{filter:sepia(.25)
.quick-review{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:22px;padding:10px 22px;background:#F7F6F2F5;border-bottom:1px solid #273b501c;backdrop-filter:blur(12px);font-size:12px}.quick-review label{display:flex;align-items:center;gap:9px}.quick-review select{font:inherit;color:#273B50;background:white;border:1px solid #273b5033;border-radius:8px;min-height:36px;padding:5px 10px}.quick-review a{font-size:11px}.direction-picker,.phone{scroll-margin-top:80px} .quick-review{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:22px;padding:10px 22px;background:#F7F6F2F5;border-bottom:1px solid #273b501c;backdrop-filter:blur(12px);font-size:12px}.quick-review label{display:flex;align-items:center;gap:9px}.quick-review select{font:inherit;color:#273B50;background:white;border:1px solid #273b5033;border-radius:8px;min-height:36px;padding:5px 10px}.quick-review a{font-size:11px}.direction-picker,.phone{scroll-margin-top:80px}
@media(max-width:500px){.quick-review{gap:10px;padding:8px 10px}.quick-review label{gap:5px}.quick-review select{max-width:130px;font-size:11px}.quick-review a{font-size:10px}.review-heading h1{font-size:28px}} @media(max-width:500px){.quick-review{gap:10px;padding:8px 10px}.quick-review label{gap:5px}.quick-review select{max-width:130px;font-size:11px}.quick-review a{font-size:10px}.review-heading h1{font-size:28px}}
/* 07 Macaron: white phone chrome and cards on the cream world; controls keep the game-tools rules. */
body[data-design=macaron] .phone{border:1px solid #EAD9DE;border-radius:34px;box-shadow:0 20px 40px rgba(110,70,82,.12)}
body[data-design=macaron] .phone-top strong{color:#5A3A44}
body[data-design=macaron] .moves{color:#5A3A44}
body[data-design=macaron] .rotations button{color:#7A5560}
.sheet-page[data-design=macaron] .sample-modal{border-radius:28px;box-shadow:0 10px 30px rgba(110,70,82,.12);color:#5A3A44}
.sheet-page[data-design=macaron] .sample-controls button{border-radius:999px;box-shadow:0 4px 0 #C96A0E}
/* Paper Routes carries the light, flat drawing language of the variants lab. */ /* Paper Routes carries the light, flat drawing language of the variants lab. */
body[data-design=paper] .phone{border:1px solid #CBD7DD;border-radius:28px;box-shadow:none} body[data-design=paper] .phone{border:1px solid #CBD7DD;border-radius:28px;box-shadow:none}
body[data-design=paper] .icon-button{background:#607B90;border:1px solid #FFFFFFB8;border-radius:12px;box-shadow:none} body[data-design=paper] .icon-button{background:#607B90;border:1px solid #FFFFFFB8;border-radius:12px;box-shadow:none}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=macaron/index.html"><title>马卡龙 · 设计稿已迁移</title></head><body><p>设计稿已整理到独立目录:<a href="macaron/index.html">07 · 马卡龙</a></p></body></html>
+5
View File
@@ -0,0 +1,5 @@
# 07 · 马卡龙
本文件为旧入口。完整、人工维护的 Agent 规范已迁移到 [macaron/design.md](macaron/design.md)。
[设计稿](macaron/index.html) · [配色数据](macaron/tokens.json) · [Agent 接入说明](../README.md)
+72
View File
@@ -0,0 +1,72 @@
# 07 · 马卡龙
设计 ID:`macaron` · 渲染风格:`macaron` · 英文名:MACARON。2026-09-14 参考 Meowdoku(喵喵数独)的设计语言制作,可与其他方案同时保留。参考分析与实机对照见 [docs/art-proposal-macaron.html](../../../docs/art-proposal-macaron.html)。
[Agent 接入约定](../../shared.md) · [配色数据](tokens.json) · [完整设计稿](index.html) · [试玩与审核](../../../design-showcase.html?design=macaron)
## 设计目标
从 Meowdoku 借来的是一套"奶油世界 + 白卡片 + 糖果色块 + 白色粗记号"的语言:奶油色世界上托一张白色软托盘,六角格像带白缝的软糖砖,藕紫色轨道压在糖砖上;棋子是糖果色圆角六角,白色贴纸边,十二色统一粗圆头白箭头。所有状态用颜色和弹跳表达,不用描边和阴影:路线点亮成棋子自己的浅色,碰撞处橘红打叉,出场从左上角一波弹开,离场撒星。文字是藕紫褐色,行动色只有一种橙。
## 棋盘与棋子怎么画
以格半径 s 为单位,复用 [renderer.js](../../../src/renderer.js) 的 macaron 分支和 [token-art.js](../../../src/token-art.js) 的 macaron 分支。圆角六角由 [tile-shape.js](../../../src/tile-shape.js) 的 `roundedHex(x, y, r, 0.16)` 生成。
| 部件 | 当前实现 |
| --- | --- |
| 画布边距 | `layout.pad = 0.3`:布局时每一侧多留 0.3 格半径;同时画布向左右各多伸 8px 到外壳内边距里(`.canvas-wrap` 负外边距),所以棋盘尺寸与其他方案相同,出口处的冲出与消融仍落在画布内 |
| 托盘 | 全部格面外扩 0.34s 后取凸包,转角圆化半径 0.9s,纯色 `tray`(白),随棋盘旋转 |
| 托盘阴影 | 两层不透明色阶:外层再放大 0.06s、下移 0.20s 用 `shadowSoft`;内层下移 0.10s 用 `shadow`。偏移在屏幕坐标里施加,旋转时保持向下 |
| 糖砖(格面) | 圆角六角,半径 0.90s,圆角 0.16;格与格之间是 0.17s 的白缝,不画格线 |
| 环带色 | 从棋盘中心格向外按六角距离分环,三色循环 `rings[d % 3]`;只表达位置,旋转后不变 |
| 轨道 | `track` 藕紫褐(每个世界一档),单层,宽 clamp(0.11s, 2.2, 6.5),圆头圆接;跨过白缝连续画,路线不断开;只有板边端点内收到 0.90s − 轨宽/√3 |
| 棋子 | 圆角六角,半径 0.90s,正好盖满糖砖,圆角 0.16,纯色面;白色贴纸边宽 0.10r,与白缝连成一体。轨道从棋子底下钻过:白缝里的一小段一直画到白边为止,和空砖之间的画法一致,所以看得出哪几条轨道通向这枚棋子;不再画底座 |
| 箭头 | 白色线条:杆从 −0.34r 到 0.30r,头两笔到 ±0.30r;线宽 0.20r,圆头,十二色统一 |
| 路线点亮 | 预览或行进中路线经过的糖砖改用棋子色调白 80%(行进中 84%);被挡时用 `blush` 橘奶色 |
| 预览路线 | 棋子本色一根粗线 1.15 × 轨宽,画在轨道上、棋子下;被挡只画到接触点,末端橘红叉 |
| 碰撞 | 接触时被撞格改 `blush`,接触点画橘红 `blocked` 叉,大小随 impact 变化;回弹沿用共用碰撞动画 |
| 提示 | 两层实心圆角六角光晕:`hintGlow` 1.02s、`hint` 0.94s,露出棋子外一圈蜂蜜黄 |
| 出场 | 新棋盘时糖砖、轨道、棋子按左上到右下的顺序缩放弹入:每格延迟 = 归一化位置 × 0.55,各自 0.45 段,ease-out 回弹 5%,总长 720ms |
| 离场 | 滑行沿用共用时序;到达出口后是 640ms 的收束(`exitDuration` 把窗口从共用的 180ms 放宽):前 45% 棋子沿出口方向减速冲出 0.55s(三次 ease-out),大半个身体越过托盘边缘;从 15% 起实心面、白边在 20% 内淡掉,箭头在 25% 内淡掉;面被一层同色圆点阵接管(间距 0.17s、半径 0.115s、六角排列、内缩到 0.82r),圆点跟着棋子走,并从外圈向中心依次化掉:开始时刻 = 0.16 + 0.38 × (1 − 到边缘的比例) + 0.16 × 噪声,各自用 0.28 段缩小到 0、颜色向白调 45%、透明度降到 40%、沿固定随机方向漂 0.14s 并上浮 0.10s。没有尾迹、碎片和飞出的粒子 |
| 计数 | 棋子离场后 `.moves-bubble` 弹一次(1 → 1.18 → 1,420ms) |
| 通关庆祝 | 最后一枚棋子离场后先在棋盘上放 720ms 的清空涟漪(`state.celebrate`):糖砖按到中心格的环数依次鼓起 8% 并向白调亮 35% 再落回,每环延迟 0.07、各自 0.45 段的正弦脉冲;轨道不随之缩放;结束后才淡入结算 |
不使用棋子图集,不使用滤镜调色。全部造型由多边形、折线与圆组成;阴影是两层不透明多边形,不是模糊。
## 五种主题
| 主题 ID | 阶段 | 名称 | 用色方向 |
| --- | --- | --- | --- |
| lagoon | 轻松 | 奶油 | 奶油底,蜜桃奶/奶黄/薄荷奶三环,草莓、蓝莓、抹茶领色 |
| apricot | 进阶 | 蜜桃 | 蜜桃奶油底,蜜柑与海盐蓝领色 |
| lavender | 烧脑 | 香芋 | 香芋奶油底,香芋紫与玫瑰领色 |
| rose | 挑战 | 草莓牛奶 | 草莓牛奶底,玫瑰与抹茶对照 |
| midnight | 每周挑战 | 可可夜 | 可可色底,白托盘像被灯照亮的甜品盘 |
完整色值、环带色、托盘与阴影色、每主题 4/7/9/12 色有序 palette 见 tokens.json 与 [art-directions.js](../../../src/art-directions.js)。场景文字用藕紫褐(可可夜用奶白),对世界色 5.5 : 1 以上;十二色白箭头最低 3.30 : 1;轨道对三种糖砖最低 3.28 : 1(奶油世界)。
主游戏中本方案的主题按旅程切换:五个世界平均铺在整条主线上,最后一段为可可夜;`?theme=` 参数仍可强制指定。
## 控件与边界
- 字体:资源圆体 Resource Han Rounded(用户指定,SIL OFL),Medium 500 与 Bold 700 两档子集在 [assets/fonts](../../../assets/fonts/README.md),`@font-face` 写在 game-tools.css 的 macaron 段;其后回落 `ui-rounded`、Arial Rounded、Nunito、PingFang。界面里 600 以上的字重落到 Bold,400–500 落到 Medium。子集之外的字符按字形回落到系统字体,新增文案要补进字符表。
- 顶部选关、设置:白色圆底加柔和投影,图标通过遮罩着色为深藕紫;不用滤镜。
- 关卡号与待解计数:两列并排放在两枚圆钮之间,小标签在上(关卡 / 待解,淡藕紫 12px),大数字在下(26px 粗体深藕紫);由 `direction.hud` 提供标签,app.js 生成;数字在棋子离场后弹一次。教学关显示 入门 N/3。
- 通知:白色气泡,顶部小尾巴指向计数胶囊,前置一枚橙点;位置沿用 shared.md(步数下方)。
- 旋转按钮:无底座,图标 60px 用世界色对应的浅藕紫着色,标签 12px 藕紫;位置由 [app.js](../../../src/app.js) 的 `placeRotation` 按棋盘几何计算(`layout.rotation = 'under-board'`,`layout.rim = 0.40`):取下方斜边中点,向下作垂线到道具上缘,按钮中心放在垂线中点。旋转不占独立布局行,与 06 相同,是与 shared.md 的一处出入。
- 撤销、重来、提示:参考作品的白色圆钮。白底 64px、柔和投影、无描边;图标通过图集遮罩着色为海盐蓝 #4A91D4 / 玫瑰 #D06E93 / 蜂蜜褐 #C98A0E;标签藕紫;禁用 45% 透明。这是与 shared.md「道具无阴影」的一处有意出入,2026-09-14 用户确认只允许本方案使用,不向其他方案放开。
- 结算:参考作品的深色庆祝画面,而且是全屏覆盖层:`<dialog>` 铺满整个视口(inset 0、无最大宽高、无圆角、无卡片),320ms 淡入,遮罩 rgba(40,26,32,.86) 加模糊;内容居中,奶白发光标题 25px,副标题浅奶色,金色发光星星后有 640px 缓慢旋转的奶黄射线和一次糖果色纸屑,全部铺在整屏上不被裁切;主按钮是橙色胶囊 `#E07416`(白字 3.1 : 1)底边 4px 深橙,次按钮是半透明奶白胶囊。失败画面用同一覆盖层。
- 选关与设置:白色圆角卡片弹入(0.86 → 1,380ms 回弹),顶部一条蜜桃色标题带,右上角白色圆形关闭钮;当前关橙色胶囊,普通关奶油方块,完成关薄荷奶。
- 棋盘居中、金色奖励继承 shared.md。
## 验收与接入
使用 `artDirection('macaron')` 和 `directionTheme(direction, themeId, colorCount)`;主游戏 `?design=macaron`。
- 检查五个世界的托盘、阴影方向与环带色;可可夜下托盘保持奶白。
- 检查 37 / 61 / 91 格下白缝与轨道宽度:91 格时白缝约 3px、轨道 2.2px,箭头仍可读。
- 检查出场动画在换关、重来、教学三处都播放一次;旋转、撤销时不重播;清空涟漪只播一次且全屏结算在它之后淡入,射线与纸屑不被任何盒子裁切。
- 检查棋子砖面上没有轨道露出,白缝里通向棋子的轨道段可见,空格之间的轨道连续不断;提示路线连续画过白缝。
- 检查路线点亮只覆盖路线经过的格;被挡路线在接触点结束并打叉。
- 检查左右两侧出口的消融完整留在画布内,没有被画布边裁掉;`prefers-reduced-motion` 下取消出场、消融、庆祝与计数弹跳。
- 原生端需实现两层不透明阴影、圆角六角与遮罩着色;尚未完成原生实机验收。
File diff suppressed because one or more lines are too long
+469
View File
@@ -0,0 +1,469 @@
{
"schemaVersion": 1,
"generated": true,
"generatedBy": "scripts/build-art-directions.mjs",
"pathBase": "repository-root",
"designId": "macaron",
"artStyle": "macaron",
"sources": {
"directions": "src/art-directions.js",
"baseTokens": "src/design-tokens.js",
"renderer": "src/renderer.js",
"tokenDrawing": "src/token-art.js",
"componentStyles": "design/art-directions.css",
"itemStyles": "design/game-tools.css"
},
"accent": "#E07416",
"documentBackground": "#FBF6F0",
"sharedSemanticColors": {
"background": "#A8BECF",
"board": "#F2EEE5",
"boardGrid": "#89867D",
"track": "#435F78",
"trackHalo": "#F2EEE5",
"surface": "#F7F6F2",
"textPrimary": "#273B50",
"textSecondary": "#314A5F",
"primary": "#6652B8",
"onPrimary": "#FFFFFF",
"secondary": "#E4EAF0",
"utility": "#52697E",
"onUtility": "#FFFFFF",
"selection": "#DFD9F3",
"onSelection": "#3F327A",
"disabled": "#CBD4DD",
"onDisabled": "#526579",
"input": "#FFFFFF",
"reward": "#B9760C",
"warning": "#A44825",
"warningSurface": "#F9E3D2",
"scrim": "#273B507A",
"focus": "#3F327A",
"tileBlue": "#2392FD",
"tilePink": "#FC3E80",
"tileYellow": "#FDBC28",
"tilePurple": "#874FFD",
"arrowLight": "#FFFFFF",
"arrowDark": "#273B50"
},
"assets": {
"tileAtlas": null,
"uiIconAtlas": "assets/ui-icons-generated.png"
},
"pigments": [
{
"index": 0,
"name": "草莓",
"color": "#EE5398",
"arrow": "#FFFFFF"
},
{
"index": 1,
"name": "蜜柑",
"color": "#E5680C",
"arrow": "#FFFFFF"
},
{
"index": 2,
"name": "蜂蜜",
"color": "#AB8716",
"arrow": "#FFFFFF"
},
{
"index": 3,
"name": "抹茶",
"color": "#4C9E5A",
"arrow": "#FFFFFF"
},
{
"index": 4,
"name": "薄荷",
"color": "#369C94",
"arrow": "#FFFFFF"
},
{
"index": 5,
"name": "蓝莓",
"color": "#578BF0",
"arrow": "#FFFFFF"
},
{
"index": 6,
"name": "香芋",
"color": "#937DE4",
"arrow": "#FFFFFF"
},
{
"index": 7,
"name": "玫瑰",
"color": "#D06E93",
"arrow": "#FFFFFF"
},
{
"index": 8,
"name": "可可",
"color": "#B5806A",
"arrow": "#FFFFFF"
},
{
"index": 9,
"name": "海盐",
"color": "#4A91D4",
"arrow": "#FFFFFF"
},
{
"index": 10,
"name": "葡萄",
"color": "#8C68CC",
"arrow": "#FFFFFF"
},
{
"index": 11,
"name": "洋李",
"color": "#C56AC4",
"arrow": "#FFFFFF"
}
],
"themes": [
{
"id": "lagoon",
"label": "轻松",
"name": "奶油",
"background": "#F5EFE7",
"ink": "#7A5560",
"materials": {
"board": "#FADBCB",
"boardGrid": "#FFFFFF",
"track": "#96707B",
"trackHalo": "#FFFFFF"
},
"anchorPalette": [
0,
5,
3,
2,
6,
1,
4
],
"palettes": {
"4": [
0,
5,
3,
2
],
"7": [
0,
5,
3,
2,
6,
1,
4
],
"9": [
0,
5,
3,
2,
6,
1,
4,
7,
8
],
"12": [
0,
5,
3,
2,
6,
1,
4,
7,
8,
9,
10,
11
]
},
"contrast": {
"sceneText": 5.577670453960404,
"trackOnBoard": 3.277177835431525
}
},
{
"id": "apricot",
"label": "进阶",
"name": "蜜桃",
"background": "#FBE6DA",
"ink": "#7C4E52",
"materials": {
"board": "#FDE3D3",
"boardGrid": "#FFFFFF",
"track": "#976A66",
"trackHalo": "#FFFFFF"
},
"anchorPalette": [
1,
9,
0,
4,
2,
10,
3
],
"palettes": {
"4": [
1,
9,
0,
4
],
"7": [
1,
9,
0,
4,
2,
10,
3
],
"9": [
1,
9,
0,
4,
2,
10,
3,
5,
6
],
"12": [
1,
9,
0,
4,
2,
10,
3,
5,
6,
7,
8,
11
]
},
"contrast": {
"sceneText": 5.681057760459171,
"trackOnBoard": 3.7433859071275655
}
},
{
"id": "lavender",
"label": "烧脑",
"name": "香芋",
"background": "#EEE8F6",
"ink": "#5F4E78",
"materials": {
"board": "#E9E0F6",
"boardGrid": "#FFFFFF",
"track": "#78678F",
"trackHalo": "#FFFFFF"
},
"anchorPalette": [
6,
7,
4,
2,
11,
5,
3
],
"palettes": {
"4": [
6,
7,
4,
2
],
"7": [
6,
7,
4,
2,
11,
5,
3
],
"9": [
6,
7,
4,
2,
11,
5,
3,
0,
1
],
"12": [
6,
7,
4,
2,
11,
5,
3,
0,
1,
8,
9,
10
]
},
"contrast": {
"sceneText": 6.148741738606406,
"trackOnBoard": 3.979775627465162
}
},
{
"id": "rose",
"label": "挑战",
"name": "草莓牛奶",
"background": "#F9E2E8",
"ink": "#7B4658",
"materials": {
"board": "#FBDDE5",
"boardGrid": "#FFFFFF",
"track": "#966076",
"trackHalo": "#FFFFFF"
},
"anchorPalette": [
7,
3,
5,
2,
11,
8,
1
],
"palettes": {
"4": [
7,
3,
5,
2
],
"7": [
7,
3,
5,
2,
11,
8,
1
],
"9": [
7,
3,
5,
2,
11,
8,
1,
0,
4
],
"12": [
7,
3,
5,
2,
11,
8,
1,
0,
4,
6,
9,
10
]
},
"contrast": {
"sceneText": 5.970867897749838,
"trackOnBoard": 3.917201236136076
}
},
{
"id": "midnight",
"label": "每周挑战",
"name": "可可夜",
"background": "#3E2E35",
"ink": "#FBEFE6",
"materials": {
"board": "#F9E3D6",
"boardGrid": "#FFFFFF",
"track": "#8A6370",
"trackHalo": "#FFFFFF"
},
"anchorPalette": [
4,
0,
2,
6,
1,
9,
3
],
"palettes": {
"4": [
4,
0,
2,
6
],
"7": [
4,
0,
2,
6,
1,
9,
3
],
"9": [
4,
0,
2,
6,
1,
9,
3,
5,
7
],
"12": [
4,
0,
2,
6,
1,
9,
3,
5,
7,
8,
10,
11
]
},
"contrast": {
"sceneText": 11.287619453403153,
"trackOnBoard": 4.143716175864876
}
}
]
}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=signpost/index.html"><title>路标 · 设计稿已迁移</title></head><body><p>设计稿已整理到独立目录:<a href="signpost/index.html">06 · 路标</a></p></body></html>
+5
View File
@@ -0,0 +1,5 @@
# 06 · 路标
本文件为旧入口。完整、人工维护的 Agent 规范已迁移到 [signpost/design.md](signpost/design.md)。
[设计稿](signpost/index.html) · [配色数据](signpost/tokens.json) · [Agent 接入说明](../README.md)
+59
View File
@@ -0,0 +1,59 @@
# 06 · 路标
设计 ID:`signpost` · 渲染风格:`signpost` · 英文名:SIGNPOST。2026-09-14 由美术评审后的设计提案接入,可与其他方案同时保留。提案与实机对照见 [docs/art-proposal-signpost.html](../../../docs/art-proposal-signpost.html)。
[Agent 接入约定](../../shared.md) · [配色数据](tokens.json) · [完整设计稿](index.html) · [试玩与审核](../../../design-showcase.html?design=signpost)
## 设计目标
棋盘是一张线路图:奶白卡片托在世界色上,带一圈边框和一层向下偏移的平面底板;浅色路基先铺,墨蓝钢轨再压上去,端点在板边收口。棋子是路标:内缩露出脚下端口,一圈细描边,十二色统一白箭头。控件退到纸面里,一眼看过去重心只在棋盘。
## 棋盘与棋子怎么画
以格半径 s 为单位,复用 [renderer.js](../../../src/renderer.js) 的 signpost 分支和 [token-art.js](../../../src/token-art.js) 的 signpost 分支。
| 部件 | 当前实现 |
| --- | --- |
| 底板 | 全部格面放大 s + 0.2 + 边框宽,向下偏移 0.12s,纯色 `base`;偏移在屏幕坐标里施加,旋转时保持向下 |
| 边框 | 同样放大的格面,纯色 `rim`,内部被格面覆盖只剩外缘;宽 max(1.5, 0.06s) |
| 格面 | 正六角 s + 0.2,各主题奶白 `board` |
| 格线 | max(0.6, 0.02s),`boardGrid`,约 1.14 : 1,只在旋转时对位 |
| 路基 | `trackHalo`,宽 clamp(0.30s, 5, 18) |
| 钢轨 | `track` #3A5068,宽 clamp(0.105s, 2.5, 7),圆头圆接;板边端点按路基宽内收,不外伸 |
| 棋子 | 圆角六角,半径 0.90s,纯色面,描边 #2E4256 38%、宽 max(1.5, 0.05s) |
| 箭头 | 白色七点形,尺度 0.66 × 棋子半径,十二色统一 |
| 预览路线 | 画在棋子之上:光晕 1.05 × 路基宽 + 主线 1.5 × 钢轨宽;可出 #2F5FBF / #C9D7F3,被挡 #C4432F / #F3D3CB,末端小叉 |
| 提示环 | 单环 #D9A227,半径 1.1s,宽 max(2.5, 0.08s) |
不使用棋子图集,不使用滤镜调色。全部造型由多边形、折线与圆组成。
## 五种主题
| 主题 ID | 阶段 | 名称 | 用色方向 |
| --- | --- | --- | --- |
| lagoon | 轻松 | 晨雾 | 蓝灰世界色,靛蓝、松石与琥珀领色 |
| apricot | 进阶 | 杏仁 | 暖砂世界色,朱砂与靛蓝领色 |
| lavender | 烧脑 | 苔原 | 灰绿世界色,紫藤与玫红提亮 |
| rose | 挑战 | 暮砂 | 玫瑰灰世界色,玫红与靛蓝对照 |
| midnight | 每周挑战 | 夜航 | 深蓝灰世界色,奶白卡片像被灯照亮的图 |
完整色值、边框与底板色、每主题 4/7/9/12 色有序 palette 见 tokens.json 与 [art-directions.js](../../../src/art-directions.js)。世界色压低明度,棋盘对世界色 1.50–1.62 : 1,边界靠边框与底板而不是色相差;场景文字对世界色 7 : 1 以上;十二色白箭头最低 4.48 : 1。
主游戏中本方案的主题按旅程切换:五个世界平均铺在整条主线上,最后一段为夜航;`?theme=` 参数仍可强制指定。
## 控件与边界
- 顶部选关、设置:底板只比世界色深一档(`--signpost-plate`),图标用场景文字色;图标通过遮罩着色,不用滤镜。
- 旋转按钮:无底座,图标 64px,用世界色深一档着色,上 1px 暗、下 1px 亮形成压痕;标签 12px 同色系。位置由 [app.js](../../../src/app.js) 的 `placeRotation` 按棋盘几何计算:取下方斜边中点(棋盘轮廓宽 25% / 75%、高 87.5%),向下作垂线到道具上缘,按钮中心放在垂线中点。旋转不再占独立布局行,这是与 shared.md 的一处出入。
- 撤销、重来、提示:沿用原版蓝、紫、金圆底与白边;标签用场景文字色。
- 通知位置、棋盘居中、金色奖励继承 shared.md。
## 验收与接入
使用 `artDirection('signpost')` 和 `directionTheme(direction, themeId, colorCount)`;主游戏 `?design=signpost`。
- 检查五个世界的棋盘边框、底板与格线;夜航下棋盘保持奶白。
- 检查 37 / 61 / 91 格下钢轨宽度上限与棋子描边,箭头在 19px 格半径可读。
- 检查旋转按钮落点:斜边中点与道具上缘的中点;换关、旋转、窗口尺寸变化后位置稳定。
- 检查提示路线画在棋子之上、被挡路线只到接触点。
- 原生端需实现两次偏移绘制的压痕与白色精灵着色;尚未完成原生实机验收。
File diff suppressed because one or more lines are too long
+469
View File
@@ -0,0 +1,469 @@
{
"schemaVersion": 1,
"generated": true,
"generatedBy": "scripts/build-art-directions.mjs",
"pathBase": "repository-root",
"designId": "signpost",
"artStyle": "signpost",
"sources": {
"directions": "src/art-directions.js",
"baseTokens": "src/design-tokens.js",
"renderer": "src/renderer.js",
"tokenDrawing": "src/token-art.js",
"componentStyles": "design/art-directions.css",
"itemStyles": "design/game-tools.css"
},
"accent": "#2F5FBF",
"documentBackground": "#F6F2E9",
"sharedSemanticColors": {
"background": "#A8BECF",
"board": "#F2EEE5",
"boardGrid": "#89867D",
"track": "#435F78",
"trackHalo": "#F2EEE5",
"surface": "#F7F6F2",
"textPrimary": "#273B50",
"textSecondary": "#314A5F",
"primary": "#6652B8",
"onPrimary": "#FFFFFF",
"secondary": "#E4EAF0",
"utility": "#52697E",
"onUtility": "#FFFFFF",
"selection": "#DFD9F3",
"onSelection": "#3F327A",
"disabled": "#CBD4DD",
"onDisabled": "#526579",
"input": "#FFFFFF",
"reward": "#B9760C",
"warning": "#A44825",
"warningSurface": "#F9E3D2",
"scrim": "#273B507A",
"focus": "#3F327A",
"tileBlue": "#2392FD",
"tilePink": "#FC3E80",
"tileYellow": "#FDBC28",
"tilePurple": "#874FFD",
"arrowLight": "#FFFFFF",
"arrowDark": "#273B50"
},
"assets": {
"tileAtlas": null,
"uiIconAtlas": "assets/ui-icons-generated.png"
},
"pigments": [
{
"index": 0,
"name": "靛蓝",
"color": "#2F5FBF",
"arrow": "#FFFFFF"
},
{
"index": 1,
"name": "朱砂",
"color": "#C4432F",
"arrow": "#FFFFFF"
},
{
"index": 2,
"name": "松石",
"color": "#1C8378",
"arrow": "#FFFFFF"
},
{
"index": 3,
"name": "紫藤",
"color": "#7A4EB8",
"arrow": "#FFFFFF"
},
{
"index": 4,
"name": "苔绿",
"color": "#4A8235",
"arrow": "#FFFFFF"
},
{
"index": 5,
"name": "琥珀",
"color": "#A8690C",
"arrow": "#FFFFFF"
},
{
"index": 6,
"name": "玫红",
"color": "#BF3A6B",
"arrow": "#FFFFFF"
},
{
"index": 7,
"name": "钢蓝",
"color": "#4A6B8A",
"arrow": "#FFFFFF"
},
{
"index": 8,
"name": "赤陶",
"color": "#B0572F",
"arrow": "#FFFFFF"
},
{
"index": 9,
"name": "墨绿",
"color": "#357358",
"arrow": "#FFFFFF"
},
{
"index": 10,
"name": "藕紫",
"color": "#8A5C92",
"arrow": "#FFFFFF"
},
{
"index": 11,
"name": "铁灰",
"color": "#5A6D7C",
"arrow": "#FFFFFF"
}
],
"themes": [
{
"id": "lagoon",
"label": "轻松",
"name": "晨雾",
"background": "#B7CBD3",
"ink": "#12202A",
"materials": {
"board": "#F5F2EA",
"boardGrid": "#E9E3D6",
"track": "#3A5068",
"trackHalo": "#E2DBCC"
},
"anchorPalette": [
0,
2,
5,
3,
1,
8,
6
],
"palettes": {
"4": [
0,
2,
5,
3
],
"7": [
0,
2,
5,
3,
1,
8,
6
],
"9": [
0,
2,
5,
3,
1,
8,
6,
4,
7
],
"12": [
0,
2,
5,
3,
1,
8,
6,
4,
7,
9,
10,
11
]
},
"contrast": {
"sceneText": 9.872709985958306,
"trackOnBoard": 7.427567140854274
}
},
{
"id": "apricot",
"label": "进阶",
"name": "杏仁",
"background": "#DBC4A6",
"ink": "#12202A",
"materials": {
"board": "#F7F2E7",
"boardGrid": "#EAE3D3",
"track": "#3A5068",
"trackHalo": "#E4DCCA"
},
"anchorPalette": [
1,
0,
2,
6,
3,
9,
7
],
"palettes": {
"4": [
1,
0,
2,
6
],
"7": [
1,
0,
2,
6,
3,
9,
7
],
"9": [
1,
0,
2,
6,
3,
9,
7,
4,
5
],
"12": [
1,
0,
2,
6,
3,
9,
7,
4,
5,
8,
10,
11
]
},
"contrast": {
"sceneText": 9.84281455268355,
"trackOnBoard": 7.442657598835995
}
},
{
"id": "lavender",
"label": "烧脑",
"name": "苔原",
"background": "#BBCBB1",
"ink": "#12202A",
"materials": {
"board": "#F5F3E9",
"boardGrid": "#E8E4D6",
"track": "#3A5068",
"trackHalo": "#E1DCCC"
},
"anchorPalette": [
3,
6,
1,
0,
4,
10,
2
],
"palettes": {
"4": [
3,
6,
1,
0
],
"7": [
3,
6,
1,
0,
4,
10,
2
],
"9": [
3,
6,
1,
0,
4,
10,
2,
5,
7
],
"12": [
3,
6,
1,
0,
4,
10,
2,
5,
7,
8,
9,
11
]
},
"contrast": {
"sceneText": 9.709754954665774,
"trackOnBoard": 7.470269532165791
}
},
{
"id": "rose",
"label": "挑战",
"name": "暮砂",
"background": "#D7BAB5",
"ink": "#12202A",
"materials": {
"board": "#F7F1EA",
"boardGrid": "#EAE2D8",
"track": "#3A5068",
"trackHalo": "#E4DBCF"
},
"anchorPalette": [
6,
0,
3,
5,
2,
11,
8
],
"palettes": {
"4": [
6,
0,
3,
5
],
"7": [
6,
0,
3,
5,
2,
11,
8
],
"9": [
6,
0,
3,
5,
2,
11,
8,
1,
4
],
"12": [
6,
0,
3,
5,
2,
11,
8,
1,
4,
7,
9,
10
]
},
"contrast": {
"sceneText": 9.148840055226982,
"trackOnBoard": 7.409208337359319
}
},
{
"id": "midnight",
"label": "每周挑战",
"name": "夜航",
"background": "#1F2C3B",
"ink": "#FFFFFF",
"materials": {
"board": "#F6F2E9",
"boardGrid": "#E9E3D6",
"track": "#3A5068",
"trackHalo": "#E2DBCC"
},
"anchorPalette": [
2,
5,
0,
6,
1,
9,
3
],
"palettes": {
"4": [
2,
5,
0,
6
],
"7": [
2,
5,
0,
6,
1,
9,
3
],
"9": [
2,
5,
0,
6,
1,
9,
3,
4,
7
],
"12": [
2,
5,
0,
6,
1,
9,
3,
4,
7,
8,
10,
11
]
},
"contrast": {
"sceneText": 14.173029259487338,
"trackOnBoard": 7.437303508154617
}
}
]
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+130
View File
@@ -58,3 +58,133 @@ body:not(.editing) .board-tools>.game-tool{grid-row:3;justify-self:center;width:
.item-study{padding:44px 0;border-bottom:1px solid #273B5020;scroll-margin-top:80px} .item-study{padding:44px 0;border-bottom:1px solid #273B5020;scroll-margin-top:80px}
.item-study-content{max-width:640px;margin:auto}.item-study-content>.item-samples{background:var(--scene-bg,#E9EDE5);border-radius:24px;padding:24px 12px 18px} .item-study-content{max-width:640px;margin:auto}.item-study-content>.item-samples{background:var(--scene-bg,#E9EDE5);border-radius:24px;padding:24px 12px 18px}
@media(max-width:380px){.item-samples,.guide-tools{gap:4px}.component-preview{padding:16px}.game-tool{min-width:72px}} @media(max-width:380px){.item-samples,.guide-tools{gap:4px}.component-preview{padding:16px}.game-tool{min-width:72px}}
/* 06 路标 (signpost): controls recede into the paper; rotation hangs under the board. Values: design/directions/signpost/design.md */
body[data-design=signpost]{--signpost-rotate:#8AA1AD;--signpost-label:#5C7280;--signpost-plate:#9AAEB9;--signpost-plate-ink:#22354A;--signpost-hi:rgba(255,255,255,.6);--signpost-lo:rgba(34,53,74,.28)}
body[data-design=signpost][data-theme=apricot]{--signpost-rotate:#A79378;--signpost-label:#6B5A44;--signpost-plate:#BFA98A}
body[data-design=signpost][data-theme=lavender]{--signpost-rotate:#8E9F86;--signpost-label:#56664F;--signpost-plate:#A2B398}
body[data-design=signpost][data-theme=rose]{--signpost-rotate:#A58C89;--signpost-label:#6A5453;--signpost-plate:#BC9F9B}
body[data-design=signpost][data-theme=midnight]{--signpost-rotate:#4E6376;--signpost-label:#8FA3B4;--signpost-plate:#33465A;--signpost-plate-ink:#DCE5EE;--signpost-hi:rgba(255,255,255,.14);--signpost-lo:rgba(0,0,0,.55)}
/* White atlas icons are tinted through a mask (the CSS form of tinting a white sprite); mask geometry derives from ICONS in src/ui-skin.js. Shared by 06 signpost and 07 macaron. */
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])>.sprite-crop{-webkit-mask:url(../assets/ui-icons-generated.png) no-repeat;mask:url(../assets/ui-icons-generated.png) no-repeat;background:currentColor}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])>.sprite-crop>img{visibility:hidden}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])[data-icon=left]>.sprite-crop{-webkit-mask-size:540.517% 540.517%;mask-size:540.517% 540.517%;-webkit-mask-position:4.207% 36.008%;mask-position:4.207% 36.008%}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])[data-icon=right]>.sprite-crop{-webkit-mask-size:552.423% 552.423%;mask-size:552.423% 552.423%;-webkit-mask-position:36.125% 37.196%;mask-position:36.125% 37.196%}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])[data-icon=grid]>.sprite-crop{-webkit-mask-size:620.792% 620.792%;mask-size:620.792% 620.792%;-webkit-mask-position:35.361% 8.270%;mask-position:35.361% 8.270%}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])[data-icon=gear]>.sprite-crop{-webkit-mask-size:547.598% 547.598%;mask-size:547.598% 547.598%;-webkit-mask-position:5.659% 6.829%;mask-position:5.659% 6.829%}
body:is([data-design=signpost],[data-design=macaron]) :is(.rotate-button>.ui-icon,.game-icon>.ui-icon,.rotations button>[data-icon],.icon-button[data-icon])[data-icon=close]>.sprite-crop{-webkit-mask-size:646.392% 646.392%;mask-size:646.392% 646.392%;-webkit-mask-position:94.245% 8.679%;mask-position:94.245% 8.679%}
body[data-design=signpost] .rotations button>[data-icon],body[data-design=signpost]:not(.editing) .rotate-button>.ui-icon{color:var(--signpost-rotate);filter:drop-shadow(0 1px 0 var(--signpost-hi)) drop-shadow(0 -1px 0 var(--signpost-lo))}
body[data-design=signpost]:not(.editing) .rotate-button b{color:var(--signpost-label)}
body[data-design=signpost]:not(.editing) .game-icon>.ui-icon{color:var(--signpost-plate-ink)}
body[data-design=signpost] .icon-button[data-icon]{color:var(--signpost-plate-ink);background:var(--signpost-plate);border:0;box-shadow:none;border-radius:12px}
body[data-design=signpost]:not(.editing) .game-icon>.ui-plate{background:var(--signpost-plate);border-radius:12px}
body[data-design=signpost]:not(.editing) .game-icon>.ui-plate .sprite-crop{display:none}
body[data-design=signpost]:not(.editing) .game-tool>b{color:var(--scene-ink,#273B50)}
/* Rotation belongs to the board: app.js sets --rot-x / --rot-x2 / --rot-y from the board geometry. */
body[data-design=signpost]:not(.editing) .game-card{grid-template-rows:minmax(0,1fr) 108px}
body[data-design=signpost]:not(.editing) .board-tools>.game-tool{grid-row:2}
body[data-design=signpost]:not(.editing) .rotation-controls{position:absolute;inset:0;grid-row:1/-1;grid-column:1/-1;display:block;padding:0;margin:0;pointer-events:none;z-index:3}
body[data-design=signpost]:not(.editing) .rotate-button{position:absolute;left:var(--rot-x,25%);top:var(--rot-y,82%);margin:-41px 0 0 -42px;width:84px;min-width:0;min-height:0;padding:0;gap:2px;display:flex;flex-direction:column;align-items:center;pointer-events:auto}
body[data-design=signpost]:not(.editing) #rotate-right{left:var(--rot-x2,75%)}
body[data-design=signpost]:not(.editing) .rotate-button>.ui-icon{width:64px;height:64px}
body[data-design=signpost]:not(.editing) .rotate-button b{font-size:12px;letter-spacing:0}
/* 07 马卡龙 (macaron): cream world, white objects with soft elevation, mauve ink, one orange action. Values: design/directions/macaron/design.md */
/* Resource Han Rounded (SIL OFL), subset to the game's own characters; see assets/fonts/README.md. */
@font-face{font-family:'Resource Han Rounded';font-weight:500;font-display:swap;src:url(../assets/fonts/ResourceHanRoundedCN-Medium.subset.woff2) format('woff2')}
@font-face{font-family:'Resource Han Rounded';font-weight:700;font-display:swap;src:url(../assets/fonts/ResourceHanRoundedCN-Bold.subset.woff2) format('woff2')}
body[data-design=macaron]{--mac-ink:#7A5560;--mac-ink-strong:#5A3A44;--mac-muted:#A98590;--mac-rotate:#B4939C;--mac-card:#FFFFFF;--mac-elev:0 4px 14px rgba(110,70,82,.14);--mac-cta:#E07416;--mac-cta-edge:#B95C0C;--mac-scrim:rgba(62,46,53,.5);font-family:'Resource Han Rounded',ui-rounded,'Arial Rounded MT Bold','Nunito','PingFang SC','Microsoft YaHei',sans-serif}
body[data-design=macaron][data-theme=apricot]{--mac-ink:#7C4E52;--mac-rotate:#BC9A97}
body[data-design=macaron][data-theme=lavender]{--mac-ink:#5F4E78;--mac-rotate:#A79BC0}
body[data-design=macaron][data-theme=rose]{--mac-ink:#7B4658;--mac-rotate:#BE9AA6}
body[data-design=macaron][data-theme=midnight]{--mac-ink:#FBEFE6;--mac-ink-strong:#FBEFE6;--mac-muted:#C4A9B0;--mac-rotate:#9E8189;--mac-elev:0 6px 18px rgba(0,0,0,.35);--mac-scrim:rgba(20,12,16,.62)}
/* Top row: two white discs at the sides, two stat columns (关卡 / 待解) in the middle, the notice bubble on the row below. */
body[data-design=macaron]:not(.editing) .game-column{grid-template-rows:64px 64px minmax(0,1fr);grid-template-columns:1fr 1fr;column-gap:40px}
body[data-design=macaron]:not(.editing) .level-heading{grid-row:1;grid-column:1;justify-self:end;align-self:center;margin:0;padding:0}
body[data-design=macaron]:not(.editing) .hud{grid-row:1;grid-column:2;justify-self:start;align-self:center;margin:0;padding:0}
body[data-design=macaron]:not(.editing) .notice-slot{grid-row:2;grid-column:1/-1}
body[data-design=macaron]:not(.editing) .game-card{grid-row:3;grid-column:1/-1}
body[data-design=macaron]:not(.editing) .level-ribbon{display:flex;flex-direction:column;align-items:center;gap:3px;font-size:26px;line-height:1;letter-spacing:0;color:var(--mac-ink-strong)}
body[data-design=macaron]:not(.editing) .level-ribbon small{font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--mac-muted)}
body[data-design=macaron]:not(.editing) .level-ribbon b{font-weight:800}
body[data-design=macaron]:not(.editing) .level-ribbon b i{font-style:normal;font-size:14px;font-weight:600;color:var(--mac-muted)}
body[data-design=macaron]:not(.editing) .moves-bubble{background:none;box-shadow:none;padding:0;height:auto;flex-direction:column;align-items:center;gap:3px;min-width:0;width:auto;transform-origin:center}
body[data-design=macaron]:not(.editing) .moves-bubble>span{font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--mac-muted);margin:0}
body[data-design=macaron]:not(.editing) .moves-bubble strong{font-size:26px;line-height:1;font-weight:800;color:var(--mac-ink-strong)}
body[data-design=macaron] .moves-bubble.pop{animation:mac-pill-pop .42s cubic-bezier(.34,1.56,.64,1)}
@keyframes mac-pill-pop{0%{transform:scale(1)}35%{transform:scale(1.18)}100%{transform:scale(1)}}
body[data-design=macaron]:not(.editing) .game-icon>.ui-plate{background:var(--mac-card);border-radius:50%;box-shadow:var(--mac-elev)}
body[data-design=macaron]:not(.editing) .game-icon>.ui-plate .sprite-crop{display:none}
body[data-design=macaron]:not(.editing) .game-icon>.ui-icon{color:#5A3A44}
body[data-design=macaron] .icon-button[data-icon]{color:#5A3A44;background:var(--mac-card);border:0;box-shadow:var(--mac-elev);border-radius:50%}
/* Notices are white speech bubbles with a tail towards the stats and an orange dot instead of the "i" badge. */
body[data-design=macaron] .game-notice{position:relative;background:var(--mac-card);color:#5A3A44;border:0;border-radius:16px;box-shadow:var(--mac-elev);font-weight:600}
body[data-design=macaron] .game-notice::before{content:'';flex:0 0 8px;width:8px;height:8px;border-radius:50%;background:var(--mac-cta)}
body[data-design=macaron] .game-notice::after{content:'';position:absolute;left:50%;top:-6px;margin-left:-6px;border:6px solid transparent;border-top:0;border-bottom:6px solid var(--mac-card)}
/* Rotation hangs under the tray like 06; plain ink-tinted sprites, no plate. */
body[data-design=macaron] .rotations button>[data-icon],body[data-design=macaron]:not(.editing) .rotate-button>.ui-icon{color:var(--mac-rotate)}
body[data-design=macaron]:not(.editing) .rotate-button b{color:var(--mac-ink)}
/* The canvas bleeds 8px into the shell padding on each side, so the exit dissolve has room without shrinking the board. */
body[data-design=macaron]:not(.editing) .canvas-wrap{margin-inline:-8px;width:calc(100% + 16px)}
body[data-design=macaron]:not(.editing) .game-card{grid-template-rows:minmax(0,1fr) 108px}
body[data-design=macaron]:not(.editing) .board-tools>.game-tool{grid-row:2}
body[data-design=macaron]:not(.editing) .rotation-controls{position:absolute;inset:0;grid-row:1/-1;grid-column:1/-1;display:block;padding:0;margin:0;pointer-events:none;z-index:3}
body[data-design=macaron]:not(.editing) .rotate-button{position:absolute;left:var(--rot-x,25%);top:var(--rot-y,82%);margin:-41px 0 0 -42px;width:84px;min-width:0;min-height:0;padding:0;gap:2px;display:flex;flex-direction:column;align-items:center;pointer-events:auto}
body[data-design=macaron]:not(.editing) #rotate-right{left:var(--rot-x2,75%)}
body[data-design=macaron]:not(.editing) .rotate-button>.ui-icon{width:60px;height:60px}
body[data-design=macaron]:not(.editing) .rotate-button b{font-size:12px;letter-spacing:0}
/* Tools are the reference's white discs: soft elevation, a candy-coloured glyph tinted through the atlas mask, mauve labels. */
body[data-design=macaron] .game-tool{--item-color:var(--mac-card);--item-border:0;--item-radius:50%;--item-icon-filter:none}
body[data-design=macaron] .game-tool .item-face::before{box-shadow:var(--mac-elev)}
body[data-design=macaron] .game-tool .item-face{color:#4A91D4}
body[data-design=macaron] .game-tool[data-tool=restart] .item-face{color:#D06E93}
body[data-design=macaron] .game-tool[data-tool=hint] .item-face{color:#C98A0E}
body[data-design=macaron] .game-tool .item-face :is(.ui-icon>.sprite-crop,.art-icon){-webkit-mask:url(../assets/ui-icons-generated.png) no-repeat;mask:url(../assets/ui-icons-generated.png) no-repeat;background:currentColor;filter:none}
body[data-design=macaron] .game-tool .item-face :is(.ui-icon>.sprite-crop,.art-icon)>img{visibility:hidden}
body[data-design=macaron] .game-tool[data-tool=undo] .item-face :is(.ui-icon>.sprite-crop,.art-icon){-webkit-mask-size:577.880% 577.880%;mask-size:577.880% 577.880%;-webkit-mask-position:65.574% 38.380%;mask-position:65.574% 38.380%}
body[data-design=macaron] .game-tool[data-tool=restart] .item-face :is(.ui-icon>.sprite-crop,.art-icon){-webkit-mask-size:540.517% 540.517%;mask-size:540.517% 540.517%;-webkit-mask-position:95.890% 36.008%;mask-position:95.890% 36.008%}
body[data-design=macaron] .game-tool[data-tool=hint] .item-face :is(.ui-icon>.sprite-crop,.art-icon){-webkit-mask-size:533.617% 533.617%;mask-size:533.617% 533.617%;-webkit-mask-position:4.220% 66.045%;mask-position:4.220% 66.045%}
body[data-design=macaron]:not(.editing) .game-tool>b,body[data-design=macaron] .phone-tools .game-tool>b,body[data-design=macaron] .item-samples .game-tool>b{color:var(--mac-ink)}
:is(.phone .phone-tools,body[data-design=macaron]:not(.editing) .board-tools) .game-tool:disabled{opacity:.45}
/* Result screen: the reference's dark celebration. No card; cream glowing title on the scrim, rays and confetti behind the stars, one orange pill. */
/* Full-screen result: the dialog covers the viewport, so rays, confetti and text are never clipped by a card edge. */
body[data-design=macaron] .win-overlay{background:transparent!important;box-shadow:none;position:fixed;inset:0;width:100%;max-width:none;height:100%;max-height:none;margin:0;padding:24px 20px;border-radius:0;overflow:hidden}
body[data-design=macaron] .win-overlay[open]{display:flex;flex-direction:column;justify-content:center;align-items:center;animation:mac-veil .32s ease-out both}
@keyframes mac-veil{from{opacity:0}to{opacity:1}}
body[data-design=macaron] .win-overlay>.ui-plate{display:none!important}
body[data-design=macaron] .win-overlay::backdrop{background:rgba(40,26,32,.86);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
body[data-design=macaron] .win-overlay .eyebrow{color:#C9AEB6}
body[data-design=macaron] .win-overlay h3{color:#FFF3E6;font-size:25px;letter-spacing:.01em;text-shadow:0 0 22px rgba(255,214,150,.55),0 2px 0 rgba(0,0,0,.25)}
body[data-design=macaron] .win-overlay p{color:#E9D2C4}
body[data-design=macaron] .win-overlay .text-button{color:#FBEFE6;background:rgba(255,255,255,.14)!important;border-radius:999px;min-height:44px;padding:10px 26px;margin-top:12px}
body[data-design=macaron] .win-overlay .text-button>.ui-plate{display:none!important}
body[data-design=macaron] .win-overlay .result-emblem{position:relative;isolation:isolate;overflow:visible;margin-bottom:6px}
body[data-design=macaron] .win-overlay[open] .result-emblem::before{content:'';position:absolute;left:50%;top:50%;width:640px;height:640px;margin:-320px 0 0 -320px;border-radius:50%;background:repeating-conic-gradient(from 0deg,rgba(255,200,96,.40) 0 7deg,transparent 7deg 18deg);-webkit-mask:radial-gradient(circle,#000 10%,transparent 60%);mask:radial-gradient(circle,#000 10%,transparent 60%);animation:mac-rays 40s linear infinite;z-index:-1;pointer-events:none}
@keyframes mac-rays{to{transform:rotate(360deg)}}
body[data-design=macaron] .win-overlay[open] .result-emblem::after{content:'';position:absolute;left:50%;top:-6px;width:7px;height:11px;border-radius:2px;background:#EE5398;box-shadow:-84px 6px 0 #578BF0,-48px -12px 0 #F7C948,-120px 16px 0 #4C9E5A,36px -10px 0 #937DE4,72px 8px 0 #E5680C,112px -2px 0 #369C94,-18px 18px 0 #C56AC4,96px 24px 0 #D06E93,-140px -4px 0 #F7C948,140px 10px 0 #EE5398;animation:mac-confetti 1.6s .3s ease-out both;pointer-events:none;z-index:-1}
@keyframes mac-confetti{from{opacity:0;transform:translateY(-40px) rotate(0)}30%{opacity:1}to{opacity:0;transform:translateY(110px) rotate(200deg)}}
body[data-design=macaron] .primary{color:#FFFFFF;font-weight:800;font-size:16px;min-height:52px;padding:12px 30px}
body[data-design=macaron] .primary>.ui-plate{background:var(--mac-cta);border-radius:999px;box-shadow:0 4px 0 var(--mac-cta-edge);filter:none}
body[data-design=macaron] .primary>.ui-plate .sprite-crop{display:none}
/* Menus and the level map: a white card with a peach title band, like the reference's settings sheet. */
body[data-design=macaron] #info-dialog::backdrop{background:var(--mac-scrim)}
body[data-design=macaron] #info-dialog>.ui-plate{background:#FFFFFF;border-radius:28px}
body[data-design=macaron] #info-dialog>.ui-plate .sprite-crop{display:none}
body[data-design=macaron] #info-dialog>#dialog-content{margin:-32px -25px 0;padding:30px 25px 0;background:linear-gradient(#FBE6DA 0,#FBE6DA 104px,transparent 104px);border-radius:28px 28px 0 0}
body[data-design=macaron] #info-dialog>#dialog-content>.eyebrow{text-align:center;display:block}
body[data-design=macaron] #info-dialog>#dialog-content>h2{text-align:center;margin:8px 0 34px}
body[data-design=macaron] dialog h2{color:#5A3A44}
body[data-design=macaron] dialog p,body[data-design=macaron] dialog li,body[data-design=macaron] dialog .eyebrow{color:#8A6670}
body[data-design=macaron] #info-dialog[open]{animation:mac-pop .38s cubic-bezier(.34,1.56,.64,1) both}
@keyframes mac-pop{from{opacity:0;transform:scale(.86)}to{opacity:1;transform:scale(1)}}
body[data-design=macaron] .text-button{color:var(--mac-muted)}
body[data-design=macaron] .dialog-close.game-icon{z-index:2}
body[data-design=macaron] .dialog-close.game-icon>.ui-plate{background:#FFFFFF;border-radius:50%;box-shadow:0 2px 8px rgba(110,70,82,.16)}
body[data-design=macaron] .dialog-close.game-icon>.ui-plate .sprite-crop{display:none}
body[data-design=macaron] .dialog-close.game-icon>.ui-icon{color:#7A5560}
body[data-design=macaron] .level-btn>.ui-plate{background:#F7EFE8;border-radius:16px}
body[data-design=macaron] .level-btn.done>.ui-plate{background:#E4F3EA}
body[data-design=macaron] .level-btn.current>.ui-plate{background:var(--mac-cta)}
body[data-design=macaron] .level-btn>.ui-plate .sprite-crop{display:none}
body[data-design=macaron] .level-btn{color:#7A5560}
@media(prefers-reduced-motion:reduce){body[data-design=macaron] .moves-bubble.pop,body[data-design=macaron] .win-overlay[open] .result-emblem::before,body[data-design=macaron] .win-overlay[open] .result-emblem::after{animation:none}}
+6 -6
View File
File diff suppressed because one or more lines are too long
+25 -1
View File
@@ -9,7 +9,7 @@
"catalog": "design/index.html", "catalog": "design/index.html",
"example": "design/examples/render-design.mjs", "example": "design/examples/render-design.mjs",
"defaultDesignId": "calm", "defaultDesignId": "calm",
"latestDesignId": "paper", "latestDesignId": "macaron",
"selectionPolicy": "multiple-candidates", "selectionPolicy": "multiple-candidates",
"themeIds": [ "themeIds": [
"lagoon", "lagoon",
@@ -92,6 +92,30 @@
"tokens": "design/directions/paper/tokens.json", "tokens": "design/directions/paper/tokens.json",
"preview": "design/directions/paper/index.html", "preview": "design/directions/paper/index.html",
"legacyPreview": "design/directions/paper.html" "legacyPreview": "design/directions/paper.html"
},
{
"id": "signpost",
"code": "06",
"name": "路标",
"artStyle": "signpost",
"status": "review-candidate",
"directory": "design/directions/signpost",
"designDoc": "design/directions/signpost/design.md",
"tokens": "design/directions/signpost/tokens.json",
"preview": "design/directions/signpost/index.html",
"legacyPreview": "design/directions/signpost.html"
},
{
"id": "macaron",
"code": "07",
"name": "马卡龙",
"artStyle": "macaron",
"status": "review-candidate",
"directory": "design/directions/macaron",
"designDoc": "design/directions/macaron/design.md",
"tokens": "design/directions/macaron/tokens.json",
"preview": "design/directions/macaron/index.html",
"legacyPreview": "design/directions/macaron.html"
} }
] ]
} }
+2 -2
View File
@@ -8,7 +8,7 @@
| 参数 | 合法值 | 作用 | | 参数 | 合法值 | 作用 |
| --- | --- | --- | | --- | --- | --- |
| `design` | `calm` / `vivid` / `toy` / `animals` / `paper` | 棋子造型、轨道画法、配色库和控件风格 | | `design` | `calm` / `vivid` / `toy` / `animals` / `paper` / `signpost` / `macaron` | 棋子造型、轨道画法、配色库和控件风格 |
| `theme` | `lagoon` / `apricot` / `lavender` / `rose` / `midnight` | 轻松、进阶、烧脑、挑战、每周挑战的视觉主题 | | `theme` | `lagoon` / `apricot` / `lavender` / `rose` / `midnight` | 轻松、进阶、烧脑、挑战、每周挑战的视觉主题 |
| `colors` | 4 / 7 / 9 / 12 | 主游戏单关使用的棋子配色数量,默认 7 | | `colors` | 4 / 7 / 9 / 12 | 主游戏单关使用的棋子配色数量,默认 7 |
@@ -76,7 +76,7 @@ drawScene(painter, level, level.tiles,
## 所有方案共用的产品要求 ## 所有方案共用的产品要求
- 棋盘在通知区与旋转区之间垂直居中。旋转与道具占真实布局行,不绝对定位压住棋盘。适配手机、Pad、折叠屏和桌面。 - 棋盘在通知区与旋转区之间垂直居中。旋转与道具占真实布局行,不绝对定位压住棋盘。适配手机、Pad、折叠屏和桌面。
- 撤销、重来、提示是游戏道具,与顶部紧凑导航分开。常规底座 64px,宽度至少 600px 时为 68px,短屏高度不超过 600px 时为 56px;图标 32px、标签 13px。底座无阴影、立体底边或渐变高光,方案的棋子材质不覆盖这条要求。 - 撤销、重来、提示是游戏道具,与顶部紧凑导航分开。常规底座 64px,宽度至少 600px 时为 68px,短屏高度不超过 600px 时为 56px;图标 32px、标签 13px。底座无阴影、立体底边或渐变高光,方案的棋子材质不覆盖这条要求。唯一例外:07 `macaron` 的道具是参考作品的白色圆钮带柔和投影,2026-09-14 用户确认只允许该方案使用,其他方案(含新增方案)继续保持扁平,不得引用这条例外。
- 次数和“▶ AD”角标只用于设计示例,当前不接入真实库存、广告或付费获取逻辑。 - 次数和“▶ AD”角标只用于设计示例,当前不接入真实库存、广告或付费获取逻辑。
- 奖励星星为黄色/金色并带光感。通知固定在剩余步数下方,不能挪回棋盘下方。 - 奖励星星为黄色/金色并带光感。通知固定在剩余步数下方,不能挪回棋盘下方。
- 路线以弯曲路径为主要观看内容。动画复用 [exit-animation.js](../src/exit-animation.js) 和 [collision-animation.js](../src/collision-animation.js)。离场时长按实际路径长度计算,不把旧文档中的固定时长或上下限当作当前速度公式。 - 路线以弯曲路径为主要观看内容。动画复用 [exit-animation.js](../src/exit-animation.js) 和 [collision-animation.js](../src/collision-animation.js)。离场时长按实际路径长度计算,不把旧文档中的固定时长或上下限当作当前速度公式。
File diff suppressed because one or more lines are too long