playbook-dsh 0.11.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/bridge.js +23 -2
- package/client.js +44 -2
- package/index.js +6 -2
- package/package.json +3 -3
- package/runtime/build/ui/assets/index-CZsXj_xX.css +1 -0
- package/runtime/build/ui/assets/index-C_Zps-DT.js +18 -0
- package/runtime/build/ui/index.html +2 -2
- package/runtime/desktop/narration.mjs +4 -0
- package/runtime/desktop/presentation/annotation.js +24 -5
- package/runtime/desktop/runner.mjs +25 -7
- package/runtime/examples/tutorial/practice/bridge.ts +4 -0
- package/runtime/package.json +1 -1
- package/runtime/skills/playbook-playwright/SKILL.md +1 -1
- package/runtime/skills/playbook-wright/SKILL.md +1 -1
- package/runtime/skills/playbook-wright/references/installation.md +1 -1
- package/runtime/skills/playbook-wright/scripts/install.sh +3 -21
- package/server.mjs +37 -8
- package/runtime/build/ui/assets/index-BwJxZC7c.css +0 -1
- package/runtime/build/ui/assets/index-Go2NLIlu.js +0 -18
package/README.md
CHANGED
|
@@ -6,24 +6,24 @@
|
|
|
6
6
|
|
|
7
7
|
## 制作与安装
|
|
8
8
|
|
|
9
|
-
Playbook 的 `skills/playbook-wright/scripts/install.sh --install --framework dsh --scope user` 在 DSH Shell 中会识别当前 profile,安装 Skill 后从 npm 注册表安装 `playbook-dsh@0.11.
|
|
9
|
+
Playbook 的 `skills/playbook-wright/scripts/install.sh --install --framework dsh --scope user` 在 DSH Shell 中会识别当前 profile,安装 Skill 后从 npm 注册表安装 `playbook-dsh@0.11.2`。运行中的 DSH Desktop 需要通过插件管理界面安装;安装器会备份 profile 配置,并以退出码 4 提示改在 DSH 内操作。
|
|
10
10
|
|
|
11
|
-
在 DSH 的「插件 → 添加插件」中输入 `playbook-dsh@0.11.
|
|
11
|
+
在 DSH 的「插件 → 添加插件」中输入 `playbook-dsh@0.11.2`,选择 npm 注册表并确认来源、版本。已有从本地 `.tgz` 安装的旧版时,先在 DSH 插件管理界面卸载旧插件,再按包名安装;项目设置和运行记录保存在 `$DSH_HOME/playbook`,卸载插件依赖不会删除它们。DSH 0.2.1-rc.3 尚不提供第三方插件的详情页更新按钮;支持注册表插件更新的 DSH 版本发布后,详情页才能检查新版并提供更新操作。
|
|
12
12
|
|
|
13
13
|
在隔离 Web profile 中也可通过命令安装:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
dsh plugin --profile web add playbook-dsh@0.11.
|
|
16
|
+
dsh plugin --profile web add playbook-dsh@0.11.2
|
|
17
17
|
dsh web
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
插件使用预先发布的 WebAssembly 编译依赖,安装时无需批准 `esbuild` 构建脚本,也无需调整 DSH 的构建脚本权限。安装成功后用 `dsh --profile web --dump-config` 确认出现 `playbook-dsh` 层。
|
|
21
21
|
|
|
22
22
|
维护者在 Playbook 仓库根目录运行 `npm ci`、`npm run desktop:build`,然后在 `integrations/dsh` 运行 `npm pack` 核对待发布内容。`prepack` 会重新收集已构建的 Playbook 运行文件并检查应用、Skill、插件与安装器版本一致;发布到 npm 注册表后,用户按包名安装,以便 DSH 识别注册表来源。
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
插件启动时由系统在本机 `127.0.0.1` 分配空闲端口,页签自动获取当前实例的地址;DSH 与其他发行版可同时运行,无需配置端口。DSH 与受控 Chrome 需要运行在同一台机器;当前版本的 DSH 远程 Web 客户端不能通过远端浏览器控制本机 Playbook。演示使用本机 Google Chrome。项目设置与运行记录写到 `$DSH_HOME/playbook`,与 Electron 版用户数据隔离。插件停用时会请求停止当前演示并等待资源释放回执。
|
|
25
25
|
|
|
26
|
-
页签内提供画面、暂停/继续/停止、手动交接、元素批注、旁白、PPTX 导出和历史记录。PPTX 保存在 `$DSH_HOME/playbook/exports`,可从运行记录下载。添加项目或选择 Skill
|
|
26
|
+
页签内提供画面、暂停/继续/停止、手动交接、元素批注、旁白、PPTX 导出和历史记录。PPTX 保存在 `$DSH_HOME/playbook/exports`,可从运行记录下载。添加项目或选择 Skill 项目目录时会打开 DSH 的文件夹选择窗口;取消选择不会添加项目或写入 Skill。写入 Skill 仍须在界面中查看预览后点击安装。
|
|
27
27
|
|
|
28
28
|
## 验证
|
|
29
29
|
|
package/bridge.js
CHANGED
|
@@ -27,10 +27,29 @@
|
|
|
27
27
|
if (!response.ok) throw new Error(data.error || `${method} 失败`)
|
|
28
28
|
return data.result
|
|
29
29
|
}
|
|
30
|
+
function chooseDirectory() {
|
|
31
|
+
if (window.parent === window) return Promise.reject(new Error('请在 DSH 的 Playbook 面板中选择项目文件夹'))
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const channel = new MessageChannel()
|
|
34
|
+
const finish = (error, directory) => {
|
|
35
|
+
clearTimeout(timer); channel.port1.close()
|
|
36
|
+
if (error) reject(new Error(error)); else resolve(directory)
|
|
37
|
+
}
|
|
38
|
+
const timer = setTimeout(() => finish('无法连接文件夹选择器,请重新打开 Playbook 面板'), 5000)
|
|
39
|
+
channel.port1.onmessage = ({ data }) => {
|
|
40
|
+
if (data?.ready === true) { clearTimeout(timer); return }
|
|
41
|
+
if (data?.error) finish(data.error)
|
|
42
|
+
else if (data?.path === null || typeof data?.path === 'string') finish(null, data.path)
|
|
43
|
+
else finish('文件夹选择结果无效')
|
|
44
|
+
}
|
|
45
|
+
// The request carries no path or token; the host verifies this iframe before replying on the private port.
|
|
46
|
+
window.parent.postMessage({ type: 'playbook:choose-directory' }, '*', [channel.port2])
|
|
47
|
+
})
|
|
48
|
+
}
|
|
30
49
|
const api = {
|
|
31
50
|
getState: () => lastState ? Promise.resolve(lastState) : invoke('getState'),
|
|
32
51
|
onState(callback) { listeners.add(callback); if (lastState) callback(lastState); return () => listeners.delete(callback) },
|
|
33
|
-
async addWorkspace() { const directory =
|
|
52
|
+
async addWorkspace() { const directory = await chooseDirectory(); return directory ? invoke('addWorkspace', { path: directory }) : api.getState() },
|
|
34
53
|
removeWorkspace: input => invoke('removeWorkspace', input),
|
|
35
54
|
removeBook: input => invoke('removeBook', input),
|
|
36
55
|
refreshWorkspace: input => invoke('refreshWorkspace', input),
|
|
@@ -38,6 +57,8 @@
|
|
|
38
57
|
control: input => invoke('control', input),
|
|
39
58
|
showEmbedded: input => invoke('showEmbedded', input),
|
|
40
59
|
annotate: () => invoke('annotate'),
|
|
60
|
+
setNarrationEnabled: input => invoke('setNarrationEnabled', input),
|
|
61
|
+
deleteAnnotation: input => invoke('deleteAnnotation', input),
|
|
41
62
|
setPlaybackSelection: input => invoke('setPlaybackSelection', input),
|
|
42
63
|
async copyAnnotation(input) { const { text } = await invoke('copyAnnotation', input); await navigator.clipboard.writeText(text); return { copied: true } },
|
|
43
64
|
async copyContext(input) { const { text } = await invoke('copyContext', input); await navigator.clipboard.writeText(text); return { copied: true } },
|
|
@@ -49,7 +70,7 @@
|
|
|
49
70
|
if (!input.reveal) { const link = document.createElement('a'); link.href = result.download; link.download = ''; document.body.append(link); link.click(); link.remove() }
|
|
50
71
|
return result
|
|
51
72
|
},
|
|
52
|
-
async chooseSkillProject() { const directory =
|
|
73
|
+
async chooseSkillProject() { const directory = await chooseDirectory(); return directory ? invoke('chooseSkillProject', { path: directory }) : null },
|
|
53
74
|
skillPreview: input => invoke('skillPreview', input),
|
|
54
75
|
skillInstall: input => invoke('skillInstall', input),
|
|
55
76
|
}
|
package/client.js
CHANGED
|
@@ -4,9 +4,51 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
const React = require('react')
|
|
5
5
|
const id = 'playbook'
|
|
6
6
|
return {
|
|
7
|
-
inject: ['slots', 'layout'],
|
|
7
|
+
inject: ['slots', 'layout', 'uiWorkspace'],
|
|
8
8
|
apply(ctx) {
|
|
9
|
-
|
|
9
|
+
function Playbook() {
|
|
10
|
+
const [endpoint, setEndpoint] = React.useState({})
|
|
11
|
+
const [attempt, retry] = React.useReducer(value => value + 1, 0)
|
|
12
|
+
const frame = React.useRef(null)
|
|
13
|
+
React.useEffect(() => ctx.on('connection/reset', retry), [])
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
if (!endpoint.url) return
|
|
16
|
+
const origin = new URL(endpoint.url).origin
|
|
17
|
+
let active
|
|
18
|
+
const receive = event => {
|
|
19
|
+
if (!frame.current || event.source !== frame.current.contentWindow || event.origin !== origin
|
|
20
|
+
|| event.data?.type !== 'playbook:choose-directory' || event.ports.length !== 1) return
|
|
21
|
+
const port = event.ports[0]
|
|
22
|
+
if (active) { port.postMessage({ error: '请先完成当前文件夹选择' }); port.close(); return }
|
|
23
|
+
active = port; port.postMessage({ ready: true })
|
|
24
|
+
Promise.resolve().then(() => window.__DSH_DIRECTORY_PICKER__
|
|
25
|
+
? window.__DSH_DIRECTORY_PICKER__.pick() : ctx.uiWorkspace.pickDirectory())
|
|
26
|
+
.then(directory => port.postMessage({ path: directory }), error => port.postMessage({ error: error?.message || '文件夹选择失败' }))
|
|
27
|
+
.finally(() => { port.close(); if (active === port) active = null })
|
|
28
|
+
}
|
|
29
|
+
window.addEventListener('message', receive)
|
|
30
|
+
return () => {
|
|
31
|
+
window.removeEventListener('message', receive)
|
|
32
|
+
if (active) { active.postMessage({ error: 'Playbook 面板已关闭' }); active.close(); active = null }
|
|
33
|
+
}
|
|
34
|
+
}, [endpoint.url])
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
const controller = new AbortController()
|
|
37
|
+
setEndpoint({})
|
|
38
|
+
void fetch('api/playbook/endpoint', { signal: controller.signal, cache: 'no-store' }).then(async response => {
|
|
39
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
40
|
+
const { url } = await response.json()
|
|
41
|
+
if (typeof url !== 'string' || !/^http:\/\/127\.0\.0\.1:[1-9]\d{0,4}\/$/.test(url) || new URL(url).port === '') throw new Error('无效的播放地址')
|
|
42
|
+
if (!controller.signal.aborted) setEndpoint({ url })
|
|
43
|
+
}).catch(() => { if (!controller.signal.aborted) setEndpoint({ error: true }) })
|
|
44
|
+
return () => controller.abort()
|
|
45
|
+
}, [attempt])
|
|
46
|
+
if (endpoint.url) return React.createElement('iframe', { ref: frame, src: endpoint.url, title: 'Playbook', style: { width: '100%', height: '100%', border: 0, display: 'block' } })
|
|
47
|
+
return React.createElement('div', { style: { padding: 24 }, role: 'status' }, endpoint.error
|
|
48
|
+
? React.createElement(React.Fragment, null, 'Playbook 暂时无法连接。', React.createElement('button', { onClick: retry }, '重试'))
|
|
49
|
+
: '正在打开 Playbook…')
|
|
50
|
+
}
|
|
51
|
+
ctx.effect(() => ctx.slots.inject('main', () => ctx.slots.register({ name: 'main', key: id }, Playbook)), 'playbook main')
|
|
10
52
|
ctx.effect(() => ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({ name: 'sidebar.panellist', id, order: 1, label: () => 'Playbook' }, ({ size }) => React.createElement('span', { style: { fontSize: size * .7 } }, '▶'))), 'playbook sidebar')
|
|
11
53
|
}
|
|
12
54
|
}
|
package/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { startServer } from './server.mjs'
|
|
2
2
|
export const name = 'playbook-dsh'
|
|
3
|
-
export const inject = []
|
|
3
|
+
export const inject = ['connection']
|
|
4
4
|
export async function apply(ctx) {
|
|
5
|
-
const stop = await startServer()
|
|
5
|
+
const { url, stop } = await startServer()
|
|
6
6
|
ctx.effect(() => stop, 'playbook-dsh server')
|
|
7
|
+
ctx.connection.fetch.register({
|
|
8
|
+
path: '/api/playbook/endpoint', methods: ['GET'], requestBody: 'buffered',
|
|
9
|
+
fetch: () => Response.json({ url }, { headers: { 'Cache-Control': 'no-store' } }),
|
|
10
|
+
})
|
|
7
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playbook-dsh",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dsh": {
|
|
11
11
|
"bundle": { "patch": "./cordis.patch.yml" },
|
|
12
|
-
"client": { "platform": "web", "inject": ["@deepseek-ai/dsh-client-ui-layout", "@deepseek-ai/dsh-client-ui-sidebar"] }
|
|
12
|
+
"client": { "platform": "web", "inject": ["@deepseek-ai/dsh-client-ui-layout", "@deepseek-ai/dsh-client-ui-sidebar", "@deepseek-ai/dsh-client-ui-workspace"] }
|
|
13
13
|
},
|
|
14
14
|
"files": ["index.js", "server.mjs", "bridge.js", "client.js", "cordis.patch.yml", "runtime/**", "README.md", "LICENSE"],
|
|
15
15
|
"license": "MIT",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@playwright/test": "1.58.2",
|
|
22
22
|
"driver.js": "1.10.2",
|
|
23
|
-
"esbuild": "0.28.2",
|
|
23
|
+
"esbuild": "npm:esbuild-wasm@0.28.2",
|
|
24
24
|
"jszip": "3.10.1",
|
|
25
25
|
"playwright": "1.58.2",
|
|
26
26
|
"pptxgenjs": "4.0.1",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.narration-toggle{color:#46694f;font:inherit;cursor:pointer;-webkit-app-region:no-drag;background:#f9fcf7;border:1px solid #cbd9cd;border-radius:7px;flex-shrink:0;align-items:center;gap:8px;padding:8px 10px;font-size:12px;display:inline-flex}.narration-toggle-state{color:#526052;background:#e0e5df;border-radius:10px;padding:1px 7px;font-size:11px}.narration-toggle[aria-checked=true] .narration-toggle-state{color:#fff;background:#2e7957}.narration-toggle:disabled{opacity:.55;cursor:default}.narration-toggle:focus-visible{outline-offset:2px;outline:3px solid #83bda7}html.playback-control-window,.playback-control-window body,.playback-control-window #root{min-height:0;overflow:hidden;background:0 0!important}.playback-control-bar{color:#f0f6f3;-webkit-app-region:drag;-webkit-user-select:none;user-select:none;background:#1c302af5;border:1px solid #ffffff2b;border-radius:14px;align-items:center;gap:20px;padding:16px 20px 19px;font-size:13px;display:flex;position:absolute;inset:9px 10px 12px;box-shadow:0 6px 12px #0b1d232d}.control-brand{align-items:center;gap:9px;font-weight:650;display:flex}.control-brand>svg{color:#7adab7;flex-shrink:0}.control-brand>svg.paused{color:#eac77b}.control-caption{flex:1;gap:4px;min-width:0;display:grid}.control-caption small{color:#a6beb2;white-space:nowrap;text-overflow:ellipsis;font-size:10px;overflow:hidden}.control-caption strong{white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;overflow:hidden}.playback-control-bar button{color:inherit;white-space:nowrap;-webkit-app-region:no-drag;cursor:pointer;background:#ffffff0d;border:1px solid #ffffff25;border-radius:6px;padding:7px 11px;font-size:12px}.playback-control-bar button:disabled{cursor:default;opacity:.55}.playback-control-bar .control-size{padding-inline:10px;font-size:15px}.playback-control-bar.is-collapsed{border-radius:12px;gap:13px;padding:10px 13px 12px}.is-collapsed .control-caption{flex:1}.is-collapsed button{min-width:32px;padding:6px 8px}.playback-control-bar button:hover:enabled{background:#ffffff24}.playback-control-bar kbd{font:inherit;color:#a6beb2;margin-left:8px;font-size:10px}#playbook-playback-progress{background:#ffffff14;border-radius:4px;height:3px;position:absolute;bottom:0;left:16px;right:16px;overflow:hidden}#playbook-playback-progress i{background:#8ad4ba;height:100%;transition:width .2s;display:block}:root{color:#293531;font-synthesis:none;-webkit-font-smoothing:antialiased;--accent:#187a69;--accent-hover:#126656;--muted:#86908a;--border:#e4e7e1;--warm:#f7f8f4;background:#f4f5f1;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,PingFang SC,Microsoft YaHei,sans-serif;font-weight:400}*{box-sizing:border-box}body{margin:0}button,input,select{font:inherit}button{cursor:pointer}button:disabled{cursor:default;opacity:.45}button,input,select{-webkit-app-region:no-drag}button{color:inherit}button:focus-visible,input:focus-visible,select:focus-visible{outline-offset:3px;outline:3px solid #43ad9955}button svg{flex-shrink:0}button{transition:background .15s,color .15s,border-color .15s,box-shadow .15s}h1,h2,h3,h4,p{margin:0}h1,h2,h3,h4{font-weight:600}button{background:0 0;border:0}input,select{min-width:0}svg{flex-shrink:0}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-thumb{background:#a4b0a53a;border-radius:8px}::-webkit-scrollbar-track{background:0 0}.app-shell{height:100vh;min-height:600px;display:flex;overflow:hidden}.sidebar{color:#b7c5bc;background:#202d29;border-right:1px solid #13231c;flex-direction:column;flex-shrink:0;width:222px;padding:0 15px 20px;display:flex;position:relative}.traffic-space{-webkit-app-region:drag;flex-shrink:0;height:49px}.brand{color:#f3f7f4;letter-spacing:-.5px;align-items:center;gap:10px;padding:10px 11px 30px;font-size:22px;font-weight:650;display:flex}.brand-icon{color:#eff9f2;background:#287b68;border-radius:11px;flex-shrink:0;place-items:center;width:39px;height:42px;display:grid}.brand span{color:#879b8e;letter-spacing:.1px;white-space:nowrap;margin-top:4px;font-size:9px;font-weight:400;display:block}.sidebar nav{gap:5px;display:grid}.nav-item{text-align:left;color:#aebdb4;border-radius:7px;align-items:center;gap:12px;width:100%;padding:12px 13px;font-size:13px;line-height:20px;display:flex}.nav-item svg{color:#8ba194}.nav-item:hover{color:#fff;background:#ffffff06}.nav-item.is-active{color:#e9f6ef;background:#3b5245}.nav-item.is-active svg{color:#a2d7c1}.nav-item span{flex:1}.live-dot{background:#75d6b2;border-radius:50%;width:6px;height:6px;box-shadow:0 0 0 4px #72ceaa13}.live-dot.paused{box-shadow:none;background:#d4b36c}.sidebar-projects{flex-direction:column;min-height:0;margin-top:38px;display:flex}.sidebar-label{letter-spacing:1.3px;color:#6f8a79;justify-content:space-between;align-items:center;padding:0 11px 9px;font-size:10px;display:flex}.icon-button{width:27px;height:27px;color:inherit;border-radius:5px;flex-shrink:0;justify-content:center;align-items:center;padding:4px;display:inline-flex}.icon-button:hover{background:#7a8d8020}.sidebar .icon-button{color:#829b8b}.project-item{text-align:left;color:#9bb0a1;border-radius:6px;flex:1;align-items:center;gap:10px;width:100%;min-width:0;padding:10px 12px;font-size:12px;display:flex}.project-item>span:not(.project-initial):not(.project-error){white-space:nowrap;text-overflow:ellipsis;flex:1;overflow:hidden}.project-item small{text-align:center;color:#799383;min-width:17px;font-size:10px}.project-row{border-radius:6px;align-items:center;display:flex;position:relative}.project-row.is-selected,.project-item.is-selected{color:#e0ece3;background:#ffffff07}.project-row:hover,.project-item:hover{color:#dae7de;background:#ffffff05}.project-initial{color:#93b69c;background:#516a5738;border-radius:4px;flex-shrink:0;place-items:center;width:18px;height:18px;font-size:9px;display:grid}.project-scroll{min-height:0;overflow:auto}.remove-project{opacity:0;background:#27382e;position:absolute;right:4px}.project-row:hover .remove-project,.remove-project:focus-visible{opacity:1}.project-error{color:#dcb581;font-size:11px}.sidebar-empty{color:#6e8776;padding:11px;font-size:11px;line-height:1.8}.sidebar-footer{margin-top:auto;padding:26px 10px 0}.read-only-mark{color:#839b8b;white-space:nowrap;align-items:center;gap:6px;font-size:10px;display:flex}.read-only-mark svg{color:#6e997f}.sidebar-footer>small{color:#a8b9ad;letter-spacing:.2px;font-variant-numeric:tabular-nums;margin-top:10px;font-size:11px;display:block}.main-shell{background:#f6f7f3;flex-direction:column;flex:1;min-width:0;display:flex;position:relative}.titlebar-drag{-webkit-app-region:drag;flex-shrink:0;height:37px}.page-header{flex-shrink:0;justify-content:space-between;align-items:center;gap:20px;padding:13px 33px 26px;display:flex}.eyebrow{color:#929e93;letter-spacing:1.5px;margin-bottom:8px;font-size:9px;font-weight:550}.page-header h1{letter-spacing:-.7px;color:#27362e;font-size:25px;font-weight:600;line-height:1.2}.page-header p{color:#8b948c;margin-top:10px;font-size:11px;line-height:1.5}.header-actions{align-items:center;gap:12px;padding-top:10px;display:flex}.button{white-space:nowrap;background:#ffffffb8;border:1px solid #dce2d9;border-radius:6px;justify-content:center;align-items:center;gap:7px;height:34px;padding:0 13px;font-size:11px;font-weight:500;display:inline-flex;box-shadow:0 1px 2px #193c1e03}.button:hover:not(:disabled){background:#fff;border-color:#c9d4c9;box-shadow:0 2px 5px #193c1e08}.button.primary{color:#fff;background:var(--accent);border-color:var(--accent);box-shadow:0 2px 3px #12675212}.button.primary:hover:not(:disabled){background:var(--accent-hover);border-color:var(--accent-hover)}.button.quiet{box-shadow:none;color:#738379;background:0 0;border-color:#0000;padding-left:0;padding-right:0}.button.quiet:hover:not(:disabled){color:var(--accent);box-shadow:none;background:0 0;border-color:#0000}.version-pill{color:#6e8271;background:#e9eee6;border:1px solid #e0e7dd;border-radius:5px;padding:7px 10px;font-size:10px}.notice{border-radius:6px;flex-shrink:0;align-items:center;gap:9px;margin:0 33px 15px;padding:9px 12px;font-size:11px;line-height:1.7;display:flex}.notice span{overflow-wrap:anywhere;flex:1}.notice-error{color:#956248;background:#fcf0ea;border:1px solid #f0d9cb}.notice-success{color:#357759;background:#e8f3ed;border:1px solid #d6e7dc}.notice .icon-button{width:22px;height:22px}.library-toolbar{flex-shrink:0;gap:12px;padding:0 33px 21px;display:flex}.search-box{color:#9aa69a;background:#fff;border:1px solid #e0e5dc;border-radius:7px;flex:1;align-items:center;gap:9px;height:38px;padding:0 11px;display:flex;box-shadow:0 1px 3px #152c1603}.search-box input{color:#3a4b40;background:0 0;border:0;outline:none;flex:1;height:100%;font-size:11px}.search-box input::placeholder{color:#a3aca2}.search-box kbd{color:#b0b8ae;padding-right:2px;font-family:inherit;font-size:14px}.project-select{color:#627263;appearance:auto;background:#fff;border:1px solid #e0e5dc;border-radius:7px;width:151px;padding:0 11px;font-size:11px}.list-topline{flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;padding-bottom:17px;display:flex}.list-topline>span{color:#98a295;white-space:nowrap;font-size:9px}.segmented{background:#eaede5;border-radius:5px;gap:2px;padding:2px;display:flex}.segmented button{color:#899685;white-space:nowrap;border-radius:4px;padding:5px 9px;font-size:10px;line-height:1.4}.segmented button.selected{color:#4e6550;background:#fff;box-shadow:0 1px 3px #263a2510}.entry-card{text-align:left;background:#fff;border:1px solid #e5e9df;border-radius:8px;align-items:flex-start;gap:14px;width:100%;margin-bottom:10px;padding:18px 16px 15px;display:flex;position:relative;box-shadow:0 1px 2px #1f341901}.entry-card:hover{border-color:#becfc0;box-shadow:0 2px 7px #243e2605}.entry-card.selected{background:#fafdf9;border-color:#85b6a8;box-shadow:0 0 0 1px #85b6a812}.entry-icon{color:#73916a;background:#f0f4eb;border-radius:7px;flex-shrink:0;place-items:center;width:38px;height:42px;margin-top:3px;display:grid}.entry-card-body{flex:1;min-width:0}.entry-card-meta{color:#9ca794;font-size:9px;line-height:1.5}.entry-card-meta span{color:#c4ccc0;margin:0 6px}.entry-card h3{color:#3f5542;letter-spacing:.1px;margin-top:4px;font-size:13px;line-height:1.6}.entry-card p{color:#8c9989;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin-top:5px;font-size:10px;line-height:1.8;display:-webkit-box;overflow:hidden}.tag-row{flex-wrap:wrap;gap:5px;min-height:17px;margin-top:10px;display:flex}.tag{color:#82957b;background:#f0f4ea;border-radius:3px;padding:0 5px;font-size:8px;line-height:16px}.tag-error{color:#aa8256;background:#fbefdf}.card-chevron{color:#bac7b5;align-self:center}.entry-card.selected .card-chevron{color:#77a48d}.library-footnote{color:#a1aa9b;flex-shrink:0;align-items:center;gap:5px;padding:14px 0 17px;font-size:9px;line-height:1.6;display:flex}.detail-heading{color:#8a9a88;justify-content:space-between;align-items:center;margin-bottom:13px;display:flex}.entry-kind{letter-spacing:.4px;color:#7d9381;align-items:center;gap:5px;font-size:9px;font-weight:500;display:inline-flex}.entry-kind.demo{color:#649082}.detail-intro h2{letter-spacing:-.4px;color:#334c38;font-size:21px;line-height:1.5}.detail-intro>p{color:#8a9985;margin-top:10px;font-size:11px;line-height:1.9}.detail-project{color:#9ca994;align-items:center;gap:5px;margin-top:13px;font-size:9px;display:flex}.play-setup{background:#edf1e9;border:1px solid #e5eadf;border-radius:7px;margin:24px 0 19px;padding:16px}.play-setup>label{color:#7e917b;letter-spacing:.4px;margin-bottom:8px;font-size:9px;display:block}.play-setup select{color:#536d50;background:#fff;border:1px solid #d9e2d2;border-radius:5px;width:100%;height:33px;padding:0 9px;font-size:11px}.play-button{width:100%;height:36px;margin-top:10px}.requirements{border-bottom:1px solid var(--border);gap:11px;margin-bottom:23px;padding:0 2px 21px;display:grid}.requirements>div{justify-content:space-between;gap:15px;font-size:10px;line-height:1.5;display:flex}.requirements span{color:#9da996;flex-shrink:0}.requirements strong{text-align:right;color:#6f8369;overflow-wrap:anywhere;font-weight:400}.section-label{justify-content:space-between;align-items:center;margin-bottom:15px;display:flex}.section-label h3{letter-spacing:.2px;color:#63785c;font-size:11px;font-weight:600}.step-list{margin:0;padding:0;list-style:none}.step-list>li{gap:12px;padding:0 0 19px;display:flex;position:relative}.step-list>li:not(:last-child):before{content:"";background:#e6ebdf;width:1px;position:absolute;top:25px;bottom:4px;left:12px}.step-number{color:#91a187;background:#f9fbf6;border:1px solid #e4eadd;border-radius:50%;flex-shrink:0;place-items:center;width:25px;height:25px;font-size:9px;display:grid}.step-list>li>div{padding-top:3px}.step-list h4{color:#6c8063;font-size:11px;font-weight:500;line-height:1.6}.step-list p{color:#a0ac96;margin-top:5px;font-size:10px;line-height:1.85}.step-list small{color:#a2b39b;margin-bottom:3px;font-size:8px;display:block}.detail-footer{border-top:1px solid var(--border);margin-top:3px;padding:14px 0 19px}.detail-footer .button{font-size:9px}.field-hint,.field-error{margin-top:9px;font-size:10px;line-height:1.7}.field-hint{color:#8e9b83}.field-error{color:#ad7658;overflow-wrap:anywhere}.inline-error{color:#a18660;background:#faf5eb;border:1px solid #eddec7;border-radius:6px;gap:8px;margin-top:10px;padding:12px;font-size:10px;line-height:1.6;display:flex}.inline-error strong{font-weight:500}.inline-error p{overflow-wrap:anywhere;margin-top:3px}.muted{color:#98a58f}.small{font-size:10px;line-height:1.8}.empty{text-align:center;flex-direction:column;align-items:center;padding:66px 20px;display:flex}.empty-icon{color:#94ab86;background:#edf2e8;border:1px solid #dfe6d9;border-radius:17px;place-items:center;width:65px;height:65px;margin-bottom:20px;display:grid;box-shadow:0 4px 9px #243c1d02}.empty h3{color:#6a805f;letter-spacing:.1px;font-size:14px}.empty p{color:#9ba991;max-width:280px;margin-top:10px;font-size:11px;line-height:1.9}.empty .button{margin-top:17px}.empty-action{text-align:center;margin-top:-39px}.loading-state{color:#93a18b;flex:1;justify-content:center;align-items:center;gap:10px;font-size:12px;display:flex}.spinner{border:2px solid #dce7d4;border-top-color:#639373;border-radius:50%;width:16px;height:16px;animation:1s linear infinite spin;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.run-page{flex:1;min-height:0;padding:0 33px 28px;overflow:auto}.run-detail{border:1px solid var(--border);background:#fdfefb;border-radius:10px;max-width:980px;margin:0 auto;padding:27px 30px}.run-title-row{justify-content:space-between;align-items:center;gap:20px;display:flex}.run-title-row h2{color:#3e5c3e;letter-spacing:-.5px;margin-top:8px;font-size:23px;line-height:1.5}.run-title-row p{color:#99a98e;margin-top:9px;font-size:10px;line-height:1.5}.run-title-row p>span{color:#c4d1ba;margin:0 8px}.status{color:#93a083;white-space:nowrap;background:#f0f3eb;border:1px solid #e3e8dc;border-radius:5px;align-items:center;gap:5px;padding:5px 7px;font-size:9px;display:inline-flex}.status>span{background:currentColor;border-radius:50%;width:4px;height:4px}.status-playing,.status-preparing,.status-pausing{color:#4c977a;background:#eaf6ef;border-color:#d5e9db}.status-completed{color:#5a9875;background:#eaf3e9;border-color:#dae9d7}.status-paused,.status-stopping{color:#b19664;background:#fbf4e6;border-color:#eee0c3}.status-failed{color:#b17558;background:#fcf0e5;border-color:#eedac4}.run-progress{background:#f1f5ec;border:1px solid #e4ebdc;border-radius:8px;margin-top:27px;padding:21px 22px 19px}.run-progress>div:first-child{justify-content:space-between;align-items:center;gap:15px;font-size:11px;display:flex}.run-progress strong{color:#739164;font-weight:500;line-height:1.6}.run-progress>div:first-child>span{color:#a4b292;white-space:nowrap;font-size:10px}.progress-track{background:#e3ebda;border-radius:5px;height:5px;margin-top:15px;overflow:hidden}.progress-track>div{background:#679f79;border-radius:5px;height:100%;transition:width .3s}.run-controls{gap:9px;margin-top:19px;display:flex}.run-controls .button{height:31px;font-size:10px}.run-controls .button.quiet{margin-left:auto}.run-callout{color:#9a946b;background:#f5f4e9;border:1px solid #e9e7d1;border-radius:6px;align-items:flex-start;gap:9px;margin-top:15px;padding:12px 14px;font-size:10px;line-height:1.8;display:flex}.run-error{color:#b88a67;background:#fff4ed;border:1px solid #eddac8;border-radius:7px;align-items:flex-start;gap:11px;margin-top:16px;padding:18px;display:flex}.run-error h3{color:#a17555;font-size:12px}.run-error p{overflow-wrap:anywhere;margin-top:6px;font-size:11px;line-height:1.8}.run-error span{color:#c1a185;margin-top:10px;font-size:10px;line-height:1.8;display:block}.run-meta{border-bottom:1px solid var(--border);gap:34px;padding:25px 0;display:flex}.run-meta>div{flex-direction:column;gap:7px;display:flex}.run-meta strong{color:#849b75;font-size:10px;font-weight:500}.run-steps{padding-top:23px}.run-steps ol{margin:0;padding:0;list-style:none}.run-steps li{border-bottom:1px solid #eff2e8;align-items:flex-start;gap:12px;padding:14px 12px;display:flex}.run-steps li.current{background:#f2f6ec;border-bottom-color:#0000;border-radius:6px}.run-step-icon{color:#b5c0aa;background:#fff;border:1px solid #e3e9db;border-radius:50%;flex-shrink:0;place-items:center;width:23px;height:23px;font-size:9px;display:grid}.run-steps li.done .run-step-icon{color:#88a873;background:#edf5e7;border-color:#dcead1}.run-steps li.current .run-step-icon{color:#7e9c69;background:#e5f0db;border-color:#bdd3ae}.run-steps li>div{flex:1;min-width:0;padding-top:3px}.run-steps h4{color:#a0ae92;font-size:11px;font-weight:500;line-height:1.6}.run-steps p{color:#b3bea7;margin-top:4px;font-size:10px;line-height:1.8}.run-steps small{white-space:nowrap;color:#b7c1ac;padding-top:6px;font-size:9px}.run-steps li.done small{color:#94af7e}.tiny-pulse{background:#81a46d;border-radius:50%;width:6px;height:6px;animation:1.7s ease-in-out infinite pulse}@keyframes pulse{50%{opacity:.4;box-shadow:0 0 0 4px #99b58515}}.run-bottom{align-items:center;gap:13px;padding-top:24px;display:flex}.run-bottom>span{color:#b0bca2;font-size:9px;line-height:1.6}.history-split{border-top:1px solid var(--border);flex:1;min-height:0;margin:0 33px;display:flex}.history-list{border-right:1px solid var(--border);width:37%;min-width:255px;padding:19px 20px 20px 0;overflow:auto}.history-card{text-align:left;background:#fff;border:1px solid #e6ebdf;border-radius:7px;align-items:flex-start;gap:12px;width:100%;margin-bottom:10px;padding:16px 12px;display:flex}.history-card.selected{background:#fbfdf8;border-color:#a4c1a4}.run-result-icon{color:#a8b798;background:#f1f4eb;border-radius:6px;flex-shrink:0;place-items:center;width:29px;height:30px;margin-top:2px;display:grid}.run-result-icon.completed{color:#7ba674;background:#edf5e6}.run-result-icon.failed{color:#bd9871;background:#fbf1e4}.run-result-icon.playing{color:#65a38a;background:#eaf4ed}.history-card>div:nth-child(2){flex:1;min-width:0}.history-card h3{color:#789069;font-size:12px;font-weight:500;line-height:1.6}.history-card p{color:#b3bfa5;margin-top:5px;font-size:9px;line-height:1.8}.history-card p>span{margin:0 5px}.history-card .status{margin-top:10px;padding:3px 5px;font-size:8px}.history-detail{flex:1;min-width:0;padding:19px 0 20px 25px;overflow:auto}.run-detail.compact{border-radius:8px;padding:22px 23px}.run-detail.compact .run-title-row{align-items:flex-start;gap:8px}.run-detail.compact .run-title-row h2{font-size:19px}.run-detail.compact .status{margin-top:1px;padding:4px 6px;font-size:8px}.run-detail.compact .run-progress{margin-top:22px;padding:16px}.run-detail.compact .run-meta{flex-wrap:wrap;gap:18px;padding:21px 0}.run-detail.compact .run-meta>div{min-width:100px}.run-detail.compact .run-steps li{gap:9px;padding:12px 0}.run-detail.compact .run-steps li.current{padding:12px 8px}.run-detail.compact .run-step-icon{width:20px;height:20px}.run-detail.compact .run-bottom{flex-direction:column;align-items:flex-start;gap:10px}.history-empty{color:#d2ddc7;flex-direction:column;justify-content:center;align-items:center;gap:17px;height:80%;display:flex}.skill-page{flex:1;gap:27px;min-height:0;padding:0 33px 28px;display:flex;overflow:auto}.skill-main{flex:1;min-width:0}.skill-intro{background:#edf2e8;border:1px solid #e0e8d9;border-radius:9px;align-items:center;gap:17px;padding:22px;display:flex}.skill-art{color:#83a370;background:#e1ecd9;border:1px solid #d5e2cb;border-radius:14px;flex-shrink:0;place-items:center;width:58px;height:62px;display:grid;box-shadow:inset 0 1px #f9fcf5}.skill-intro .eyebrow{color:#a1b18f;letter-spacing:1px;margin-bottom:5px;font-size:8px}.skill-intro h2{color:#6c8c59;letter-spacing:-.2px;font-size:18px;font-weight:550;line-height:1.5}.skill-intro p{color:#9fb08e;margin-top:5px;font-size:10px;line-height:1.9}.install-form{background:#fff;border:1px solid #e3e9dc;border-radius:9px;margin-top:17px;padding:23px}.install-form .section-label{margin-bottom:25px}.form-row{margin-bottom:22px}.form-row>label,.scope-field legend{color:#8ca178;margin-bottom:9px;font-size:10px;font-weight:500;display:block}.form-row select{color:#8ca176;background:#fdfefa;border:1px solid #e0e7d8;border-radius:5px;width:100%;height:36px;padding:0 10px;font-size:11px}.scope-field{border:0;min-width:0;margin:0 0 23px;padding:0}.scope-options{gap:10px;display:flex}.scope-options label{cursor:pointer;background:#fdfefa;border:1px solid #e3e9dc;border-radius:6px;flex:1;align-items:center;gap:9px;padding:13px 12px;display:flex}.scope-options input,.replace-check input{appearance:none;cursor:pointer;background:#fff;border:1px solid #cad6be;border-radius:50%;flex-shrink:0;place-items:center;width:13px;height:13px;margin:0;display:grid}.scope-options input:checked{border-color:#7fa469}.scope-options input:checked:after{content:"";background:#7fa469;border-radius:50%;width:5px;height:5px}.scope-options strong{color:#91a67d;font-size:11px;font-weight:500;line-height:1.4;display:block}.scope-options small{color:#b3c0a5;margin-top:4px;font-size:8px;line-height:1.5;display:block}.preview-heading{justify-content:space-between;align-items:center;margin-top:2px;margin-bottom:10px;display:flex}.preview-heading h4{color:#9bac88;font-size:10px;font-weight:500}.text-button{color:#91aa7a;align-items:center;gap:4px;padding:4px 0;font-size:9px;display:inline-flex}.text-button:hover{color:#658a4c}.install-preview{background:#f9fbf5;border:1px solid #e7edde;border-radius:6px;min-height:126px;padding:16px}.preview-status{justify-content:space-between;align-items:center;gap:8px;display:flex}.preview-badge{color:#91ac70;background:#eaf3df;border:1px solid #e0ecd0;border-radius:4px;padding:3px 6px;font-size:8px;line-height:1.5}.preview-badge.modified,.preview-badge.conflict,.preview-badge.symlink{color:#b9a56f;background:#fbf1da;border-color:#eee2bf}.target-path{color:#8da676;word-break:break-all;margin-top:12px;font-family:SF Mono,Menlo,Consolas,monospace;font-size:10px;line-height:1.8}.install-preview dl{gap:32px;margin:13px 0 0;display:flex}.install-preview dl>div{align-items:baseline;gap:8px;display:flex}.install-preview dd{color:#9cb487;margin:0;font-size:9px}.preview-message{color:#acbd98;margin-top:12px;font-size:9px;line-height:1.8}.install-preview>.muted{font-size:10px;line-height:1.8}.preview-loading{color:#abc295;align-items:center;gap:8px;min-height:90px;font-size:10px;display:flex}.install-error{color:#b49a6f;overflow-wrap:anywhere;align-items:flex-start;gap:7px;margin-top:11px;font-size:10px;line-height:1.8;display:flex}.replace-check{color:#a39e72;cursor:pointer;align-items:flex-start;gap:9px;margin-top:16px;font-size:10px;display:flex}.replace-check input{border-color:#d5d1b1;border-radius:3px;margin-top:2px}.replace-check input:checked{background:#90a775;border-color:#90a775}.replace-check input:checked:after{content:"✓";color:#fff;font-size:10px}.replace-check small{color:#bdb796;margin-top:4px;font-size:9px;line-height:1.7;display:block}.backup-hint{color:#9bb385;align-items:center;gap:5px;margin-top:13px;font-size:9px;display:flex}.install-actions{align-items:center;gap:13px;margin-top:21px;display:flex}.install-actions>.button{min-width:135px;font-size:10px}.install-actions>span{color:#b4c4a2;font-size:8px;line-height:1.8}.skill-aside{flex-shrink:0;width:223px;padding:22px 0 0 1px}.skill-aside>h3{color:#98ae80;margin-bottom:24px;font-size:11px;font-weight:500}.creation-step{gap:13px;padding-bottom:26px;display:flex;position:relative}.creation-step:not(:nth-child(4)):after{content:"";background:#e2ead9;width:1px;position:absolute;top:28px;bottom:5px;left:11px}.creation-step>span{color:#9eb686;background:#f9fcf5;border:1px solid #dce7d1;border-radius:50%;flex-shrink:0;place-items:center;width:23px;height:23px;font-size:9px;display:grid}.creation-step h4{color:#91ab76;padding-top:3px;font-size:11px;font-weight:500;line-height:1.5}.creation-step p{color:#b0c29c;margin-top:7px;font-size:10px;line-height:1.9}.skill-note{color:#abc397;border-top:1px solid #e3ebda;align-items:flex-start;gap:10px;margin-top:3px;padding:15px 0;display:flex}.skill-note p{color:#b3c5a0;font-size:9px;line-height:1.9}.bridge-missing{text-align:center;background:#f5f7f1;flex-direction:column;justify-content:center;align-items:center;min-height:100vh;padding:30px;display:flex}.bridge-missing .brand-icon{border-radius:16px;width:62px;height:66px;margin-bottom:25px}.bridge-missing h1{color:#3a5940;font-size:23px;font-weight:550}.bridge-missing p{color:#8c9e82;margin-top:14px;font-size:13px;line-height:1.9}.bridge-missing>span{color:#afbca3;background:#eaf0e4;border:1px solid #dfe8d6;border-radius:20px;margin-top:28px;padding:6px 13px;font-size:10px}@media (width>=1450px){.sidebar{width:240px}.page-header,.library-toolbar{padding-left:42px;padding-right:42px}.history-split{margin-left:42px;margin-right:42px}.entry-card{padding:22px 20px}.entry-card h3{font-size:14px}.entry-card p{font-size:11px}.entry-card-meta{font-size:10px}.skill-page,.run-page{padding-left:42px;padding-right:42px}.skill-aside{width:260px}}@media (width<=1100px){.sidebar{width:195px;padding-left:12px;padding-right:12px}.brand{gap:8px;padding-left:8px;font-size:20px}.brand span{font-size:8px}.page-header,.library-toolbar{padding-left:25px;padding-right:25px}.history-split{margin-left:25px;margin-right:25px}.entry-card{gap:10px;padding:14px 11px}.entry-icon{width:30px;height:35px}.entry-card h3{font-size:12px}.entry-card-meta{font-size:8px}.entry-card p{font-size:9px}.entry-card .card-chevron{display:none}.tag{font-size:7px}.list-topline{gap:4px}.segmented button{padding:5px 7px;font-size:9px}.skill-page{gap:20px;padding-left:25px;padding-right:25px}.skill-aside{width:180px}.install-form{padding:20px}.scope-options label{gap:7px;padding:12px 10px}.install-actions{flex-direction:column;align-items:flex-start;gap:8px}.history-list{width:36%;min-width:230px}.history-detail{padding-left:19px}.run-detail.compact{padding:19px}.run-page{padding-left:25px;padding-right:25px}}.page-header p{color:#828b83;font-size:12px}.eyebrow{color:#939b90}.entry-card-meta{color:#8c978c;font-size:10px}.entry-card h3{color:#3d4c41;font-size:14px}.entry-card p{color:#849081;font-size:11px}.entry-card.selected{background:#fbfdf9;border-color:#86b6a6}.entry-icon{color:#759274;background:#eef3e9}.entry-icon.demo{color:#5e9382;background:#eaf2ed}.tag{color:#7f9278;font-size:9px}.list-topline>span{color:#8b9686;font-size:10px}.segmented button{font-size:11px}.entry-card-meta span{color:#b4beb0}.detail-intro h2{color:#344b3a}.detail-intro>p{color:#7f8d7a;font-size:12px}.detail-project{color:#8f9d87;font-size:10px}.entry-kind{color:#7a907a;font-size:10px}.play-setup>label{color:#7c8e74;font-size:10px}.play-setup select{color:#5c7052;font-size:12px}.button,.play-button{font-size:12px}.requirements>div{font-size:11px}.requirements span{color:#8b9783}.requirements strong{color:#6f8262}.section-label h3{color:#667f59;font-size:12px}.section-label>span{color:#94a087;font-size:10px}.step-list h4{color:#6d825f;font-size:12px}.step-list p{color:#929f86;font-size:11px}.step-number{color:#839774;font-size:10px}.step-list small{color:#91a282;font-size:9px}.detail-footer .button{color:#7f9470;font-size:10px}.library-footnote{color:#96a18d;font-size:10px}.field-hint{color:#89997b;font-size:11px}.field-error{color:#a87b59;font-size:11px}.empty h3{color:#6d845c;font-size:15px}.empty p{color:#91a281;font-size:12px}.header-count{color:#7b8e70;font-size:12px}.version-pill{color:#718766;font-size:11px}.status{font-size:10px}.run-title-row h2{color:#3b513b}.run-title-row p{color:#90a182;font-size:11px}.run-progress strong{color:#708c5d;font-size:12px}.run-progress>div:first-child>span{color:#93a57e;font-size:11px}.progress-track>div{background:#629a76}.run-controls .button{font-size:11px}.run-callout{color:#94865f;font-size:11px}.run-meta span{color:#94a282;font-size:10px}.run-meta strong{color:#80946d;font-size:11px}.run-steps h4{color:#94a182;font-size:12px}.run-steps li.done h4,.run-steps li.current h4{color:#6d8857}.run-steps p{color:#9fac8c;font-size:11px}.run-steps small{color:#a4b18f;font-size:10px}.run-bottom .button{font-size:11px}.run-bottom>span{color:#9baa86;font-size:10px}.history-card h3{color:#6f865e;font-size:13px}.history-card p{color:#9cae87;font-size:10px}.history-card .status,.run-detail.compact .status{font-size:9px}.run-detail.compact .run-title-row p{font-size:10px}.run-detail.compact .run-progress strong{font-size:11px}.run-detail.compact .run-meta strong{font-size:10px}.run-detail.compact .run-steps h4{font-size:11px}.run-detail.compact .run-steps p{font-size:10px}.run-detail.compact .run-bottom>span{font-size:9px}.history-empty p{color:#a5b68e;font-size:12px}.skill-intro h2{color:#678251}.skill-intro p{color:#8da077;font-size:11px}.skill-intro .eyebrow{color:#97aa7f;font-size:9px}.install-form .section-label h3{color:#718b5c;font-size:13px}.install-form .section-label>span{color:#9fb189;font-size:10px}.form-row>label,.scope-field legend{color:#829a6d;font-size:11px}.form-row select{color:#7e9765;font-size:12px}.scope-options strong{color:#819a67;font-size:12px}.scope-options small{color:#a0b287;font-size:9px}.scope-options label.chosen{background:#f8fbf2;border-color:#a4bd8a}.preview-heading h4{color:#8aa174;font-size:11px}.text-button{color:#839f69;font-size:10px}.install-preview dt{color:#a0b38a;font-size:9px}.install-preview dd{color:#88a169;font-size:10px}.target-path{color:#829b65;font-size:11px}.preview-badge{color:#7f9c5a;font-size:9px}.preview-status>span:last-child{color:#9cae83;font-size:9px}.preview-message{color:#98ad7c;font-size:10px}.install-actions>.button{font-size:11px}.install-actions>span{color:#9eb483;font-size:9px}.backup-hint{color:#8ea76e;font-size:10px}.replace-check{color:#a0976a;font-size:11px}.replace-check small{color:#afa57d;font-size:10px}.skill-aside>h3{color:#899f70;font-size:12px}.creation-step h4{color:#819c64;font-size:12px}.creation-step p{color:#9bb17e;font-size:11px}.creation-step>span{color:#8da76c;font-size:10px}.skill-note p{color:#9db580;font-size:10px}.entry-card h3,.detail-intro h2,.run-title-row h2,.history-card h3{color:#34463b}.entry-card p,.detail-intro>p,.step-list p,.run-steps p,.skill-intro p,.creation-step p{color:#7b897c}.entry-card-meta,.detail-project,.library-footnote,.list-topline>span,.field-hint,.run-title-row p,.run-meta span,.run-bottom>span,.history-card p{color:#849080}.requirements span,.section-label>span,.step-list small,.run-steps small,.run-steps li.done small{color:#85937b}.requirements strong,.step-list h4,.section-label h3,.run-meta strong,.run-steps h4{color:#667b5f}.run-steps li.done h4,.run-steps li.current h4,.run-progress strong{color:#52795c}.skill-intro h2,.install-form .section-label h3,.skill-aside>h3{color:#4c6a51}.form-row>label,.scope-field legend,.scope-options strong,.preview-heading h4,.creation-step h4{color:#698264}.form-row select,.target-path,.install-preview dd{color:#69835d}.scope-options small,.preview-status>span:last-child,.install-preview dt,.preview-message,.install-actions>span,.skill-note p,.backup-hint{color:#8a9a7b}.skill-art{color:#749c73;background:#e4eee2;border-color:#d5e4d1}.preview-badge{color:#75965a;background:#eaf2e4;border-color:#dae7d0}.preview-badge.modified,.preview-badge.conflict,.preview-badge.symlink{color:#a58e57}.skill-aside .creation-step>span{color:#819c6c}.skill-note{color:#91a87c}.empty h3{color:#637e56}.empty p{color:#879b79}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none!important;animation:none!important}}.app-shell.book-open .sidebar{width:196px}.book-open .brand{gap:8px;padding-left:7px;padding-right:0;font-size:20px}.book-open .brand span{display:none}.project-item .folder-chevron{color:#718a7c;flex-shrink:0;transition:transform .15s}.folder-chevron.expanded{transform:rotate(90deg)}.folder-books{border-left:1px solid #53665a60;margin:0 0 9px 22px;padding:2px 0 3px 7px}.folder-book{text-align:left;color:#9eb5a6;border-radius:5px;width:100%;padding:8px;font-size:11px;display:block}.folder-book span{white-space:nowrap;text-overflow:ellipsis;display:block;overflow:hidden}.folder-book:hover{color:#e0ece4;background:#ffffff08}.folder-book.selected{color:#e9f6ef;background:#3b5245}.project-item{gap:7px}.project-folder .project-item{padding-left:3px;padding-right:2px;font-size:11px}.book-library{border-top:1px solid var(--border);flex:1;min-height:0;margin:0 33px 25px;padding-top:21px;overflow:auto}.book-cards{gap:13px;display:grid}.book-list-card{background:#fcfdf9;border:1px solid #e0e6dc;border-radius:10px;align-items:center;display:flex;overflow:hidden}.book-card-open{text-align:left;flex:1;align-items:center;gap:20px;min-width:0;padding:25px 23px;display:flex}.book-card-open:hover{background:#f1f6ed}.book-cover{color:#719168;background:#e9f0e4;border:1px solid #dce7d6;border-radius:7px;flex-shrink:0;place-items:center;width:51px;height:64px;display:grid}.book-card-copy{flex:1;gap:7px;min-width:0;display:grid}.book-card-copy small{color:#8c9b86;font-size:10px}.book-card-copy strong{color:#35503c;font-size:18px;font-weight:600;line-height:1.5}.book-card-copy>span{color:#7c8c77;font-size:12px;line-height:1.7}.book-card-open>svg{color:#a4b39d}.book-card-play{color:#648966;white-space:nowrap;border:1px solid #d6e2cf;border-radius:6px;align-items:center;gap:5px;margin:0 22px 0 8px;padding:8px 11px;font-size:11px;display:flex}.book-card-play:hover:enabled{background:#edf4e8}.compact-header{padding-top:5px;padding-bottom:17px}.compact-header h1{color:#869383;font-size:13px;font-weight:500}.back-list svg{transform:rotate(180deg)}.book-detail-page{flex-direction:column;flex:1;min-height:0;margin:0 33px 20px;display:flex;overflow:hidden}.book-detail-page>.detail-heading{margin-top:15px}.book-overview{flex-shrink:0;justify-content:space-between;align-items:center;gap:24px;padding:13px 0 25px;display:flex}.book-overview-copy{flex:1;min-width:0}.book-overview-copy h2{color:#334c3b;margin:9px 0;font-size:27px;font-weight:600;line-height:1.5}.book-overview-copy p{color:#81907b;max-width:650px;font-size:13px;line-height:1.8}.book-overview-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:9px;max-width:330px;display:flex}.book-overview-actions label{color:#899981;width:100%;font-size:10px}.book-overview-actions select{color:#6b805f;background:#fdfefa;border:1px solid #dfe6da;border-radius:6px;max-width:210px;padding:8px 10px;font-size:11px}.section-tabs{border-bottom:1px solid #dfe6da;flex-shrink:0;gap:25px;margin-bottom:0;display:flex;overflow-x:auto}.section-tabs [role=tab]{color:#93a087;white-space:nowrap;border-bottom:2px solid #0000;padding:13px 2px 12px;font-size:13px}.section-tabs [role=tab]:hover{color:#527c5c}.section-tabs [aria-selected=true]{color:#276e58;border-bottom-color:#328168;font-weight:600}.section-panel{flex:1;min-height:0;padding:25px 3px 15px 0;overflow:auto}.section-overview{justify-content:space-between;align-items:center;gap:18px;padding-bottom:22px;display:flex}.section-overview h3{color:#58714e;font-size:18px;line-height:1.6}.section-overview p{color:#8b9a7f;margin-top:6px;font-size:12px;line-height:1.8}.section-overview span{color:#99a88e;margin-top:8px;font-size:10px;display:block}.section-script-list{gap:11px;display:grid}.section-script-row{background:#fcfdf9;border:1px solid #e1e7dc;border-radius:8px;align-items:center;gap:14px;padding:20px;display:flex}.script-order{color:#a6b39a;font-size:11px}.script-open{text-align:left;flex:1;min-width:0}.script-open strong{color:#516e4c;font-size:15px;font-weight:550;line-height:1.7}.script-open p{color:#87977b;margin:4px 0;font-size:12px;line-height:1.8}.script-open small{color:#a0af94;font-size:10px}.script-open:hover strong{color:#25805f}.section-script-row>.button{font-size:11px}.script-breadcrumb{color:#9eac92;align-items:center;gap:10px;margin-bottom:24px;font-size:10px;display:flex}.script-breadcrumb button{color:#7b946d;align-items:center;gap:7px;display:flex}.script-breadcrumb svg{transform:rotate(180deg)}.section-panel .detail-intro h2{font-size:24px}.section-panel .detail-intro>p{font-size:13px}.section-panel .step-list h4{font-size:14px}.section-panel .step-list p{font-size:13px;line-height:1.9}.section-panel .step-list li{padding-bottom:23px}.section-panel .play-setup{background:0 0;border:0;max-width:290px;margin:20px 0 25px;padding:0}.section-panel .requirements{flex-wrap:wrap;gap:12px 30px;max-width:750px;padding-bottom:20px;display:flex}.section-panel .requirements>div{gap:10px;display:flex}.book-view-footer{border-top:1px solid #e5eade;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;margin-top:30px;padding-top:20px;display:flex}.book-view-footer>.button{font-size:10px}.book-view-footer>span{color:#98a88b;font-size:10px}.book-view-footer kbd{border:1px solid #dde5d5;border-radius:4px;margin-right:7px;padding:2px 5px;font:11px inherit}@media (width>=1500px){.book-library,.book-detail-page{margin-left:42px;margin-right:42px}}@media (width<=1100px){.book-library,.book-detail-page{margin-left:25px;margin-right:25px}.app-shell.book-open .sidebar{width:180px}.book-overview{gap:15px}.book-overview-copy h2{font-size:23px}.book-overview-actions{gap:6px;max-width:280px}.book-overview-actions select{max-width:170px}.section-tabs{gap:18px}.section-script-row{gap:10px;padding:15px}.book-card-open{gap:15px;padding:20px 16px}.book-card-copy strong{font-size:16px}}.shortcut-hint{color:#84977a;justify-content:center;align-items:center;gap:7px;margin-top:12px;font-size:9px;line-height:1.5;display:flex}.shortcut-hint kbd{color:#718a66;white-space:nowrap;background:#f8fbf4;border:1px solid #d9e3d2;border-bottom-width:2px;border-radius:4px;padding:2px 5px;font:10px -apple-system,BlinkMacSystemFont,sans-serif}.shortcut-hint.unavailable{color:#ab8e65}.run-step-section{color:#8ea082;margin-bottom:3px;font-size:9px;line-height:1.5}.project-picker{align-items:center;gap:10px;display:flex}.project-picker input{color:#718b60;background:#fdfefa;border:1px solid #e0e7d8;border-radius:5px;flex:1;min-width:0;height:36px;padding:0 10px;font-size:11px}.project-picker .button{flex-shrink:0}.form-hint{color:#8ca178;margin-top:8px;font-size:10px;line-height:1.7}.compat-target{border-top:1px solid #e0e7d8;margin-top:14px;padding-top:12px}.compat-target strong{color:#718b60;font-size:10px;font-weight:500}.compat-target small{color:#8ca178;margin-top:8px;font-size:9px;display:block}.export-hint{color:var(--muted,#778371);margin:8px 0 16px;font-size:12px;line-height:1.6}.export-actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.export-result{background:#f5f8f0;border:1px solid #cad8bf;border-radius:12px;justify-content:space-between;align-items:center;gap:18px;margin:20px 0;padding:22px;display:flex}.export-result p{color:#6d7d64;margin:6px 0;font-size:13px}.export-result small{overflow-wrap:anywhere;color:#7b8972;max-width:520px;display:block}.book-overview-actions{flex-shrink:0;grid-template-columns:minmax(100px,180px) auto auto auto;max-width:none;display:grid}.book-overview-actions label{grid-column:1/-1}.book-overview-actions select{width:100%}.play-setup>.button:not(.primary){margin-top:8px}.export-result{flex-wrap:wrap}.export-result>div:first-child{flex:1;min-width:200px}.run-detail.compact .export-result{flex-direction:column;align-items:flex-start}.status-exporting{color:#4c977a;background:#eaf6ef;border-color:#d5e9db}.status-cleaning,.status-recovering{color:#9b7c42;background:#fbf4e6;border-color:#eee0c3}.cleanup-status{color:#67805c;background:#f1f6ed;border:1px solid #dce7d8;border-radius:7px;margin-top:16px;padding:17px 18px}.cleanup-status.needs-review{color:#967748;background:#fff6eb;border-color:#ead8bb}.cleanup-heading{align-items:flex-start;gap:9px;font-size:12px;line-height:1.5;display:flex}.cleanup-heading svg{flex-shrink:0}.cleanup-status p{overflow-wrap:anywhere;margin:8px 0 0;font-size:11px;line-height:1.8}.cleanup-error{color:#9b654b;border-top:1px solid #e9dac5;margin-top:12px;padding-top:12px;font-size:11px}.cleanup-recover{margin-top:13px}.cleanup-recover .button{font-size:11px}.run-error p{white-space:pre-wrap}.run-controls{flex-wrap:wrap}.tutorial-banner{text-align:right;letter-spacing:.2px;color:#5a846b;white-space:nowrap;padding:11px 30px 0;font-size:10px;line-height:16px;display:block}.embedded-player{background:#f6f7f3;flex-direction:column;height:100vh;min-height:0;display:flex;overflow:hidden}.embedded-titlebar{-webkit-app-region:drag;text-align:right;color:#8da296;letter-spacing:.2px;background:#202d29;flex:0 0 37px;height:37px;padding:11px 24px 0;font-size:10px}.embedded-toolbar{background:#f5f8f1;border-bottom:1px solid #dce5d9;flex:0 0 81px;align-items:center;gap:18px;min-width:0;height:81px;padding:12px 24px;display:flex}.embedded-toolbar.is-waiting{background:#fff8e9;border-bottom-color:#e5d7b8}.embedded-back{color:#66816d;flex-shrink:0;align-items:center;gap:5px;padding:8px 0;font-size:11px;display:flex}.embedded-back svg{transform:rotate(180deg)}.embedded-heading{gap:5px;min-width:110px;max-width:220px;display:grid}.embedded-heading small{text-overflow:ellipsis;white-space:nowrap;color:#7e907d;font-size:10px;display:block;overflow:hidden}.embedded-heading strong{color:#375a45;font-size:14px;font-weight:600}.embedded-caption{color:#536e55;flex:1;min-width:0;font-size:12px;line-height:1.65}.embedded-caption p{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.embedded-caption small{color:#937b4d;font-size:10px}.embedded-controls{flex-shrink:0;align-items:center;gap:8px;display:flex}.embedded-controls .button{padding:0 11px;font-size:11px}.embedded-page-space{background:#eef2e9;flex:1;min-height:0}.dsh-browser-stage{box-sizing:border-box;justify-content:center;align-items:center;height:100%;padding:12px;display:flex;position:relative}.dsh-browser-screen{aspect-ratio:16/10;background:#fff;outline:1px solid #c9d5ca;width:min(100%,160vh - 256px);max-height:100%;position:relative;overflow:hidden;box-shadow:0 8px 30px #263d291a}.dsh-browser-screen:focus{outline:2px solid #5c9474}.dsh-browser-screen img{object-fit:fill;-webkit-user-select:none;user-select:none;pointer-events:none;width:100%;height:100%;display:block}.dsh-browser-hint{color:#fff;pointer-events:none;background:#234a3de0;border-radius:6px;padding:6px 10px;font-size:11px;position:absolute;bottom:18px;right:20px}@media (width<=800px){[data-playbook-host=dsh] .app-shell .sidebar,[data-playbook-host=dsh] .app-shell.book-open .sidebar{width:58px;padding:0 6px 10px}[data-playbook-host=dsh] .sidebar .brand{justify-content:center;padding:8px 3px 18px;font-size:0}[data-playbook-host=dsh] .sidebar .brand span,[data-playbook-host=dsh] .sidebar-projects,[data-playbook-host=dsh] .sidebar-footer{display:none}[data-playbook-host=dsh] .sidebar .brand-icon{width:36px;height:36px}[data-playbook-host=dsh] .sidebar .nav-item{justify-content:center;padding:10px 0}[data-playbook-host=dsh] .sidebar .nav-item span{display:none}[data-playbook-host=dsh] .page-header{flex-wrap:wrap;padding:12px 16px 16px}[data-playbook-host=dsh] .book-library,[data-playbook-host=dsh] .book-detail-page{margin-left:16px;margin-right:16px}[data-playbook-host=dsh] .library-toolbar{padding-left:16px;padding-right:16px}[data-playbook-host=dsh] .book-card-open{gap:10px;padding:14px 10px}[data-playbook-host=dsh] .book-card-copy strong{font-size:14px}[data-playbook-host=dsh] .book-card-copy>span{font-size:10px}[data-playbook-host=dsh] .embedded-toolbar{flex-wrap:wrap;gap:7px;height:auto;min-height:105px;padding:9px 12px}[data-playbook-host=dsh] .embedded-caption{min-width:140px}[data-playbook-host=dsh] .embedded-controls{justify-content:flex-end;width:100%}[data-playbook-host=dsh] .embedded-titlebar{flex-basis:24px;height:24px;padding:5px 12px 0}[data-playbook-host=dsh] .dsh-browser-screen{width:min(100%,160vh - 262.4px)}}.embedded-finished{color:#719074;text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:16px;height:100%;padding:30px;display:flex}.embedded-finished h2{color:#476e54;font-size:21px}.embedded-finished p{color:#8a9a80;font-size:12px;line-height:1.8}.browser-choice{min-width:155px}.book-overview-actions{grid-template-columns:minmax(110px,180px) minmax(155px,180px) auto auto auto}.play-setup>.browser-choice{margin-bottom:4px}.interaction-prompt{color:#886f3e;background:#fff8e7;border:1px solid #e8d7ad;border-radius:8px;margin:18px 0;padding:17px 18px}.interaction-prompt strong{font-size:13px;font-weight:600}.interaction-prompt p{margin-top:8px;font-size:12px;line-height:1.8}.interaction-prompt small{color:#9b8050;margin-top:9px;font-size:11px;line-height:1.7;display:block}.interaction-records{border-top:1px solid #e1e7db;margin:25px 0;padding-top:20px}.interaction-records ol{gap:10px;margin:0;padding:0;list-style:none;display:grid}.interaction-records li{background:#f5f7f0;border:1px solid #e2e7db;border-radius:5px;align-items:baseline;gap:12px;padding:9px 12px;font-size:11px;line-height:1.8;display:flex}.interaction-records li strong{color:#637c61;flex:1;font-weight:500}.interaction-records li span{color:#9a8053}.interaction-records li small{color:#93a087;font-size:10px}.interaction-records>p{color:#8b9781;margin-top:11px;font-size:10px;line-height:1.8}.status-waiting{color:#967438;background:#fff4db;border-color:#ead8ad}.tutorial-banner.live-skill{color:#987037}@media (width<=1250px){.book-overview{flex-direction:column;align-items:flex-start}.book-overview-actions{grid-template-columns:minmax(120px,180px) minmax(155px,180px) auto auto auto;justify-content:start;align-self:stretch}}@media (width<=1100px){.embedded-toolbar{gap:12px;padding:12px 16px}.embedded-heading{min-width:90px;max-width:160px}.embedded-controls{gap:6px}.embedded-controls .button{padding:0 9px;font-size:10px}.embedded-caption{font-size:11px}.book-overview-actions{grid-template-columns:minmax(100px,150px) minmax(155px,175px) auto auto auto}.book-overview-actions .button{padding:0 10px;font-size:11px}}.project-row .remove-project{opacity:1;color:#97ac9e;background:0 0;flex:0 0 26px;width:26px;margin-right:2px;position:static}.project-row .remove-project:hover:enabled{color:#ebbbb0;background:#ffffff10}.project-row .remove-project:disabled{opacity:.3}.book-card-play{margin-right:7px}.book-card-delete{color:#987966;white-space:nowrap;border-radius:6px;flex-shrink:0;align-items:center;gap:5px;margin-right:14px;padding:8px 10px;font-size:10px;display:flex}.book-card-delete:hover:enabled{color:#9d604d;background:#fbefea}.book-card-delete:disabled{color:#9ba495}.button.danger-quiet{color:#95725f;background:0 0;border-color:#e5d9cc}.button.danger-quiet:hover:enabled{background:#fbefea;border-color:#dbc2b2}.button.danger{color:#fff;background:#a9604c;border-color:#a9604c}.button.danger:hover:enabled{background:#94513e;border-color:#94513e}.notice-backup{margin-top:4px;font-size:10px;line-height:1.8}.notice-backup summary{cursor:pointer;color:#617e64;width:fit-content}.notice-backup summary:focus-visible{outline-offset:3px;outline:2px solid #43ad9955}.notice-backup code{overflow-wrap:anywhere;background:#ffffff70;border-radius:4px;max-height:100px;margin-top:5px;padding:7px 9px;font-size:10px;display:block;overflow:auto}.removal-dialog{color:#405a48;background:#fafcf6;border:1px solid #dce5d8;border-radius:14px;width:min(440px,100vw - 48px);padding:29px;box-shadow:0 18px 80px #10231b35}.removal-dialog::backdrop{background:#12241d70}.removal-icon{color:#a17c5d;background:#f6ede2;border:1px solid #e3d5c6;border-radius:10px;place-items:center;width:43px;height:47px;margin-bottom:19px;display:grid}.removal-dialog h2{font-size:20px;font-weight:600}.removal-target{color:#3f5b45;overflow-wrap:anywhere;margin-top:16px;font-size:15px;font-weight:550;line-height:1.7}.removal-project{color:#91a185;margin-top:3px;font-size:10px;display:block}.removal-dialog #removal-impact{color:#7c8d74;margin-top:13px;font-size:12px;line-height:1.9}.removal-dialog .removal-warning,.removal-dialog .removal-error{color:#996c4e;overflow-wrap:anywhere;background:#fff5e8;border:1px solid #e8d7c0;border-radius:5px;margin-top:14px;padding:10px 12px;font-size:11px;line-height:1.8}.removal-dialog .removal-error{color:#9a604b;background:#fcf0e9;border-color:#e8cdbd}.removal-actions{justify-content:flex-end;gap:10px;margin-top:25px;display:flex}.removal-actions .button{min-width:82px}@media (width<=1100px){.header-actions{gap:7px}.header-actions .button{padding-inline:10px;font-size:10px}.book-card-delete{margin-right:10px;padding-inline:7px}.book-card-play{margin-left:4px;margin-right:3px}}.brand-icon{background:linear-gradient(135deg,#2b8a75,#16594e)}.embedded-titlebar>span{align-items:center;gap:7px;display:inline-flex}.run-annotations{background:#fff;border:1px solid #d9e2e6;border-radius:12px;margin-top:24px;padding:20px}.run-annotations ol{gap:12px;margin:12px 0 0;padding:0;list-style:none;display:grid}.run-annotations li{border:1px solid #e1e9ed;border-radius:9px;justify-content:space-between;align-items:flex-start;gap:16px;padding:12px;display:flex}.run-annotations li>div{min-width:0}.run-annotations li p{white-space:pre-wrap;overflow-wrap:anywhere;margin:5px 0}.run-annotations li small{color:#687b86;overflow-wrap:anywhere;display:block}.annotation-actions{flex-wrap:wrap;flex-shrink:0;justify-content:flex-end;gap:8px;display:flex}@media (width<=1100px){.annotation-actions{flex-direction:column}}
|