Voice 设置
标题与说明属于正文,不在顶部再造 main-title。
Voice
根页面路径直接从 Voice 开始,不显示 Apps / Voice。
正文卡片从 44px 以下开始。
继续向下滚动,Host Title Bar 保持不动。
页面级动作进入右侧 Host 图标堆栈。
main-body 是唯一纵向滚动容器。
这一页是规范的验收基准:文字规定的每一档在这里都真实画了出来。
做插件时对着看,比读数字准得多。所有取值来自 Host 的 design-base.css,
不是另起炉灶的第二套系统。
看数值,别抄写法。
这一页为了单文件能直接打开,用了大量内联 style="…" 和内联 <script>。
真插件不能这么写——插件页面的 CSP 只放行带 nonce 的样式和脚本,
没有 unsafe-inline,内联样式属性会被直接拦掉。
样式一律写进插件自己的 .css,脚本走打包后的 ESM 模块。
顶部 44px 由 Host 渲染返回、面包屑、拖拽区、App 动作与通知;插件 DOM
只从下方可滚动 main-body 开始。设置页中设置按钮保持按下,再点同一按钮返回 Voice;
也可点返回或 Voice 验证路径切换;
在正文里滚动,顶部不会出现第二层页头。
生产 Host 注入 --reai-plugin-titlebar-safe-top:
macOS 为 44px,其他平台为 0px;插件根框架只消费一次,浏览器预览使用
44px fallback。
标题与说明属于正文,不在顶部再造 main-title。
根页面路径直接从 Voice 开始,不显示 Apps / Voice。
正文卡片从 44px 以下开始。
继续向下滚动,Host Title Bar 保持不动。
页面级动作进入右侧 Host 图标堆栈。
main-body 是唯一纵向滚动容器。
这是基础视觉规则:禁止两个不同颜色的全宽大色块零距离硬切;
1px 分割线不算留白。实现只能位于插件自己的 main-body,不能改 Host 或全局样式。
插件跑在隔离的 WebView 里,读不到 Host 的任何样式——这些变量是 Host
主动注入进插件页面的 :root,切主题时再由 Host 逐个改写。
对你来说就一句话:var(--accent) 直接用,不用订阅任何事件。
整页的颜色都是这么来的,点右上角按钮试试。
三色组用法固定:主色画图标和文字,-soft 画背景,
-line 画描边。别拿主色当背景,一块提示会盖过页面主体。
这是本次 Skills 抽屉暴露的直接问题。左边是用键盘上的乘号当关闭按钮, 右边是同一位置的正确做法。虚线框是实际能点到的范围——静态看两颗差不多, 真正的差距在这里。
TOOLS
Skills粗细随系统字体变、对不齐光学重心、点击区只有一个字那么大、
鼠标移上去毫无反应。这颗还算好的——它至少写了 aria-label;
漏写时读屏会直接念出「乘号」。
TOOLS
Skills线宽统一、跟标题基线对齐、44px 可点、有悬停反馈、
读屏念的是「关闭 Skills」。颜色靠 currentColor 自动跟随。
标准档的 2 是对齐 Host 的:它的图标默认就是这个线宽, 标题栏那颗通知铃铛是 15px / 线宽 2。偏离它,插件图标跟 Host 图标并排就会显细。 小尺寸必须加粗——2 的线在 14px 下会糊成一团,这是渲染事实不是审美偏好。
小 · 14px
线宽 2.4
标准 · 16px
线宽 2
大 · 20px
线宽 2
把用得到的图标从 Host 的 icons.ts 摘进页面里的
一段 <defs>,之后处处写 <use href="#reai-icon-名字"> 引用。
名字写错只是空白,不会出乱码,也引不到外部资源。
完整图标表见 Host 的 icons.ts(当前 49 个,lucide 描边风格)。
这里只列常用的。
判据很直白:遮住页面其余部分,单看这颗按钮,说得出它属于哪一档吗? 说不出就是造型跑了。
主 · 一屏最多 1 颗
36px 高 / 圆角 10
次 · 数量不限
36px 高 / 圆角 10
图标 · 工具条 / 关闭
32px 见方 / 圆角 8
进行中 · 禁用 + 改文案
别让人连点三次
虚线是实际点击范围——用透明外扩撑开,不要靠缩小点击区来让按钮显瘦。 触控板和键盘用户点不准一颗 18px 的字符,点不准就等于"这按钮坏了"。
一个人随手写 9px、13px 没问题;十个插件各自随手写,并排就是碎的。
分组规则:回答不同问题的两块之间,留白要明显大于组内间距。 组内 8,组间就用 20 或 24——用 10 等于没分组。
一个界面里不超过三档;嵌套时外层圆角必须大于内层, 否则内层的角会顶出去。
点开下面这个抽屉,然后分别试:点关闭按钮、按 Esc、点左侧灰色遮罩—— 三种都能关。再用键盘试一遍:打开后焦点直接进抽屉,Tab 只在抽屉内循环、不会跑到后面的页面上, 关掉之后焦点回到原来那颗按钮,不用从头 Tab 一遍。
这里是插件的主内容区。
宽度 min(360px, 100% - 24px),内边距 24,
遮罩 rgba(20,18,40,.3) + 5px 模糊,滑入 120ms。
系统开了「减少动态效果」时直接显示,不做动画。
⚠️ 这里是页内演示:遮罩只盖住上面这块演示区,不像真插件那样铺满整个界面。
所以用鼠标点到演示区外面,焦点就出去了,之后 Tab 不再受约束。真插件里遮罩铺满整屏,
同时还应该给页面其余部分加 inert,读屏用户才不会读到抽屉背后的内容。
缺一种,用户就会遇到"一片空白,不知道是在加载还是坏了"。
加载中
超过 400ms 才显示,
否则一闪而过更晃眼
还没有打开过项目
空
说清为什么空 + 怎么让它不空
连不上 Codex,可能没在运行
失败
说人话 + 给重试,别甩错误码
需要「读取项目列表」权限
无权限
指到「已安装 → 权限」,别自己弹系统框
标题+说明使用两行层级;标题+动态反馈使用内缩分隔。完整规范与验收要求。本例只演示布局,不连接 App、不保存真实设置。
去口头禅、理顺语序,不动原意。
润色需要使用云端 AI。失败或超时,会按原话注入,不会中断输入。
文字注入权限已关闭。请到「已安装 → Voice → 权限」开启文字注入;新的录音会在开始前被拦截。
内边距 16px;标题与说明间隔 4px;反馈 divider 与文字左右对齐、线上下各 12px;策略间隔 12px,策略标题与正文间隔 4px。真实错误独立呈现。
每条都能答「是」才算合格。完整清单见规范正文第 7 节。
aria-label;每颗按钮都有悬停反馈--reai-plugin-titlebar-safe-top,
main-body 填满剩余空间并独立滚动aria-pressed;再次点击真实返回根页