交互

各项目定下的交互做法。每条旁边都有现场演示,能点、能打字、能用键盘操作,跟着本站的深浅色和强调色走;被否的做法标「示意」;小屋的样例在暖纸样框里;末尾「弹窗」一组是屋主收集的六种弹窗,每条一块能点、能拖的手机舞台。

工具 · 液态玻璃

单选筛选只升级手感:选中那枚长出对勾、底色从左铺满、邻居让位

规则不变,仍是单选。对勾真实占位、标签确实变宽,相邻标签用FLIP滑过去;计数变了跳一下;筛出几项只用一条礼貌播报。

本站这里在用收藏 · 类型单选

    勾掉一项,它从「进行中」挪到「已完成」,两枚标签上的数字各跳一下。

    数值 / 代码

    结构  <div role="group" aria-label="按状态筛选"> 里一排 <button aria-pressed>
    对勾  只插进选中那一枚,真实占位;入场220ms cubic-bezier(.22,1,.36,1)
          from { opacity:0; transform:scale(.2) rotate(-30deg) }
    铺底  .chip::before { transform:scaleX(0); transform-origin:left center }
          .chip[aria-pressed="true"]::before { transform:scaleX(1) }   220ms 同一条曲线
    让位  点击时先量各标签位置 → 改状态 → 从旧位置 translate 滑回0(220ms)
          标签里的文字按「相对标签」的位置补位,对勾把字往右推也是滑过去的
    计数  值变了才重播(首次渲染不跳)
          @keyframes bump-in { from { opacity:0; transform:translateY(-45%) scale(1.15) } }
    播报  <p class="visually-hidden" aria-live="polite">显示 N 项</p>——整排只这一条
    减弱  不量位置、不挂动画类,直接到位

    用在哪

    plan「全部任务」的状态筛选(全部/收件箱/进行中/已完成/已归档)。plan笔记页的标签筛选同样处理,但不铺底色——那一行本来是无边框文字,选中只换深色加粗,带下划线的蓝字会像超链接。本站收藏页按「类型」筛选的那排单选也是这套。

    为什么

    屋主给的组件原文是多选,可plan这排筛选一直是单选;改成多选就改了筛选规则,等于造新功能。所以只把对勾、铺底、让位、数字跳动套到现有的单选上。播报集中成一条:一排标签每个数都播,读屏会被刷屏。

    坑

    验FLIP有没有动,要读getComputedStyle(el).transform;读el.style.transform永远是空的,位移设完下一帧就清掉了。位置快照在点击的事件里拍,不在每次渲染里拍,否则窗口改宽也会滑。

    出处:tools/plan/docs/BUSINESS_LOGIC.md:1147「20. 任务库逻辑」、:1603「30.2 笔记页」;tools/plan/app/src/App.css:1540「.status-chip」、:1588「.chip-check」、:1614「.bump-number.is-bumped」;tools/plan/app/src/pages/TaskLibrary.tsx:150、:173;tools/plan/app/src/hooks/useFlip.ts:3「FLIP 位移动画」;tools/plan/app/src/styles/tokens.css:295「--motion-*」

    多选筛选胶囊:刷刷做过,屋主看后撤回

    要好看,不要更紧凑。题库那排从带全名的卡片换成短名胶囊,信息密度上去了,观感反而掉了。

    本站这里在用收藏 · 标签多选

    已撤回 刷刷3.13.0做过,屋主看后撤回,页面回到3.12.0。下面只是留档,不要照做。

    数值 / 代码

    做法与单选版相同:<button aria-pressed> 胶囊、对勾长出、FLIP 让位、#pool-count 数字跳动
    差别  三排都能多选;题库那排从带全名的卡片换成短名胶囊
    结果  手机上题库区从9行卡片缩成5行标签

    用在哪

    刷刷「专项练习」的题型、难度、混合题库三排。3.13.0做了,同一版撤回。本站收藏页的标签筛选在用:star是展台,屋主2026-10-08要求把合集的交互用遍,例外写在「只升级已有交互」那条;其他项目照旧不用。

    为什么

    屋主看过之后让盖回去,原话在下面(文档里转述成「屋主看过觉得不如原来,撤回」)。留下的两条结论:屋主要的是好看,不是更紧凑;以后再动这一页先出样张给屋主看,不直接落代码。

    刷刷專項練習蓋回去,該覺改了以後不好看了,沒有之前好

    屋主,2026-09-27 09:17(繁体输入,照录;控制室会话记录)

    坑

    撤回用的是「只含这一件的补丁」反向打回:这件是在单独副本里做的、差异干净,同一轮的其他改动(搜题联想与标签、首页入口按压、两处输入法回车)一行没动。可能被撤回的试验,一开始就这样隔开做。

    出处:tools/shua/design-proposal.md:599「十一、专项练习的筛选标签:做过,撤回(3.13.0)」、:601、:603;原话:控制室会话记录(2026-09-27 09:17)

    可删除标签缩成圆点再消失,后面的依次补位;输入#联想已有标签

    点叉号:文字先淡、底色缩成圆点、圆点再缩没;后面的标签错峰滑过来补位,框的高度等补位走完一次收缩。

    本站这里在用全站 · 搜索框

    回车或逗号把字收成一枚;输入#弹出已有标签,↑↓选、回车插入,Esc第一下只收浮层;框空着按退格删最后一枚。

    数值 / 代码

    删除  文字、叉号     opacity 1→0,100ms cubic-bezier(.4,0,.2,1)
          底色层         scale(圆点宽/标签宽, 圆点高/标签高) + 淡出,170ms
          中心圆点       淡入 → 55%处最亮 → scale(.2) 淡出,240ms
          圆点走完才从 DOM 里拿掉;收尾 = finished 事件 或 兜底计时器(240 + 120ms)
    补位  后面的标签和输入框 FLIP translate → 0,240ms cubic-bezier(.2,.8,.2,1)
          一个比一个晚24ms出发,最多晚96ms
    高度  补位期间 box.style.minHeight = 原高度(一次性写入)
          走完一次性清掉,框直接收缩——不做高度动画
    新增  opacity 0 + scale(.6) → 原样,180ms;输入框同时 FLIP 让位
    联想  输入框 role="combobox" aria-autocomplete="list" aria-expanded aria-controls
          浮层 role="listbox",选项 role="option",不可聚焦;当前项靠 aria-activedescendant
          浮层 mousedown 一律 preventDefault()(不让输入框失焦,否则 blur 先把浮层收掉、click 落空)
    input.addEventListener("keydown", (event) => {
      imeKeyDown = Boolean(event.isComposing);           // 只记旗标,不 preventDefault
      if (event.isComposing || event.keyCode === 229) return;
      // ↑↓ 移动;有当前项的回车 → preventDefault() 并插入;Esc 第一下只收浮层
    });
    form.addEventListener("submit", (event) => {
      event.preventDefault();
      if (imeKeyDown) return;                            // 只认 isComposing,不认229
      addTag(input.value);
    });

    用在哪

    刷刷搜题框(3.13.0,题库标签与关键词标签);plan笔记的标签输入(2026-09-27,替换原来逗号分隔的一行字:输入#联想当前库已有的标签,回车或中英文逗号收成一枚,删一枚立刻落库)。本站搜索框也是:输入#联想已有标签,收成的标签可删。

    为什么

    「缩成圆点」全程只动transform和opacity:底色单独一层,横竖各按自己的比例缩,缩出来是真的圆,不是被压扁的胶囊。高度先撑住再一次放开:一删就收缩的话,从第二行往上滑的标签有240ms画在框外,压在下面的字上。

    坑

    回车和Esc的处理第一行先判event.isComposing:输入法选词那一下回车、取消选词的Esc都不是给网页的。表单的隐式提交是回车的默认动作,不经过任何keydown分支,所以submit里还要拦一次——而且拦提交那一处只认isComposing、不认keyCode 229:安卓软键盘不在合成时也常报229,认了会让键盘上的「搜索」「完成」键按了没反应。两种错代价不对等:拼音被收成一枚标签,删掉就好;手机上回车键失灵是功能坏了。

    出处:tools/shua/design-proposal.md:572「10.3 删除动画与高度」;tools/shua/app.js:2359「reflowQuestionSearchBox」、:2411「removeQuestionSearchTag」、:702「flipMove」、:2532;tools/plan/docs/BUSINESS_LOGIC.md:1621「标签输入」;tools/plan/app/src/components/TagInput.tsx:95「remove」;tools/gang/design-proposal.md:1362「11.4 输入法规矩」

    联想浮层:最多6条、末项停住、零结果列相近、播报等停手400ms只播最后一句

    焦点一直留在输入框。只有选中了某一项的回车才拦,没选的回车照旧提交;第一下Esc只收浮层、字留着,第二下才清空。

    本站这里在用全站 · 搜索框

    数值 / 代码

    条数   桌面6条、≤600px 5条;末尾固定一条「查看全部 N 个结果」(选它 = 点「搜索」)
    游标   ↓ 从「无」到第0项;第0项按 ↑ 回到「无」;末项按 ↓ 停住
    回车   有当前项 → preventDefault() 并打开它;没有当前项 → 不拦,表单照旧提交
    Esc    第一下只收浮层、保留框内文字;第二下清空;再下一下收起 ≤900px 的整行搜索
    零结果 「没有直接命中「xx」,名称相近的业务:」+ 最多3条,不出「查看全部」
    播报   「N条联想,上下键选择」;停手约400ms后只播最后一句,同一句不重播,收起时清掉待播
    更新   非合成态 input 与 compositionend 两路都接,渲染幂等;组字期间不更新
    去抖   不做(单次查询不到1.5ms)
    鼠标   mousedown preventDefault();mousemove 到哪条游标就到哪条,键盘鼠标共用一个高亮
    底     实色,不挂 backdrop-filter

    用在哪

    岗岗顶栏搜索框(「选中后以标签插入正文」那一半不做:阅读器没有正文)。刷刷搜题框另有两条:联想只用现成数据(题库名+术语表,合计最多8条),浮层左端对齐输入框里光标的横坐标。本站搜索框的联想浮层照这几条做。

    为什么

    选项不可聚焦、焦点留在输入框,用户看着联想还能接着打字。播报等停手再说:每敲一个字播一次,读屏会被自己的播报打断。浮层不磨砂是量过的:换成半透明玻璃底加blur(30px)后,屋主台式机那档(2040×1019、软件渲染)整页帧间隔P95从16.7ms翻到33.4ms,超过25ms的长帧从0个涨到34–52个;有显卡的手机档一个都不多。

    坑

    收起时要把待播的那一句清掉,不然400ms后它会盖掉结果页自己的播报。零结果不能算「关着」:说明行照样显示,Esc照样能收。

    出处:tools/gang/design-proposal.md:1316「11.2 数据口径」、:1337「11.3 键盘、鼠标与读屏」、:1397「11.6 为什么不加磨砂」;tools/gang/app.js:3357「speakSuggest」、:3410「searchInput」;tools/shua/design-proposal.md:561「10.1 联想只用现成的两样数据」、:579「10.4 浮层」

    按压倾斜:朝触点压下去一点,松手弹簧复原

    按哪边哪边往屏幕里沉、整张缩一点、光团向触点聚拢;正常松手带过冲弹回,滚动或拖动撤掉按压时直接回位、不弹。

    本站这里在用总览 · 章节目录收藏 · 卡片按压

    已按0次

    数值 / 代码

    倾斜   触点在卡边上时最多7°,按到正中为0
           --pry = (fx - .5) × 2 × 7deg      --prx = -(fy - .5) × 2 × 7deg
    缩放   .96
    按下   transform .14s cubic-bezier(.2,.8,.2,1)
    光团   scale(1.8) → scale(1)(.22s)、opacity 0 → .9(.14s);位置用 left/top 一次写定,不做动画
           card 卡面是图,光团是白光叠 screen;本样例卡面是白底,改用强调色光团、opacity .3
    松手   transform .7s 弹簧(阻尼比 .5,过冲约16%)
           transition: transform .7s cubic-bezier(.34,1.56,.64,1);   /* 不认 linear() 的退路 */
           transition: transform .7s linear(0,.06,.208,.4,.6,.784,.935,1.047,1.119,1.155,1.163,
             1.149,1.123,1.091,1.059,1.03,1.007,.99,.979,.974,.974,.976,.981,.986,.991,.996,1,1.002,1);
    撤掉   拖出6px、pointercancel:160ms cubic-bezier(.2,.8,.2,1) 直接回位,不过冲
    键盘   空格 / 回车 = 按在正中:不倾斜、只缩放;松开键复原
    减弱   不倾斜不缩放,光团在触点原地淡入淡出
    写法   .card { transform: rotateX(var(--prx,0deg)) rotateY(var(--pry,0deg)) scale(var(--ps,1)) }
           透视写在父元素的 perspective 上,静止时 computed transform 回到单位矩阵

    用在哪

    card画廊Cover Flow正中那张和查看器里的卡(本样例取这套数,撤掉按压那一档借刷刷的)。刷刷首页「练习方式」列表行是另一套数:行很宽,鼠标最大1°缩到.985、触屏最大3°缩到.97,左右倾角再按行宽压。本站总览章节目录的每一行、收藏页的卡片,按下去都朝触点倾斜。

    为什么

    同一个角度在长行两端的位移随行宽平方增长:1°在1138宽的行两端要晃约7px,所以宽行要压角度,卡片不用。缩放不压:等比缩放两端对称,看着是「按进去」。撤掉按压不过冲:手指按下后开始滚动,用户在滚页面,不该看到一张卡在那里弹。

    坑

    倾斜并进元素原来那条transform,不另起一层,否则两套变换打架。光斑放在带透视变换、又被overflow:hidden裁切的元素里,里面的字会被先画进一张中间纹理再投影:刷刷第一版把光斑放在列表行里,手机417@3.5上按住时字明显发糊(文字边缘梯度28,静止73),后来把光斑垫到整个列表底下;card卡面是图,光团留在卡里。弹簧曲线只管这一次复原,走完要摘掉,不然下一次按下也会过冲。

    出处:tools/card/collection/gallery.js:312「PRESS_TILT」、:315「press」、:359「pointermove」(拖出6px);tools/card/collection/gallery.css:29–34「按压」;tools/card/CLAUDE.md:175「按压」;tools/shua/app.js:3819「首页入口行的按压反馈」、:3851「PRESS_CANCEL」;tools/shua/design-proposal.md:392「首页入口行的按压反馈(3.13.0)」

    会丢东西才确认,确认框写清丢什么;能撤销的不问,点了就生效的不加确认

    刷刷开始新练习会丢上次的作答,要确认;plan改完自动保存、给3秒撤销,不再问;岗岗「清空勾选」点了就生效。

    本站这里在用全站 · 恢复默认

    刷刷:会丢作答,要确认

    放弃上次的练习?

    plan:自动保存+撤销

    改几个字,回车或点别处就存。

    岗岗:点了就生效

    数值 / 代码

    刷刷  confirm(`上次的“${title}”做到第${n}/${total}题、已答${answered}题。开始新的练习会放弃它的作答,无法恢复。要继续吗?`)
    plan  文本失焦或回车即落库,点选类点了就落库 → 底部「已保存 · 撤销」3秒
          撤销 = 把对象整份回滚到这次修改之前的快照;值没变就什么都不写
          删附件仍要确认:「删除附件“X”?文件会一起删掉,撤销也找不回来。」
    岗岗  「清空勾选」「从常办移出」不加确认,读屏播「已清空该卡的勾选,共N项」
    样例  <dialog> + showModal():初始焦点在「取消」;Esc 走 cancel 事件 = 取消;
          close 后焦点还给「开始新的练习」;弹层实色,不挂 backdrop-filter

    用在哪

    刷刷所有会顶掉半截练习的入口;plan任务与笔记的详情面板;岗岗速查卡的勾选清单与常办。本站「恢复默认外观」能撤销,所以不问:点了就生效,提示条上给撤销。

    为什么

    确认框的用处是把代价说清楚:做到哪一题、答了几题、能不能恢复。能撤销的操作再问一句,等于每次多一步——plan原来的「有未保存的改动,放弃吗?」连同显式「保存/取消」一起删了,换成自动保存加撤销。

    逻辑很不合适。

    屋主,2026-09-23,在手机上看过plan显式保存的详情面板后

    坑

    样例用<dialog>而不是原生confirm():要跟随深浅色和强调色,按钮要写动作名(「放弃并开始」而不是「确定」)。代价是三件事得自己管:Esc当取消、关闭后焦点还给触发按钮、压在正文上的弹层用实色。刷刷生产用的是原生confirm(),文案是同一句。

    出处:tools/shua/app.js:1368「confirmDiscardActiveSession」;tools/plan/docs/BUSINESS_LOGIC.md:1649「31. 表单自动保存」、:1664「31.1 规则」、:1672「31.2」、:1430「25.3 详情面板结构」;tools/gang/design-proposal.md:1438「12.1 八个组件的核对表」;tools/gang/app.js:1875

    分段控件用radiogroup:←→循环并带焦点,只有选中那项在Tab序列里

    浅/深/自动是单选,语义用role="radio"加aria-checked,不用aria-pressed;六个色点是一组aria-pressed按钮。

    本站这里在用全站 · 浅深切换全站 · 背景模糊

    样例外观

    样例强调色

    今天

    3项待办 · 约2.5小时

    护照续签材料 明天

    Tab到分段控件,用←→换档(焦点跟着走),Home/End跳首尾;只改右边这个小窗,不动全站。

    数值 / 代码

    <div role="radiogroup" aria-label="外观">
      <button type="button" role="radio" aria-checked="true"  tabindex="0">浅</button>
      <button type="button" role="radio" aria-checked="false" tabindex="-1">深</button>
      <button type="button" role="radio" aria-checked="false" tabindex="-1"
              aria-label="自动,跟随系统:浅色">自动</button>
    </div>
    键盘  ←/→(↑/↓ 同)组内循环,选中跟着焦点走;Home / End 跳首尾
    色点  role="group" 里六个 <button aria-pressed aria-label="蓝">;←/→、Home/End 同样能换,↑/↓ 留给页面滚动
          中文名默认压成 0 宽(不是 display:none),hover 或键盘聚焦时就地展开
    选中  色点双圈 box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent)
    播报  「外观已切换为深色」「强调色已切换为绿」
    存储  <项目>-mode、<项目>-accent,读写一律 try/catch(file:// 下 Safari 读 localStorage 直接抛错)

    用在哪

    四个工具侧栏底部的外观控件;≤600px放进「更多」面板。本站侧栏底部的浅深分段、「背景模糊」分段也是这套。

    为什么

    单选组读屏读作「3项中的第1项,已选中」;按钮加aria-pressed读出来是三个互不相干的开关。roving tabindex让整组只占一个Tab位,组内换档用方向键。「自动」把解析结果写进可读名,读屏才答得出现在到底是深还是浅。

    坑

    roving tabindex和方向键必须一起做:只写前者,键盘用户Tab只能停在选中那一项,换不了档。岗岗2026-09-27读代码时就是这样——tabindex写了,app.js里没有←→处理;09-28补上了(774c278,统一键盘分发里的handleModeKey)。刷刷3.13.1之前是radiogroup里放aria-pressed按钮,已改成role="radio"。

    出处:tools/shua/app.js:4063「外观控件的键盘操作」;tools/shua/index.html:33;tools/shua/design-proposal.md:474「7.4 验收口径」;tools/gang/design-proposal.md:1114「分段控件是 radiogroup + radio」;tools/gang/app.js:1187「外观开关」、:1908「paintModeSwitch」、:3667「handleModeKey」;tools/plan/docs/design/SPEC-apple-glass.md:32「3. 主题与切换」

    入口用分组列表:彩色方块图标+标题副标题+计数胶囊+SVG chevron

    列表行代替卡片网格里的入口卡;chevron画成线条图标,不用字符「›」。

    本站这里在用总览 · 章节目录

    数值 / 代码

    行      图标块32px、圆角9 + 标题 / 副标题(单行省略)+ 计数胶囊 + chevron
    图标块  background-color: 分类色实底;
            background-image: linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,0));
            box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 2px 5px rgba(0,0,0,.12);
            里面白色线条图标18px、stroke 1.9;实心只给 play 这种本来就实心的形
    chevron 三级灰 rgba(60,60,67,.32),<path d="m9.8 6.2 5.8 5.8-5.8 5.8"/>
    分隔    行间1px rgba(60,60,67,.12),首行无线;不用边框分层

    用在哪

    刷刷首页「快速开始」;岗岗速查卡各节标题;card的回退列表。本站总览的章节目录也是这种列表。plan四块侧栏磁贴原来也是图标块,2026-10-08调轻成一行「彩色线条小图标+名字+右边数字」(只有逾期不为0时数字标红),图标块那套样式已从plan代码删掉(tools/plan/docs/BUSINESS_LOGIC.md:2030「39.1 侧栏磁贴调轻」)——首屏最抢眼的不该是磁贴,图标仍按四类上色、不用灰的。

    为什么

    像iOS设置那种图标块,一眼分得出类别;屋主明确说过不要灰色空方块。

    坑

    SPEC样张里chevron是字符「›」、导航图标stroke写的1.8,都是旧写法,以SPEC「图标」一节为准。白线条压在绿、橙、青实底上低于3:1(刷刷实算1.55–5.65:1),和主按钮一样按审美优先记录、不断言。

    出处:tools/plan/docs/design/SPEC-apple-glass.md:10「1. 结构」、:129「5b. 图标」;tools/plan/docs/design/shua-glass.html:72「.row .ico」;tools/gang/styles.css:88「--ic-chevron」;tools/shua/design-proposal.md:390;tools/plan/docs/ui-redesign-proposal-v2.md:565

    图标用真SVG线条;要跟文字一起变色,就用mask画

    stroke 1.9、圆头圆角,导航20px、列表18px;禁止用字符或emoji凑图标。伪元素上用mask取形、currentColor上色,换强调色、深浅、高对比都自动跟上。

    本站这里在用全站 · 侧栏导航

    • 正文色
    • 次级色
    • 强调色文字档

    同一份图标数据,颜色只来自所在元素的color;在侧栏换强调色或深浅,这一行跟着变。

    数值 / 代码

    .icon::before {
      content: ""; width: 20px; height: 20px;
      background: currentColor;                         /* 颜色 = 元素自己的 color */
      -webkit-mask: var(--ic-doc) center / contain no-repeat;
              mask: var(--ic-doc) center / contain no-repeat;
    }
    :root {
      /* 形状色无所谓,统一写 %23000;# 必须转义成 %23 */
      --ic-doc: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'
        fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E…%3C/svg%3E");
    }

    用在哪

    岗岗全部图标(不改DOM,画在伪元素上);刷刷用本地lucide,stroke-width统一成1.9;plan用lucide React;本站全部内联SVG,侧栏导航的图标就是。

    为什么

    屋主2026-09-23两次纠正后定成硬规则:线条图标,不许字符、emoji、灰色空方块占位(据控制室记录,一次是侧栏图标用了灰方块,一次是左上角放了「刷」字)。mask只取形状,一份图标通吃六个强调色、浅深两档和高对比模式,不用每种主题备一份。

    坑

    data URI里的#不写成%23,会被当成URL片段分隔符,图直接不出、也不报错。file://下<use href="外部.svg#id">会被Chrome当跨源拦掉,所以本站图标全部内联。

    出处:tools/plan/docs/design/SPEC-apple-glass.md:128「5b. 图标」;tools/gang/styles.css:83「图标 data URI」;tools/gang/design-proposal.md:1061「10.13 图标」;tools/shua/design-proposal.md:390;tools/star/CLAUDE.md:27「特意为 file:// 设计」

    品牌图标可换文件;favicon必须自带底

    渐变方块里的白色线条图优先读brand/brand-icon.svg,居中占84%;favicon没有页面替它画底,要另做一枚带渐变底的。

    本站这里在用全站 · 品牌方块

    页面里:方块是页面画的渐变,图只负责白线
    标签页上:透明底白线,浅色标签栏上看不见
    标签页上:自带渐变底,圆角22.37%

    数值 / 代码

    品牌    边长34px的圆角方块,linear-gradient(135deg, var(--accent), var(--accent-2))——和主按钮同一条
            <静态目录>/brand/brand-icon.svg → brand-icon.png(1024² 透明底白线)→ 内置 SVG
            文件居中占84%(2026-09-23由65%调大,屋主嫌小);两个文件都没有才回落内置 SVG
    favicon 整块圆角方块铺满,rx="229"(边长22.37%,iOS 应用图标比例);线条缩到84%居中
            切强调色时读 getComputedStyle(root).getPropertyValue("--accent"),拼成 data:image/svg+xml,…
            必须 encodeURIComponent(# 会截断 data URI);只接受 /^#[0-9a-fA-F]{3,8}$/
            深浅切换不重画(同一强调色浅深两值16px下分不出)

    用在哪

    四个工具;本站侧栏的品牌方块同样认brand/里的文件,并且自带一份默认brand-icon.svg(就是内置那枚,视窗四周补了留白,按84%放进去和内置等大):探测第一次就命中,不会因为找不到文件在控制台留下报错;标签页上的favicon按当前强调色画成自带渐变底的圆角方块。本条样例里这枚示意图不跟着换。

    为什么

    屋主看了内置SVG说「看得难受」,要自己手绘;65%他嫌太小,改成84%(他的画稿四周本来就留了白)。白线透明图挂成favicon,压在浅色标签栏上等于隐形。

    坑

    SVG是XML,注释里不许出现两个连字符连写:图会解不出来,页面不报错。验证要new Image()真解一遍看naturalWidth。探测文件在不在别用fetch:生产环境有SPA回退,缺文件回的是首页而不是404。

    出处:tools/plan/docs/design/SPEC-apple-glass.md:203「6. 品牌图标」;tools/gang/design-proposal.md:1159「10.14b 品牌图标可换」(由65%调大)、:1171「10.14c 标签页图标 favicon」、:1236「踩过的坑」;tools/shua/design-proposal.md:390;tools/star/brand/README.txt

    灯箱从缩略图原位放大、缩回原位;复制气泡带箭头,贴边自己躲开

    原来灯箱整块瞬间出现,关掉要重新找读到哪;现在从原图的位置变形出来,关的时候缩回去。

    本站这里在用色彩 · 复制气泡收藏 · 截图放大

    演示左边点缩略图:大图从缩略图原位放大出来,Esc、关闭按钮或点大图外面缩回原位;先把正文滚到缩略图只露出一截再点开,关的时候缩略图看不全,就只淡出。右边点交易码复制:气泡带箭头,贴边那个整体往里躲、箭头仍指着码,顶上被吸顶栏挡住就翻到下面。截图和交易码都是示例。

    办理指引 · 第2步(示例)

    先核对客户填的申请表,再和系统界面逐项比对,三张截图依次是申请表、系统录入页、回执。

    缩略图按「铺满、顶端对齐」裁过,只露出截图的上半部分;放大时裁切连续展开,终点是整张截图。

    往下还有一段正文,用来把缩略图滚到边上:看不全的缩略图不当落点,关的时候只淡出,幽灵不会落在一块看不见的地方。

    第3步:把回执交给客户签字,留存一联。(示例)

    第4步:在系统里把这笔业务标成已办结,回执编号抄到登记簿上。(示例)

    第5步:把申请表和留存的那联回执按日期归档;当天下班前交给复核岗。(示例)

    注意事项:截图里的界面只是示意,真的系统界面以柜面为准。(示例)

    速查卡 · 交易码(示例)

    个人开户

    挂失补办本人到场

    跨行转账

    定期存单到期转存

    灯箱:还没打开过。气泡:还没复制过。

    数值 / 代码

    灯箱  开260ms、关200ms;一个临时「幽灵」元素(aria-hidden、pointer-events:none)
          从缩略图可见框变形到大图框,动画完就删
          每帧在 JS 里按缓动算好,关键帧之间 easing:"linear"(开20帧、关15帧,下限12)
          原图比例两头差2%以上、未加载、量出0尺寸 → 不变形,只淡入
          关闭时缩略图不「完整可见」(被吸顶栏、tab bar、裁切祖先挡住)→ 只淡出
          收尾:finish 事件 或 兜底计时器(时长 + 120ms)
    气泡  出现160ms:opacity 0→1、4px 位移、scale(.92)→1,transform-origin 在箭头那端
          1400ms后挂 .is-leaving 淡出140ms再删(animationend + 兜底计时器)
          贴边:平移量写进 --bubble-shift,箭头按同一个量反向移、仍指着徽章中心
          上方放不下(视口顶、吸顶栏、裁切祖先)就翻到下方

    用在哪

    岗岗正文截图与速查卡胶片条的灯箱;交易码「已复制/请手动复制」气泡。本站色彩页的色值点一下复制,弹的就是这种气泡;收藏页的截图点开放大、缩回原位。

    为什么

    从哪来回哪去,看完关掉还在原来读到的地方。打断时直接到终态,不做「半路倒着缩回去」:状态机要多一倍,换来的只是0.26秒里的一点连贯。

    坑

    幽灵是直角的,缩略图的圆角在头尾一两帧会被盖住一点:圆角跟不了非等比缩放,动画border-radius又违反只动transform/opacity,所以不处理。别用WAAPI的pseudoElement选项动::backdrop:不认它的内核会把动画落到dialog本体上,整只灯箱跟着透明。

    出处:tools/gang/design-proposal.md:1451「12.2 ② 灯箱:原位放大 / 缩回」、:1497「12.3 ④ 复制气泡:箭头、进出、碰撞」

    详情用居中大对话框,不用右侧第三栏

    桌面居中920宽、只有正文区内部滚动;手机整屏页从右推入。第三栏在2552宽的实机上把阶段名截成「发通知并收…」,主区却空着。

    本站这里在用收藏 · 卡片详情

    演示同一块缩微屏幕,按笔记本2552×1274的比例画,任务和阶段都是示例。切「居中对话框」「右侧第三栏」对照:点任务那一行看详情;对话框用Esc、关闭按钮或点遮罩关上,焦点回到那一行。第三栏是被否的做法(示意),宽度和截断照2552实机那次画。

    点一行任务看详情。

    全部任务(示例)

    数值 / 代码

    尺寸  宽 min(920px × --ui-scale, 92vw),高上限86vh;标题行与底部主按钮固定,只有正文区滚动
    分栏  视口 ≥1000px 正文分两列;阶段名、材料名完整显示,允许折行,不许省略号
    遮罩  约 rgba(0,0,0,.28);点遮罩、Esc 关闭——Esc 先让正在打字的输入框失焦(失焦即存)
    焦点  role="dialog" aria-modal="true";Tab 在框内转圈;关闭后焦点还回打开它的那一行
    动画  scale(.96)→1 + 淡入,240ms cubic-bezier(.32,.72,0,1);播完再卸载
          手机整屏页从右推入,同一套时长曲线;减弱动效只留淡入淡出
    两态  桌面对话框 / 手机整屏页,同一个 DOM,只靠媒体查询分

    用在哪

    plan任务详情与笔记详情。本站收藏卡的「详情」也用居中大对话框。

    为什么

    屋主在笔记本上看了右侧第三栏,说放右边不合适、也没有动画,问能不能放到更合适的地方;控制室给了三种,他回「A」(原话在下面)。第三栏的宽照1440定,2552宽上名字被截、主区空着一大片,居中对话框借整屏的宽,名字不截(被否的样子见否掉的方向「详情第三栏」)。1000px分两列的阈值是量出来的:1000/1100/1200三档对话框都是920宽,三档列宽只差6px。

    plan右边这个窗口没有动画,并且我觉得他在右边会有点不合适,能不能放在别的更合适的地方,并且里面的内容例如材料他是可以修改的,而不是直接编辑后不能修改的。

    A

    屋主,2026-09-23 14:39、14:43(控制室会话记录)

    坑

    关闭后焦点要还回那一行:屋主会连着改好几条,焦点掉回页首就得重新找。

    出处:tools/plan/docs/BUSINESS_LOGIC.md:1360「25.2 详情是居中对话框 / 手机整屏页」;原话:控制室会话记录(2026-09-23 14:39、14:43)

    小屋 · 暖纸

    深浅切换是一只墙壁开关:role="switch",拨下去入夜,指示点亮一粒暖橙

    不是图标按钮,是家里墙上那种拨杆开关;默认跟系统,站内的显式选择优先。

    点右上角的开关。只切这个样框,不动全站。

    数值 / 代码

    <button type="button" role="switch" aria-checked="false" aria-label="夜间模式" title="关灯">
      <svg width="20" height="26" viewBox="0 0 20 26" aria-hidden="true">
        <rect x="1.75" y="1.75" width="16.5" height="22.5" rx="4" stroke-width="1.5"/>   面板:只有描边
        <rect x="6.75" y="5.4" width="6.5" height="7.2" rx="3.25"/>   拨杆:夜里 translateY(7.4px),200ms ease-out
        <circle cx="10" cy="21.2" r="1.2"/>   指示点:夜里 hsl(24 80% 60%) 炉火橙;白天 opacity .3
      </svg>
    </button>
    名字    可访问名固定「夜间模式」,开没开由aria-checked读出来;title照墙上开关写「关灯」「开灯」
    换主题  document.startViewTransition(翻类);::view-transition-old/new(root) 0.5s cubic-bezier(.4,0,.2,1)
            不支持或减弱动效:瞬切
    颜色    继承导航链接那套:暖灰,悬停亮成深橄榄

    用在哪

    小屋顶栏,全站唯一的主题入口。

    为什么

    颜色和线描的小屋logo说同一种话。第一版是实心填色的盒子,用的是冷色token,夹在一排暖字中间冷暖打架,2026-09-02屋主裁定不和谐。整页快照交叉淡化,比给几百个元素各写transition(「彩色烟花」)干净。

    像家里的开关。

    屋主,2026-09-01,恢复深色主题时

    坑

    startViewTransition被跳过或中止(页面在后台、连点第二下)时,ready和finished两个Promise会reject,要各接一个catch,不然是一条未处理的rejection。线上组件的指示点过渡的是fill和filter;合集样例按「只动transform和opacity」改成两粒圆点交叉淡入淡出,也不走整页View Transition(只切样框自己)。

    出处:Ysevan_web/components/theme-toggle.tsx「ThemeToggle」(「顶栏的墙壁开关」「aria-label="夜间模式"」「startViewTransition」「translateY(7.4px)」「hsl(24 80% 60%)」);Ysevan_web/app/globals.css「::view-transition-old(root)」;Ysevan_web/docs/xiaowu-ui-spec.md「1.2 六条原则」(「两个时辰,一间屋子」)

    每个工具恰好一个Tab位:只有「打开刷刷」那条链接可聚焦

    图、规格条、图标都不加href和tabIndex,展台四件加小架两件,六个工具就是六个Tab位。也因此工具页不做按压倾斜。

    本站这里在用总览 · 章节目录

    演示先点「从这里开始」,再按Tab走过这张工具卡,计数器实时数Tab在卡上停了几次。切到「多个Tab位」(反例,示意)再走一遍:图、序号、标题、规格条都成了Tab位。卡上文案是示例。

    这一遍Tab在卡上停了0次

    02刷题

    刷刷

    离线刷题,错题自动收进错题本。

    • 799题
    • 离线可用
    • 本机存储
    打开刷刷

    停过:还没开始

    数值 / 代码

    <a href="../tools/shua/" aria-label="打开刷刷">打开刷刷</a>   <!-- 同一个标签页打开:不带target、rel;href是构建时算好的相对地址 -->
    <!-- 图、规格条、图标:不加 href、不加 tabIndex -->
    
    .open { border-radius: 999px; border: 1px solid var(--tool-brand); color: var(--tool-brand);
            transition: background-color .18s ease, color .18s ease; }   /* 不位移、不放大、不换阴影档 */
    .open:hover { background: var(--tool-brand-soft); }
    .open:focus-visible { outline: 2px solid var(--tool-brand); outline-offset: 3px; }

    用在哪

    小屋工具页:展台四层(日程安排、刷刷、岗岗、card)和轨道之后小架上的两件(travel、设计合集),六件各恰好一个Tab位。本站总览的章节目录借了这条:一行一个Tab位。

    为什么

    不然键盘用户在同一张卡上要按两次Tab。可见文字必须被可读名包含(WCAG 2.5.3)。焦点环用身份色:中性色画的焦点环在暖纸底上看不见。把整层做成可按压等于多造一个入口,所以屋主给的「按压倾斜卡片」在这页不做。

    坑

    工具页五层叠放,Tab进一个此刻不在场的层时,脚本要把页面滚到那一层停留的正中,焦点所在的链接才看得见。

    出处:Ysevan_web/docs/xiaowu-ui-spec.md「6.6 无障碍与外链」(「六个工具就是六个 tab stop」「在同一个标签页打开」「不做按压倾斜」)、「A.6 工具入口规格(网站侧已落地)」;Ysevan_web/app/projects/tools.module.css「.open」(「打开工具」)

    随笔球:慢慢自转、手一碰就停,点开和拖动靠位移阈值分开

    同一批随笔的另一种看法。读屏、键盘、无JS、省流量拿到的都是普通卡片网格,内容一张不少。

    本站这里在用总览 · 条目星球

    轻量示意,不是原物原物是WebGL,这里没有嵌进来:用CSS 3D把14张随笔卡(标题、日期都是示例)排在球面上慢慢转。按住拖动转球;按下到松开位移≤4px(触摸≤8px)算点击,超过算拖动,右边实时显示判定。键盘:Tab进球,←→换一张、把它转到正面,回车「打开」。没有脚本时这里是普通卡片网格。

    自转
    转着
    这一下位移
    —
    判定
    —
    打开了
    —

    数值 / 代码

    自转  约80秒一圈;拖拽、悬停在卡上、键盘焦点在卡上时停下,放开后慢慢恢复
    拖拽  按下那一点跟着指针走;俯仰限位 ±0.7弧度;松手按最后100ms的速度带惯性
    悬停  只在 (hover: hover) and (pointer: fine):那张卡沿法线浮出、放大一点
    点击  按下到松开位移 ≤4px(触摸 ≤8px)才算点,进这条随笔
    触摸  只认横向拖动;舞台 touch-action: pan-y pinch-zoom;第二根手指落下作废这次拖拽
    键盘  焦点走透明网格里的链接;焦点落在哪张,球就把哪张转到正面,:focus-visible 时画 --ring 焦点环
    首帧  在3D多半会来的那一档,网格先占位(opacity:0),球画出第一帧直接淡入600ms;1800ms没来就放出网格
    提示  球上不叠任何操作提示(「拖动旋转」之类)

    用在哪

    小屋 /notes/globe。本站总览开头的条目星球借了这条:自转、一碰就停,拖动与点开靠位移阈值分开。

    为什么

    手一碰就停,才看得清要点的那张;点击和拖动靠位移阈值分开,拖完松手不会误进详情。

    先出平面网格再变成球,像闪了一下。

    屋主,2026-09-20

    坑

    只写touch-action: pan-y会把这一大块的双指缩放也关掉。手机上网格出流用overflow: clip不用hidden:hidden会建滚动容器,焦点落进被裁的部分时浏览器会去滚它。

    出处:Ysevan_web/docs/xiaowu-ui-spec.md「7.5 随笔球 /notes/globe」、「7.5.3 静态版(首屏先出)」(「首帧:不先闪一下平面网格」)、「7.5.4 3D(接管之后)」(「交互」)、「7.5.9 不许做的」、「7.5.10 手机形态」

    通用

    回车确认先判isComposing:输入法选词那一下不算提交

    凡keydown处理,第一行先挡合成态;表单的隐式提交不经过keydown,submit里再挡一次,而且那一处只认isComposing。

    本站这里在用全站 · 搜索框

      数值 / 代码

      input.addEventListener("keydown", (event) => {
        imeKeyDown = Boolean(event.isComposing);             // 只记旗标,不 preventDefault(可能打断上屏)
        if (event.isComposing || event.keyCode === 229) return;
        // ……回车、Esc、方向键的正常处理
      });
      input.addEventListener("keyup", () => { imeKeyDown = false; });
      input.addEventListener("blur",  () => { imeKeyDown = false; });  // 按下与抬起之间焦点被挪走
      form.addEventListener("submit", (event) => {
        if (imeKeyDown) { event.preventDefault(); return; }  // 只认 isComposing,不认229
        // ……正常提交
      });
      // React 里判 event.nativeEvent.isComposing
      // 组字中不切逗号,由 compositionend 补一次(候选词和「,」一起上屏时不会再来一次普通 input)

      用在哪

      岗岗搜索框与目录过滤框;plan所有回车确认的输入框(标题、材料、提醒、阶段、笔记标签、快速记录、收件箱、顶栏搜索);刷刷搜题与按题号跳转;old首页搜索。本站搜索框同样先判。

      为什么

      中文选词按回车时,keydown的key照样是Enter,只认key的代码分不清选词和提交,内容会提前落库。这类bug用户感觉得到、报不上来:打字时偶尔跳走、被清空、自己提交了,只会以为是自己手快。

      坑

      keydown里提前返回,两个都认:部分内核选词回车那一下isComposing已经是false,只剩229可认(岗岗文档注明未实测)。拦提交那一处只认isComposing:安卓软键盘不在合成时也常报229,认了会让键盘上的「搜索」键按了没反应——拼音被当成词搜一次,改个词就好;搜索键失灵是功能坏了,往后果轻的那边错。写完规矩要grep全仓key === 'Enter'和'Escape'核覆盖面:plan收件箱那处(选词回车会直接把这条转成任务、跳到下一条)就是这样查出来的。

      出处:tools/gang/design-proposal.md:1362「11.4 输入法规矩」;tools/gang/app.js:3236「submit」、:3413;tools/gang/CLAUDE.md:97「七、输入法」;tools/plan/docs/BUSINESS_LOGIC.md:1674「31.2b 回车确认必须先过输入法这一关」;old@4156029 说明.md:147「首页搜索联想、素材卡片按压」

      Esc一下只退一层;合成中的Esc是取消选词,不算关闭

      浮层开着先收浮层、字留着;再按才清空;再按才收起整行搜索。关详情前先让正在打字的输入框失焦,失焦即存。

      本站这里在用全站 · 搜索框全站 · 更多面板

      演示点「摆好四层」(或者自己点开:搜索 → 打字出联想 → 目录),然后连按Esc:一下只退一层,右边先列着现在叠了哪几层,日志写每一下退了哪层。打开「模拟输入法组字中」,这时的Esc只算取消选词,什么都不关。业务名都是示例。

      业务手册(示例)

      现在叠着(最上面那层先退)

        Esc记录

          数值 / 代码

          岗岗(由近到远,一下退一层)
            关目录抽屉
            ≤600px 的速查卡底部抽屉(关闭后焦点还给触发按钮)
            收起搜索联想浮层(保留框内文字)
            清空搜索框内文字
            收起 ≤900px 的整行搜索
          plan 详情对话框
            Esc → 先 blur 正在打字的输入框(失焦即存)→ 再关;合成中的 Esc 不关面板
          快捷键说明面板同步列出这条链

          用在哪

          岗岗全站键盘分发;plan任务与笔记详情、InlineField、顶栏铃铛菜单。上面「联想浮层」「可删除标签」两个样例里都能试。本站搜索联想和「更多」面板也是Esc一下只退一层。

          为什么

          一下Esc既清字又关面板,刚打的字就没了。每按一下只做一件看得见的事,用户按到哪一层停都知道发生了什么。

          坑

          plan「合成态的Esc不能当关闭」这句曾经只是写着:2026-09-27核实,除收件箱外的Esc处理都没判合成态,组字中按Esc会把正在改的字整段丢掉。补完再grep全仓'Escape'核了一遍。

          出处:tools/gang/design-proposal.md:296「6.2 键盘导航」、:1348「11.3」、:1057;tools/plan/docs/BUSINESS_LOGIC.md:1378「25.2」、:1695「31.2b」

          键盘走得到每个功能:跳到正文、焦点归还、装饰对读屏隐藏、播报集中一处

          首个Tab越过导航;弹层关了焦点回到打开它的那个元素;3D画布、光斑、品牌图文件都aria-hidden;结果数和切换用一条aria-live播。

          本站这里在用全站 · 跳到正文全站 · 更多面板

          演示一块迷你页面(内容是示例)。点「从这里开始」再按Tab:第一下落在「跳到正文」;打开详情再关上,焦点回到「打开详情」;光斑和3D画布对读屏隐藏,Tab也走不进去;播报只走一条aria-live,右边「读屏会听到」把它播的和焦点落到哪同步写出来。

          跳到正文

            读屏会听到

              数值 / 代码

              skip link  <a class="skip" href="#main">跳到正文</a>,首个 Tab 就能越过导航
              焦点环      :focus-visible { outline: 2px solid 强调色; outline-offset: 2px }
                          用 :focus-visible 不用 :focus(鼠标点击不冒焦点环);不许 outline:none 了事;
                          不许被 overflow:hidden 的祖先裁掉;小屋暖纸底上焦点环必须用品牌色
              焦点归还    灯箱、抽屉、对话框打开时记下触发元素,关闭后还回去
              对话框      role="dialog" aria-modal="true";Tab 在框内转圈
              装饰        光斑、3D画布、品牌图标文件(alt="")一律 aria-hidden
              播报        一条 aria-live="polite":结果数、环节切换、外观切换;不让每个控件各播各的
              清单        勾选用真 <input type="checkbox"> + <label>,不用 div 模拟
              强制色      forced-colors:active 下给气泡补 CanvasText 边框

              用在哪

              四个工具与小屋。本站外壳也照这套:跳到正文、焦点环、侧栏与「更多」面板的焦点归还。

              为什么

              岗岗改版前每次交互整片innerHTML重建,焦点掉到<body>,是当时最严重的缺口:键盘用户每点一下都得从页首重新Tab。

              出处:tools/gang/design-proposal.md:289「6.1 焦点管理」、:303「6.3 读屏语义」;tools/plan/docs/design/SPEC-apple-glass.md:118「5. 降级与可访问性」;tools/plan/docs/BUSINESS_LOGIC.md:1379;Ysevan_web/docs/xiaowu-ui-spec.md「A.3 圆角、阴影、焦点环」(「焦点环」)

              续做:任何入口要么默认续上,要么点之前就写明会从头开始

              不许静默丢进度。续上的写清续到哪,会从头的在点之前就说。

              本站这里在用总览 · 接着看

              演示一套12题的迷你练习(题目是假的)。从「连续刷题」进去答几题,点「退出」回到入口,再点进去:默认续上,入口胶囊写着做到第几题。换「只练后6题」,题目范围变了,入口上点之前就写明会从第1题开始。切到「默认从头」(反例,示意)再走一遍:进度被静默丢掉。

              练习方式

              存档(只在这块样例里,刷新就没)

              还没有存档

              记录

                数值 / 代码

                连续刷题  默认续上;首页那一行右侧胶囊写「当前题号 / 总数」
                自动看题  存 { index, signature, lastAt }
                          集合相同 → 续上,提示「接着上次看到的第N题继续」
                          集合变了 → 从第1题开始,提示「题目范围和上次不一样」
                其余入口  会顶掉半截练习时先确认(见上面「确认」一条)
                signature 条数 + 首尾题号 + 全部题号的32位哈希:定长,对增删、换序都敏感
                存位置    在 saveState() 一处抄,不在每个翻页函数里抄

                用在哪

                刷刷的三类练习入口。本站总览的「接着看」:从上次看到的那条续上。

                为什么

                屋主看到「1/799」以为连续刷题坏了,查下来是换了题库、进度在旧题库里;真正静默丢进度的是另外两处入口。所以定成判据,以后加入口都照它办。

                连续刷题可以点击后回到原本刷题的地方吗,而不是从第一题开始

                屋主,2026-09-23

                出处:tools/shua/design-proposal.md:531「九、练习入口的判据」、:533、:535、:541

                只升级已有的交互,不为套组件造新功能

                屋主给的六个交互组件,各家先对着代码核一遍:对得上的只升级手感,对不上的不做,写一句为什么。

                本站这里在用总览 · 条目星球

                演示点一个组件(或表头那一列):它在各项目的落点亮起来,下面逐家写做在哪、没做的为什么。数据就是下面「数值 / 代码」那张表;表里没单列理由的格子照写「没单列理由」,不补猜测。

                六个组件×六个项目:做了、撤回、没做

                数值 / 代码

                六个组件在各项目的落地情况
                项目做了没做(为什么)
                plan①只做手感、保持单选(全部任务状态筛选、笔记标签筛选);②+③挪到笔记标签任务没有标签字段;⑤全仓没有任务卡片,整行倾斜会让「按的是哪个」变模糊,回顾页的格子点了没反应,给按压反馈等于让不能点的东西看起来能点
                刷刷②+③搜题框;⑤首页「练习方式」列表行①专项练习做过,屋主看后撤回
                岗岗③顶栏搜索联想(「以标签插入正文」那一半不做)①分类只是单选切换;②没有标签输入;⑤没有首页,目录是列表不是卡片
                card⑤Cover Flow正中那张和查看器里的卡两侧侧立的卡不做
                old③首页搜索;⑤素材卡;老站友链、ACGN横条、游戏入口(做在提交4702be0当时的页面上;书生子白两页和Game页后来在老站整理中移出工作树(old@d216d8f),EV's world两页还在,去向以old/说明.md为准)只接有真实去处的卡:链接是#的模板占位卡点了哪也不去,加反馈只会让人以为坏了
                小屋—①随笔和归档没有筛选,新造一排等于把禁掉的标签云补回来;⑤工具页每个工具只有一个Tab位,做按压等于多造入口
                ⑥长按变录音条—谁都没做:没有一个项目有语音输入,不为它新造麦克风功能

                ①多选筛选标签 ②可删除的标签 ③输入联想浮层 ④拨动字号刻度 ⑤按压倾斜卡片 ⑥长按变录音条。④各家都没做(plan:正文编辑区有,但工具条和字号偏好都得新造,桌面上也没有「键盘顶部」;岗岗:没有字号调节,字号靠clamp()随窗口变)。

                为什么

                组件只是手感的参考,套到没有对应功能的地方就是造新功能:多一个入口、多一条规则、多一处要维护。对应表只是起点,每一项都要回代码核一遍。

                本站例外

                star自身不照这条:屋主2026-10-08要求把合集的交互在star上用遍(原话「把我stars里面所有的逻辑都狠狠的用这些设计合集的内容,纯属炫技」)。总览开头的条目星球、「本书进度」圆环是为了展示新加的,收藏页的标签筛选用的是刷刷撤回的多选版。对其他项目照旧。

                坑

                动了一个组件,要自己grep全仓看同类输入框有没有漏掉(输入法那条就是这么补全的)。改完同一轮改文档:CHANGELOG、规格、README里写着交互的地方。

                出处:tools/star/docs/sources/six-components.md「四家共同规矩」;tools/plan/docs/BUSINESS_LOGIC.md:1836「34. 交互组件轮」;tools/shua/design-proposal.md:392、:559、:601;tools/gang/design-proposal.md:1305「11.1 六个组件的核对表」;tools/card/CLAUDE.md:175;old@4156029 说明.md:129「老站卡片按压反馈」、:144「首页搜索联想、素材卡片按压」;Ysevan_web/docs/xiaowu-ui-spec.md「1.3 明确不存在的元素」(「多选筛选标签」)、「6.6 无障碍与外链」(「不做按压倾斜」)

                大图当主角时,导航栏整条透明:可读性交给整张图的压暗,不交给导航本身

                导航条不画底、不描边、不模糊、不加阴影,直接浮在封面大图上;字看得清,是因为整张图先压了一层60%的黑。主次只靠白的深浅,整条唯一的彩色是右端的绿胶囊。

                本站这里在用总览 · 透明顶栏

                黑罩开着:半透明白链接对比度中位4.8–5.2,刚过4.5

                书生子白 | Home
                • Home
                • Explore
                • Blog
                • ACGN
                • 网站素材
                • Game
                • 主页

                图是老站原图,按相对路径引用、没有拷进合集;加载不到时是深色渐变兜底。链接悬停会变白(点了不跳)。样例窄于910px时品牌字单独一行、链接按宽度换行;老站自己在窄屏上是汉堡菜单。

                数值 / 代码

                导航条  .fh5co-nav-style-1 { position: absolute; z-index: 8; width: 100%; margin-top: 40px; }
                        没写 top(落在页面最顶);没写 background、box-shadow、text-shadow、backdrop-filter
                        ≤768时 margin-top: 20px;滚动后不变色、不加底、不固定,跟着页面滚走
                黑罩    .fh5co-cover-style-2 > .fh5co-overlay {
                          position: absolute; top: 0; right: 0; bottom: 0; left: 0;
                          background: rgba(0, 0, 0, .6); z-index: 4;       /* 压的是整张封面图,导航浮在它上面 */
                        }
                品牌字  字号25px / 字重700 / #fff,"Montserrat", Arial(网络字体从没加载过,实际画出来是 Arial)
                链接    字号16px / 字重400 / rgba(255, 255, 255, .5);margin 0 15px,padding 10px 0(≤992时 margin 0 5px)
                        悬停与当前页 #fff;全站 a { transition: all .5s ease }
                胶囊    background: #58ca7e; border: 2px solid #58ca7e; border-radius: 30px; padding: 2px 15px; color: #fff;
                        悬停 #45c46f;字重没加粗
                对比度  像素法(1440×900),逐个字形像素对它身后的真实底色(中位 / 最差5%)
                        有黑罩        品牌与当前页纯白16.4 / 14.5;半透明白链接4.8–5.2 / 4.6–5.1
                        去掉黑罩      半透明白链接2.8–4.0 / 2.35–3.7
                        去掉黑罩、只加 text-shadow: 0 1px 2px rgba(0, 0, 0, .6)   半透明白链接4.0–4.9(中位)
                        图上最亮那块光斑,有黑罩时半透明白也只有2.7
                        胶囊白字对 #58ca7e   2.07:1

                用在哪

                老站「书生子白」首页Blog/Home.html(约2021年,页脚写着「© 2021 书生子白」),同一条导航也在Explore、Blog、ACGN三页顶上。模板是FREEHTML5.co的「Drag & Drop Cards」。右端「网站素材」一项和中、右两栏5:4的比例是2026-09-25整理老站时加的,透明做法、字、胶囊都是原版。本站总览开头借了这条:≤900时顶栏压在星野上整条透明。

                为什么

                图是主角:导航不占面积、不画边,整张封面从页面最顶铺满,看上去就是一张图上写了几个字。主次只靠白的深浅——品牌和当前页纯白,其余半透明白,悬停才亮起来;整条唯一的彩色是右端的绿胶囊,眼睛自然落到「回主页」上。

                与液态玻璃的对照

                老站透明导航与液态玻璃顶栏的对照
                老站透明导航(本条)液态玻璃顶栏、侧栏(四个工具与本站)
                导航自己画什么什么都不画:透明,无描边、无模糊、无阴影半透明玻璃底,用backdrop-filter把身后糊掉(本站侧栏blur(30px) saturate(160%)),顶边一条亮线
                字靠什么看清整张封面图先压一层rgba(0,0,0,.6);导航只出现在这张压暗的图上身后糊掉、再叠一层半透明底,压什么内容都读得清
                适合首屏一张大图当主角、导航只在图上出现的封面页、名片页内容会从导航底下滚过去的工具页、长页面;导航要一直钉在视口上
                代价图被压暗六成;半透明白链接有黑罩才刚过4.5,去掉黑罩只剩2.8–4.0;图最亮处有黑罩也只有2.7。换一张更亮的图就要重调压暗模糊要逐帧合成,屋主那台没显卡的台式机(2040×1019,软件渲染)上它就是性能瓶颈:联想浮层挂上磨砂后整页帧间隔P95从16.7ms翻到33.4ms、长帧从0个涨到34–52个。所以磨砂只给视口大小的面,条目卡和正文不挂

                上面我画框的这个透明背景可以值得我们后面学习使用,可以保存工具架的star里面

                屋主,2026-09-27(控制室转述;框的是老站书生子白首页顶上这条导航栏)

                坑

                半透明白链接全靠黑罩才擦过4.5:照抄「透明导航加半透明白字」却不压图,对比度直接掉到2.8–4.0;只给字加阴影补不回来(中位4.0–4.9,最差5%只有3.1–4.1)。要么整张图压暗,要么链接用纯白。胶囊白字对#58ca7e只有2.07:1,照抄时要么记成审美例外(和主按钮白字同一口径:记录不断言),要么把绿色压深。老站四页都没写<meta name="viewport">:真手机上按980px宽排版再整页缩到四成左右,导航里品牌字和ACGN各折成两行。老站main.js里那段「滚过500px就把头部钉到顶上」的windowScroll只定义、从没被调用过:这条导航从来都是跟着页面滚走的,别把「滚下去钉住变实色」当成它原本的样子。

                出处:old@4702be0 Blog/Home.html:48–70(导航)、:72(封面与背景图)、:150「© 2021」;old@4702be0 Blog/css/cards.css:611「NAV STYLE #1」、:693「call-to-action」、:945「COVER STYLE #2」、:954(黑罩)、:18「body」、:55「a」;old@4702be0 Blog/js/main.js:174「Window Scroll」;old@4702be0 Blog/css/style.css:4(模板名);old@b516adc「整理老站」(加「网站素材」一项);tools/gang/design-proposal.md:1401「11.6 为什么不加磨砂」;tools/plan/docs/design/SPEC-apple-glass.md:88「4. 自适应」(台式无显卡)、:123(磨砂只放视口大小的表面);对比度为2026-09-27无头Chrome像素实测

                弹窗 · 屋主收集

                屋主2026-10-08收集的六种弹窗交互,原出处未知。每条一块手机比例的舞台:点舞台里的按钮打开,Esc、关闭按钮或点面板外面关上,关上后焦点回到打开按钮;「重放」从头再放一遍。数据全是示例。原文的「错开4帧」「错开1帧」按60Hz折成毫秒写死:4帧=66.7ms,1帧=16.7ms。每条的「用在哪」逐个项目核过:下发三处,2026-10-08都已落地——travel订单卡翻面出示编号、岗岗速查卡「材料已备齐」小圆环、刷刷结算页分数圈;毛玻璃浮层哪儿都不用,刻度尺、照片抽屉、下拉展开没有对口的落点。

                毛玻璃浮层:背景由清楚糊到26px、面板从0.94浮起,12个月份格错开4帧依次灌满,1秒收完

                Frosted Glass Sheet。背景只糊不压暗,靠景深把面板托出来;.42的白底只有压在糊开的背景上才读得清,模糊和面板是一套。代价是没显卡的机器上最贵的那种动画,实测在下面。

                本站这里在用全站 · 背景模糊全站 · 更多面板

                示例App2026(示例)

                年度账本

                本年已用(示例数据)¥0,000.00
                • 示例条目A¥000
                • 示例条目B¥000
                • 示例条目C¥000

                「降级做法」打开时:背景不模糊,改成压暗淡入;面板底从.42提到.96。和做不出磨砂、用户要求减少透明度时是同一套样子。切换后点「重放」对比打开过程。

                点舞台里的「查看12个月用量」打开;Esc、右上角关闭或点面板外面关上。

                数值 / 代码

                原文    背景 backdrop-filter 模糊从0过渡到26px
                        面板底 rgba(255,255,255,.42),从0.94放大到1浮起
                        12个月份格按已用比例从底部填充,每格错开4帧,cubic-bezier(.2,.7,.2,1),1秒内完成
                折算    按60Hz写死:4帧 = 4 × 16.7ms = 66.7ms
                        单格时长 = 1000 − 11 × 66.7 = 266.7ms:第12格在第1000ms收完
                背景层  -webkit-backdrop-filter: blur(0px) → blur(26px);   /* 前缀在前、标准在后 */
                        backdrop-filter: blur(0px) → blur(26px);
                        transition: backdrop-filter 1s cubic-bezier(.2,.7,.2,1)
                面板    transform: scale(.94) → scale(1),.6s 同一条曲线;opacity .3s
                        深色面板底 rgba(40,42,52,.42)(本页配的:同透明度,取外壳深色玻璃的底色)
                月份格  .fill { transform: scaleY(0); transform-origin: 50% 100% }
                        .is-open .fill { transform: scaleY(var(--r));
                          transition: transform 266.7ms cubic-bezier(.2,.7,.2,1) calc(var(--i) * 66.7ms) }
                关闭    统一 .3s 收回,不带 delay、不倒放
                降级    背景 rgba(20,24,36,.28)(深色 rgba(0,0,0,.5))opacity 0 → 1,面板底 .96
                        @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)))
                        与 prefers-reduced-transparency: reduce 走同一套

                实测代价

                2026-10-08本机无头Chrome实测,打开那1秒的整页rAF帧间隔,四种做法交替各跑3次合并(每种约177个间隔);另一遍开tracing量合成器每帧画多久(viz Display::DrawAndSwap)。判据只看和基线的相对差。

                毛玻璃浮层四种做法的实测
                2040×1019@1.25,软件合成帧间隔中位P95>25ms长帧合成器每帧(中位/P95)相对基线
                原样:模糊0→26px过渡16.716.803.5/5.5ms2.9倍
                模糊固定26px、只淡入16.716.704.0/6.5ms3.3倍
                降级做法:不模糊、压暗淡入16.716.701.6/3.1ms1.3倍
                基线:同一面板动画,背景不加东西16.716.801.2/3.4ms1
                红探针:基线+每帧空转30ms33.333.578——

                同一档在负载更高时又量了一遍:合成器每帧中位原样8.9、固定模糊10.5、降级5.3、基线1.7ms,排序不变。417×750@3.5走GPU:四种做法帧间隔都是16.7/16.8、长帧0,合成器每帧0.1–0.2ms,分不出差别。

                读法:这台Mac的CPU快,软件合成下四种都没掉帧;看得出的是相对代价——打开那1秒,模糊让合成器每帧的活多出约3–5倍。屋主台式机CPU慢得多,又是WARP软件渲染,同样的倍数落在16.7ms的预算上就可能掉帧(推断,没在那台机器上量)。无头Chrome每帧整屏重画,比有窗口时悲观,数字只当相对代价看。「模糊固定、只淡入」并不省:淡入期间每一帧仍按满26px重算整块模糊,比半径从0涨上去还贵一点。

                推荐:要降级就直接不模糊——背景改压暗淡入、面板底提到.96(上面「降级做法」开关就是这一套,和做不出磨砂、用户要求减少透明度时同一个样子),代价接近基线,丢掉的是磨砂的景深。什么条件下降级是屋主/控制室的设计决策,可选:一律不降级;判出是软件合成就降级(WebGL failIfMajorPerformanceCaveat建不起来、或渲染器名是SwiftShader/WARP,代价是探测一次、显卡被禁用的快机器也会被降);第一次打开时量帧、掉帧了以后再降(第一次照样卡);一律降级(谁都看不到磨砂)。

                用在哪

                哪儿都不用(控制室2026-10-08定)。它要的是「按月份看的一年用量」,六个项目都没有;它的招牌又是整页背景模糊,正是屋主没显卡那台台式机的瓶颈(上面实测)。

                • 刷刷:学习统计只有「按周回看」「累计统计」两个页签,按月看一年等于新造统计视图。
                • 岗岗:业务手册没有时间维度。card:没有用量。
                • plan:任务详情已经是「遮罩压暗+对话框从.96放大到1」,浮起那一半现成,缺的正是背景模糊;回顾页只看一周,统计图表明写不做。
                • travel:一趟旅行1–60天,没有按月的东西;弹窗遮罩已经是blur(5px)。
                • 小屋:规格写明不存在弹窗和数据看板。

                star自身是例外(见「只升级已有交互」):「更多」面板的遮罩用这一条;外观里的「背景模糊」分段(自动/开/关)就是这条的降级档。

                为什么好看

                背景糊开和面板浮起同时发生,视线的焦点从「背景」移到「面板」,不用压暗也分得清前后。12格错开4帧,用量高低变成从左往右的一道波,比12格同时长出来更容易一格一格看清;曲线前快后慢,第一眼就看到大致高度,后段只是落定。

                要注意的地方

                backdrop-filter半径的过渡不在合成器上:每一帧都要按新半径把整块背景重新模糊一遍,没显卡的机器上它就是整页的瓶颈(上面实测)。.42的白底离不开模糊:降级去掉模糊时,面板底要同时提到近乎不透明,否则字压在清楚的背景上读不清。错开写成transition-delay,单格时长要跟着格数重算,最后一格才能正好1秒收完。关闭时去掉delay统一收回,否则要等最后一格倒着退完。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):刷刷tools/shua/app.js:3243「renderStats」;plantools/plan/app/src/App.css:2318「.detail-dialog-backdrop」、tools/plan/docs/BUSINESS_LOGIC.md:1822「33.6 明确不做」;traveltools/travel/PLANNER.md:31、tools/travel/planner/app.css:965;小屋Ysevan_web/docs/xiaowu-ui-spec.md「1.3 明确不存在的元素」(「广告位、弹窗」)

                圆环计数弹出:面板先落定,圆环再画到剩余比例,中心数字跟着同一条曲线滚到目标值

                Ring Count Sheet。底部面板0.5秒从屏幕外升到位,背景压暗到40%;落定后圆环用同一条曲线1.2秒画到剩余比例,中心数字同步从0滚上去。

                本站这里在用总览 · 本书进度

                示例健身10月(示例)

                本月课程

                下一节(示例)周三19:00
                • 示例课程A00:00
                • 示例课程B00:00
                • 示例课程C00:00

                打开后先看面板升到位,再看圆环和中心数字一起走:数字读到几,圆环就正好画到几分之几。

                数值 / 代码

                原文    底部面板 cubic-bezier(.2,.7,.2,1),0.5秒从屏幕外升到位;背景压暗到40%
                        落定后圆环 stroke-dashoffset 用同一条曲线1.2秒画到剩余比例,中心数字同步从0滚到目标值
                面板    transform: translateY(105%) → translateY(0),.5s
                遮罩    background: #000; opacity: 0 → .4,.5s
                圆环    <circle pathLength="100">  stroke-dasharray: 100 100
                        stroke-dashoffset: 100 → 35(剩26 / 共40 = .65)
                        transition: stroke-dashoffset 1.2s cubic-bezier(.2,.7,.2,1) .5s   /* delay .5s = 面板落定 */
                数字    不另起时钟,每帧读圆环那条过渡自己的 currentTime:
                        const t = getTiming();  p = (anim.currentTime − t.delay) / t.duration
                        num.textContent = Math.round(26 × bezier(.2,.7,.2,1)(p))
                        anim.finished 之后再写一次终值;不用 setInterval

                用在哪

                只借圆环那一半;「底部面板升起、背景压暗」只在本来就是底部面板的地方有意义。

                • 刷刷 · 结算页分数圈 已落地(3.14.0,offline 63c902c) renderSummary()里的.summary-score:原来是154px的圆、12px满圈实边,永远是满的,不表达分数;现在按得分画出一段弧、中心分数从0滚上来(1.2秒,数字每帧读弧那段动画的进度),页面不增元素;做完每一轮都落到这页,屋主天天看。同一轮把结算页这块长面板的blur(24px)去掉(错题多时很长,刷刷自己的规矩是长面板不加磨砂)。首页「今日目标」环不跟着改:首页每次回来整页重绘,环每次重画是噪音。
                • 岗岗 · 速查卡「材料已备齐」小圆环 已落地(岗岗4eb7ac5) renderAside()里的.qc-docs,原来是一行等宽字「已备齐3/7」;现在它和正文勾选卡卡头都是小圆环(卡头28、速查卡44,都乘--u),勾选时从当前位置画到新值。下发时说的第三处要点条已随右栏在v1.8.0取消,没有了。速查卡在阅读工具抽屉里,形态现成。小SVG允许用stroke-dashoffset,前提是A/B测帧率过关(岗岗按这条在屋主台式机那一档测过)。
                • travel · 「行程与导出」里的旅行费用:可以做,没下发。「已填写¥X/预算¥Y」+原生进度条+余量一行,全部项目里最直白的「剩余多少」。超预算要满圈转红、不能画过一圈;「未填费用不计入」那行字要留;没设预算不出环。
                • plan · 汇总卡:不改圆环。今日页「今天要做」和全部任务页「进行中」是同一个SummaryCard,数和比例都对口,但屋主2026-10-08看样张后定了「一个大数字+一条进度」,照这个留着,也不出二选一样张;plan的数字首次渲染不跳,和「中心数字从0滚上去」正相反。
                • card:十三张都已收藏,没有「剩余」。小屋:规格禁数据看板。
                • 本站 · 总览「本书进度」 点开弹出这个圆环,数的是写完的章节;整个面板都借了,是star的例外(见「只升级已有交互」)。

                为什么好看

                两个动作排队:面板先落定、眼睛跟到位置,圆环才开始画,注意力不被同时抢走。圆环和数字同一条曲线、同一个起点,数字读到几,圆环就画到几分之几,不会出现数字先到、环还在走。底部面板只占下半屏,背景压暗就分得清层次,用不着模糊。

                要注意的地方

                stroke-dashoffset不在合成器上,每帧都要重画这条弧;面积小、代价不大,但它不是transform或opacity。数字别用setInterval:那是另一只时钟,和圆环各走各的,后台标签页、掉帧时就对不上;读圆环过渡自己的currentTime,暂停、拖进度两边也一致。数字在滚的时候不播报,读屏读面板里另写的一句「剩余26次,共40次」。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):刷刷tools/shua/app.js:2085「renderSummary」、tools/shua/design-proposal.md:605「十二、结算页分数圈(3.14.0)」(offline 63c902c);岗岗tools/gang/app.js:1249「qc-docs」、:691「check-progress」、tools/gang/design-proposal.md:1707「16. 材料进度小圆环」;traveltools/travel/planner/JourneyOutputs.tsx:149「budget-total」;plantools/plan/app/src/components/cards.tsx:12「SummaryCard」、tools/plan/docs/BUSINESS_LOGIC.md:1874「35.2 规则」第1条、tools/plan/app/src/components/BumpNumber.tsx:5「首次渲染不跳」

                刻度尺进度弹出:53根周刻度逐根变深,走到今天换成强调色停住;编号原地逐字展开,行高不动

                Tick Ruler Sheet。面板滑入后,一年53周从左到右逐根变深,每根错开1帧;点「显示」,被遮住的编号在原地一个字一个字露出来。

                本站这里在用总览 · 更新记录

                示例会员2026(示例)

                今年

                示例「今天」第41周
                • 示例权益A00
                • 示例权益B00

                面板到位后刻度开走,走到「今天」那根停住。点「显示」看编号逐字露出:整块面板一个像素都不跳;读屏在展开完播一次完整编号。

                数值 / 代码

                原文    面板从下方滑入后,53根周刻度从左到右逐根变深,每根错开1帧,走到今天这一格换成强调色并停住
                        点「显示」,被遮住的编号在原地逐字展开,行高不变
                折算    按60Hz写死:1帧 = 16.7ms;示例「今天」= 第41周
                        → 前40根变深,第41根换强调色,后12根不动;41根走完约 .5s + 40 × 16.7ms + .24s ≈ 1.41s
                面板    同上一条:translateY(105%) → 0,.5s cubic-bezier(.2,.7,.2,1)
                刻度    .tick { opacity: .16 } → 走过的 .78
                        transition: opacity .24s cubic-bezier(.2,.7,.2,1) calc(.5s + var(--i) * 16.7ms)
                        今天那根另叠一层强调色:opacity 0 → 1,同一个 delay
                编号    每个字一个槽:display: inline-block; width: .62em; height: 1.5em(等宽字体,先占好最终宽高)
                        遮住时是「•」;展开时「•」上移淡出、数字从下方淡入:每字 .2s,错开50ms(3帧,本页定的)
                读屏    遮住时只读「编号已隐藏」;最后一个字落定后 aria-live 播一次「编号0000 1234 5678」

                用在哪

                没有对口的落点。它要的是「一年按周的进度」和「要遮住再出示的编号」,六个项目都对不上。

                • 刷刷:「按周回看」是一周一屏8格、左右翻周,没有一年53周的视图,也没有要遮住的编号;做就是新造年视图。
                • plan · 回顾页页头「本周 · 2026年第39周」形似:能换成53根刻度走到本周停住,但刻度只说「一年过了多少」,要说做了多少就成了明写不做的统计图表。价值低。
                • travel · 出门看行程标「接下来 · 第i站」形似:一天就几站,高亮那一站已经够用。
                • 岗岗:办理指引只有四个环节,四根刻度就是现在的步骤条;交易码是柜员自己输系统用的,没有遮住的理由。card:十三张卡全摆在Cover Flow上,用不着刻度。小屋:不对口。
                • 「遮住编号、逐字展开」唯一用得上的是travel的订单编号,并进「原地翻面」那条,而且出示时多一步,不建议放。

                star自身是例外(见「只升级已有交互」):总览的「更新记录」点开弹出53周刻度尺。

                为什么好看

                一年53周一字排开,走过的变深、今天那根用强调色停住,「过去多少、还剩多少」不用读数字就看得出。每根只差1帧,41根约0.7秒扫完,快到像一道光扫过去,又慢到看得出是从左往右走。编号在原地露出来,宽度和行高事先占好,面板不跳,眼睛不用重新找位置。

                要注意的地方

                逐字展开别直接改textContent:「•」和数字宽度不同,会挤动后面的字、可能换行。每个字先占好最终的宽和行高,换字只动opacity和transform。读屏不要逐字播:遮住时读「编号已隐藏」,展开完再用aria-live播一次完整编号。「今天」跟日期有关:真实页面验收要把页面时钟拨到固定日期,否则判据每天都在变(这里写死第41周)。错开写死成毫秒,120Hz屏上按时间走、不按帧走。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):刷刷tools/shua/app.js:3202「renderWeekBoard」;plantools/plan/app/src/pages/WeekReview.tsx:77「week-review-title」;traveltools/travel/planner/TodayBoard.tsx:16「upcoming」

                照片抽屉弹出:照片从1.08缩回1铺满,抽屉压住照片底边22px推上来,进度条随后涨到剩余比例

                Photo Drawer Sheet。上半部是照片,暗角托住白色大字;下半部抽屉用负外边距压在照片上,从下方推入,最后进度条才涨。

                本站这里在用收藏 · 卡片详情

                示例旅行12月(示例)

                行程

                进行中(示例)青山线
                • 示例站点A第6天
                • 示例站点B第7天

                照片是old/background/bg-3.jpg(老站背景图里的一张山景,没有人像),按相对路径引用、没拷进合集;只取上部的天空和山。加载不到时照片框是一道蓝灰渐变。

                数值 / 代码

                原文    上半部照片按原比例从1.08缩回1、铺满,暗角托住白色大字
                        抽屉 margin-top: -22px 压住照片底边,从下方推入,随后进度条从0涨到剩余比例
                照片    background-size: 150% auto(按原比例铺满,只取上部)
                        transform: scale(1.08) → scale(1),.8s cubic-bezier(.2,.7,.2,1)
                暗角    radial-gradient 四周压到 rgba(0,0,0,.42) + 底部 linear-gradient .62 → 0;白字放在左下最暗处
                抽屉    margin-top: -22px(360宽的舞台上;舞台按容器缩放时同比例)
                        transform: translateY(100%) → 0,.55s,delay .12s
                进度条  transform: scaleX(0) → scaleX(calc(9 / 14)),.8s,delay .6s(抽屉到位之后)
                曲线    原文只写了照片和抽屉的动作,没写曲线;沿用 cubic-bezier(.2,.7,.2,1)
                兜底    照片框自己的底色是一道渐变,图加载不到时露出来

                用在哪

                没有对口的落点。它要的是「有一张主图的详情,外加一个剩余比例」。

                • travel · 照片与日记:日记卡有照片、标题、时间、正文,主图有了,但只有列表卡、没有点开的详情;照片抽屉是「打开详情」的动画,要先造详情视图,算新功能。订单里的票券截图是文字截图,裁切压字会挡信息。
                • card · 查看器:是独立页面不是弹窗,「05/13」是第几张、不是进度;把画放大裁切再压白字,和「整张卡要看全」相冲突。
                • 小屋 · 随笔:配图在正文末尾,正文才是主角;照片铺满、白字压暗角是苹果风的做法,小屋用暖纸。
                • 岗岗:截图是系统界面、含客户信息,不能当主图、不能裁切压字。刷刷、plan:没有图。

                star自身是例外(见「只升级已有交互」):收藏卡的「详情」是居中大对话框加这个照片抽屉。

                为什么好看

                照片从1.08缩回1,像镜头往后退一步把景收进来,这就是「打开」的动作。抽屉压住照片底边22px,上下两块像叠在一起的两张纸,不像拼起来的两个框。暗角从四周和底部压暗,白字放在最暗的一角,换一张照片也读得清。进度条最后才涨,视线顺序是图、标题、数字。

                要注意的地方

                照片缩放要在overflow:hidden的框里做,框的圆角才裁得住放大的图。抽屉压住的那22px里不能放字:标题的下边距要把这一截让出来。图要有兜底:加载不到时照片框露出底色渐变,白字照样读得清。白字压照片的对比度看图:换一张更亮的照片要重测暗角够不够。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):traveltools/travel/planner/PersonalHub.tsx:1179「personal-journal-card」

                原地翻面面板:绕Y轴翻180度,翻过90度那一帧换面,背面是出示用的编号;再点沿原路翻回

                Flip to Reveal。透视1200px,曲线cubic-bezier(.3,.7,.2,1),0.8秒。翻面是「同一张卡的另一面」,比再弹一个框更说明这是同一件东西。

                本站这里在用收藏 · 翻面卡

                示例会员卡包(示例)

                卡包

                示例会员卡1,234积分
                • 示例优惠券A0张
                • 示例优惠券B0张

                点卡片翻面,再点翻回;键盘Tab到卡片按空格或回车。翻到一半再点,会从当前角度沿原路翻回去。

                数值 / 代码

                原文    perspective 1200px,绕Y轴翻180度,cubic-bezier(.3,.7,.2,1),0.8秒
                        翻到90度时切换正反面;背面显示出示用的编号和完整信息,再点一次沿原路翻回
                场景    .scene { perspective: 1200px }(360宽的舞台上;舞台按容器缩放时同比例)
                卡片    .card { transform-style: preserve-3d; transform: rotateY(0deg);
                                transition: transform .8s cubic-bezier(.3,.7,.2,1) }
                        .is-flipped .card { transform: rotateY(180deg) }   /* 再点去掉类名 = 原路翻回 */
                两面    .face { backface-visibility: hidden }   .back { transform: rotateY(180deg) }
                换面    看得见的:backface-visibility 在过90度那一帧自动换
                        读屏这边:每帧读 computed transform 的角度,过了90度就把看不见的一面设 aria-hidden + inert
                90度在哪一刻  这条曲线 y = .5(x ≈ .188)→ 0.8s × .188 ≈ 150ms(前快后慢,不是0.4秒)
                减弱动效  不转,两面原地淡入淡出(data-rm="fade")

                用在哪

                • travel · 订单卡翻面出示编号 已落地(travel 5bf5497) 「我的随身旅行本」里的订单卡(BookingCard):原来「编号:…」是一行小字,票券截图在卡底;现在点卡片或「出示编号」原地翻面,背面是放大的订单 / 确认编号连同票券截图,没有编号也没有截图的订单不给翻。全部项目里只有这里有「到前台、检票口要出示」的编号(字段confirmation,校验名「订单编号」)。数值照这一条:perspective 1200px、0.8秒、cubic-bezier(.3,.7,.2,1),90度换面。翻面只动rotate,出示多在手机上,不压没显卡的台式机。两面高度不同:同一时间DOM里只有一面,卡高跟着正在显示的那一面走。
                • card:已经有,而且更好。查看器有「翻看背面」按钮和F键,three里整张卡转180°,CSS翻面只会是降级。
                • 刷刷:题卡翻面看答案看似对口,但解析要和题干一起看,翻过去题干就没了;题卡已有滑动切题的transform,会打架。
                • 岗岗:交易码给柜员自己输,不给别人看。plan、小屋:没有要出示的编号。
                • 本站 · 收藏的翻面卡 skill、项目、提示词这几类收藏:正面一句话说它是什么,翻过来看效果截图。

                为什么好看

                翻面让人知道背面的编号和正面是同一张卡,不是另一个东西。透视1200px够远,翻的时候梯形变形不夸张。曲线前快后慢,不到五分之一的时间就翻过90度,剩下的时间慢慢落定,看起来是被「甩」过去再稳住。

                要注意的地方

                读屏不跟视觉走:backface-visibility只管画面,看不见的那一面读屏照样读得到,要在同一时刻设aria-hidden和inert。翻面区是真<button>,盖在整张卡上,空格回车能翻;卡上的字不包进按钮。按这条曲线,90度出现在第150ms左右,验收别照「0.4秒切换」去卡。翻到一半再点,CSS过渡会从当前角度原路返回,不用另写状态机。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):traveltools/travel/planner/BookingCard.tsx:27「BookingCard」、:122「出示编号」、tools/travel/planner/flip-timing.mjs:55「FLIP_PERSPECTIVE」、tools/travel/planner/PersonalHub.tsx:720「BookingCard」、tools/travel/planner/personal-model.mjs:168「订单编号」;cardtools/card/collection/shared/viewer.js:345「flip」

                下拉展开面板:拖把手把下半张沿虚线撕开,跟手下移带2度摆动,过40%松手展开、不到就弹回

                Pull Down Reveal。面板从底部弹入落定,下沿留一截把手和一条虚线;往下拉,完整信息从撕开的缝里露出来。键盘有替代:把手按↓展开、↑或Esc收回。

                本站这里在用交互 · 长代码展开

                示例票夹12月(示例)

                票夹

                示例演出12月31日
                • 示例场次A00:00
                • 示例场次B00:00

                按住票券下沿的把手往下拉:不到40%松手弹回,过了就展开。键盘:Tab到把手,↓/空格/回车展开,↑或Esc收回;也可以点「展开完整信息」。

                数值 / 代码

                原文    面板从底部弹入落定,下沿留一截把手和一条虚线
                        向下拖动把手时,下半张沿虚线分离,跟手下移并带2度摆动,超过40%松手就展开露出完整信息,不到就弹回
                弹入    transform: translateY(560px) → 0,.6s cubic-bezier(.3,1.35,.5,1)(轻微过冲,原文没给曲线,本页定的)
                拖动    pointerdown + setPointerCapture;拖动中 transition: none,每次 pointermove 直接写
                        transform: translateY(y) rotate(r)
                        p = y / 124(能拉开的距离,360宽的舞台上)
                        r = clamp(2 × sin(min(p, 1) × π) + dx × .04, −2, 2) 度   /* 先歪后正,左右拖再加一点 */
                松手    p > .4 → 展开:.45s cubic-bezier(.2,.7,.2,1)
                        p ≤ .4 → 弹回:.5s cubic-bezier(.3,1.35,.5,1),转角一起回0,带一点过冲
                键盘    把手是 <button>:↓/空格/回车展开,↑/Esc收回;另有「展开完整信息」按钮(aria-expanded)
                手机    把手 touch-action: none,拖动不会变成滚页面

                用在哪

                没有对口的落点。它要的是票据式的「存根+完整信息」。

                • travel · 订单卡形似:存根是类别、名称、时间,拉开是编号、备注、截图。但卡在可滚动的弹窗里,往下拖和滚动抢同一个手势,电脑上还得用鼠标拖。和「原地翻面」二选一,选翻面(点的更稳),两个不叠在同一张卡上。
                • 刷刷 · 结算页错题回顾每道是<details>,点开看解析:改成拖开会和滚动打架,错题又常是一长串。岗岗 · 勾选卡的「原文」折叠(.check-source)同理,点开比拖开好。
                • plan、card、小屋:没有票据形态。

                star自身是例外(见「只升级已有交互」):页面里过长的代码块先收起一截,照这一条下拉展开。

                为什么好看

                把「看完整信息」做成撕开一张票:虚线告诉人哪里能分开,下半张跟着手走、带一点摆,像真的纸。过线才展开、不到就弹回,松手那一刻结果是确定的,不会停在半路。

                要注意的地方

                拖动一定要有键盘替代:把手本身是能聚焦的按钮,另有「展开完整信息」按钮,两处的aria-expanded一起变。拖动中关掉过渡、直接跟手,松手才按结果给过渡;没拖动的按下抬起交给click,拖过的那一下要吞掉随后的click。Esc先收起下半张,再按才关面板:一下只退一层。把手要touch-action:none,否则手机上一拖就成了滚页面。减弱动效下拖动照样跟手,松手直接到位、不弹。

                出处:屋主2026-10-08收集,原出处未知。落点核对(行号2026-10-09按当时各仓库的提交重核;全文见tools/star/docs/落点-六种弹窗.md「二、按弹窗逐条」「六、控制室裁定」):刷刷tools/shua/app.js:2125「renderSummaryWrongQuestion」;岗岗tools/gang/app.js:691「check-source」