elanous 0.2.11 → 0.2.12
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1147-466ec15afacc1a65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1394-556de6d71bbdb0fb.js → 1394-ee3795b112907122.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3869-3cd46526879f454c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7277-0b2fc7c16ba2d64b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7758-0b018a9e4fc56200.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8605-ea5bee9dfae512c7.js → 8605-0259994816604c49.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9920-5cfdc5e8fd209825.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-cb169620945d1952.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-6a061bd97f0b9398.js → page-cefe8169e36cf62a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/board/{page-cb95a7432c9ee744.js → page-d2e35228bc497119.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-b12b6d2f8d2d1aea.js → page-5c05b0da4bc1392c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/{page-b9efe868bfd36255.js → page-e0ccdb576812b523.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/{page-7c97dcdfe2e37a60.js → page-813c4a52c9d05ca8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4731f2c215358937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/{page-5721537ca8a3598c.js → page-a022b257950f39e6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-b654240a572e4c48.js → page-a2ffc717e04b8b0a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/{page-b9750abc897508c3.js → page-b59ee4e70fc18fcf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a67e11ba962337b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c172dabd796eb7a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-1efd0cb9e0ed9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/{page-c8b1ccda6ba7ae98.js → page-d5dc7ff69a37b4cf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-e71c84189e8c683e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-2a9932ddb62d76bd.js → page-1d6a533ce5a6efcb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/market/{page-9688f5b4f1ff950f.js → page-dfca9b7d2de0b135.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-793fa536b3a6ef37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-35414e0a007b4082.js → page-6dd3bfbbde2a5c2c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/{not-found-e7a529e0507ac86c.js → not-found-490653e8d4cc8852.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/{page-e001823c35c9dd67.js → page-77447356baad75d2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-29e961191f6057df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-c822f55b884d9104.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fa4ccfc432424e52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-3a24072b35470157.js → page-6d604227e1664b71.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-9c7e8f744a765daf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/{page-0be8d4b2ced75ba0.js → page-4048543b4b7ad5e0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-d37cb0d52f9b6bd5.js → page-4c3a3126abed551a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/{page-686da0df9bf23e5c.js → page-64b0aecb1ca75e75.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4292d0149020e8a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/{page-53f80edc6b8dc07c.js → page-db14d0be7f1c460c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-e5d8072cd7cfef73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/{page-239c17b911b84e72.js → page-9547b5cec7cf76bf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-e6dcb83265530636.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-45248f08d6aecae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/{page-1218753c82d585f6.js → page-2cddeb9e2aeedc55.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/term/{page-4b5935e67531efb5.js → page-e297866051595d81.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/{page-3285bc87caf1eaa5.js → page-baba2e047872fb0f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/{page-ad553b0e06505ecd.js → page-e895da4ec9cac345.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4344faf20216233b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-698bb29f11864b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-bd6a6dc1ddc273f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2e9e2fb01c9da1c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d62ceb13411ebba4.js +1 -0
- package/apps/pwa/out/_next/static/css/128fb7fb670b2fbf.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +14 -14
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +14 -14
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +14 -14
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +14 -14
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +14 -14
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +14 -14
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +14 -14
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +14 -14
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +14 -14
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +14 -14
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +14 -14
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +14 -14
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +14 -14
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +14 -14
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +14 -14
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +14 -14
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +14 -14
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +14 -14
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +14 -14
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +14 -14
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +14 -14
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +14 -14
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +14 -14
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +14 -14
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +15 -15
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +14 -14
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +14 -14
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +14 -14
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +14 -14
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +14 -14
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +14 -14
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +14 -14
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +14 -14
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +14 -14
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +14 -14
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +14 -14
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +14 -14
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +14 -14
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +14 -14
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +14 -14
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +14 -14
- package/graphs/context/nightly-condense.yaml +21 -0
- package/graphs/context/recipes.yaml +12 -0
- package/graphs/demo/inside-seed.yaml +20 -0
- package/graphs/demo/recipes.yaml +12 -0
- package/package.json +1 -1
- package/plugins/card-followup/examples/sample-card.png +0 -0
- package/scripts/lib/telegram-inject-args.ts +31 -0
- package/scripts/measure-pod-memory-by-goal.ts +130 -0
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/checklist-gate-node.ts +2 -1
- package/scripts/release-loop/gate-node.ts +8 -2
- package/scripts/release-loop/ops-upgrade-node.ts +47 -6
- package/scripts/release-loop/publish-node.ts +4 -1
- package/scripts/release-loop/version-node.ts +13 -3
- package/scripts/telegram-inject.ts +14 -6
- package/scripts/test-diet/remeasure-list.ts +112 -0
- package/scripts/ux/demo-rehearsal.ts +17 -13
- package/scripts/ux/demo-seed.ts +108 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +12 -5
- package/src/agent-mission/driver.ts +138 -16
- package/src/agent-mission/pty-decision.ts +1 -1
- package/src/autopilot/pty-control-loop.ts +4 -1
- package/src/chat/index.ts +1 -0
- package/src/cli/persona-cli.ts +17 -14
- package/src/cli/pod-cli.ts +17 -0
- package/src/cli/pod-memory-advice.ts +35 -0
- package/src/cli/release-cli.ts +46 -6
- package/src/context-bus/context-now-surfaces.ts +17 -0
- package/src/context-bus/context-now.ts +2 -2
- package/src/context-bus/coord-events.ts +2 -2
- package/src/context-bus/nightly-condense.ts +153 -0
- package/src/context-bus/session-events.ts +35 -0
- package/src/dashboard/dashboard-status-lines.ts +2 -0
- package/src/dashboard/index.ts +8 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +24 -0
- package/src/domains/outbound-alert.ts +99 -31
- package/src/domains/outbound-log-probe.ts +8 -0
- package/src/execution-loop/launch-gate.ts +17 -8
- package/src/field-note/telegram.ts +142 -0
- package/src/graph-runner/graph-grow-llm.ts +23 -13
- package/src/graph-runner/graph-grow.ts +5 -2
- package/src/graph-runner/runner.ts +12 -8
- package/src/harness/harness-cli-command.ts +138 -16
- package/src/hooks/consult-intake.ts +153 -0
- package/src/hooks/receiver.ts +78 -1
- package/src/index.ts +33 -9
- package/src/intake-plane/discord-seat-work.ts +28 -2
- package/src/intake-plane/wish-card.ts +33 -0
- package/src/llm/difficulty.ts +1 -1
- package/src/maturity/feature-maturity.ts +2 -1
- package/src/nexus/api/http-server.ts +31 -8
- package/src/nexus/api/outbound-report.ts +40 -7
- package/src/nexus/api/personas.ts +95 -53
- package/src/nexus/api/task-cards-api.ts +19 -0
- package/src/nexus/api/workflow-history.ts +88 -0
- package/src/nexus/api/workflows.ts +52 -0
- package/src/nexus/outbound/delivery-ledger.ts +17 -8
- package/src/nexus/outbound/router.ts +8 -3
- package/src/persona/presets.ts +8 -1
- package/src/plugins/maker/market-bundle.ts +2 -1
- package/src/release-loop/checklist.ts +15 -3
- package/src/release-loop/feature-store.ts +24 -10
- package/src/release-loop/landed-but-yellow.ts +48 -0
- package/src/seat-loop/seat-loop.ts +168 -7
- package/src/self-dev/draft-sweep.ts +44 -10
- package/src/self-dev/draft-triage-rules.ts +54 -2
- package/src/self-implement/budget-gate.ts +29 -12
- package/src/self-implement/gate-candidate-ranking.ts +60 -0
- package/src/self-implement/gate-scope.ts +9 -8
- package/src/self-implement/headless-elanous-driver.ts +7 -2
- package/src/self-implement/orchestrator.ts +15 -0
- package/src/self-implement/test-seams.ts +1 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -10
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +8 -0
- package/src/telegram-commands.ts +21 -0
- package/src/telegram-project-command.ts +78 -4
- package/src/telegram.ts +32 -5
- package/src/user-config.ts +8 -4
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/2310-7a59f043f6db207e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2548-6e316138d347cefe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3869-a39d1d9921e10d43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/507-5acd98bd6dab2d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5445-745eb795c5963d79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1dcdc58fc2de2454.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-8fd36984f549270a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-4cd1de371f8ad048.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d99f89657828421c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-50cb2a0eb15e6c83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-d6b1d156fb95e74b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6b15dd6456c5df09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-371423d1a573d64b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4b764b125339ac17.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cdf8e4b01067bcf1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-94c82eb0ae5abb32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4dc614f3ce043e63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d02c782fc792e2af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-dc6a79fb003f746c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-0fffb84cafdc9da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-fca096e3e860306f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ebfa78f0d9885c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-3dc5f21f7e39622d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-c6da2b468454532d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-93bc70e36f595414.js +0 -1
- package/apps/pwa/out/_next/static/css/543f56bcb1f79fca.css +0 -1
- /package/apps/pwa/out/_next/static/{Y4zKzL62sakG5momz3SoQ → -6XrAoD3eU7NyMHAE4xPS}/_buildManifest.js +0 -0
- /package/apps/pwa/out/_next/static/{Y4zKzL62sakG5momz3SoQ → -6XrAoD3eU7NyMHAE4xPS}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--Y4zKzL62sakG5momz3SoQ--><html lang="ko" class="font-sans __variable_45c93f"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/><link rel="preload" href="/app/_next/static/media/22a5144ee8d83bca-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/app/_next/static/css/543f56bcb1f79fca.css" data-precedence="next"/><link rel="stylesheet" href="/app/_next/static/css/04dabcbcc4bfa6db.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/app/_next/static/chunks/webpack-9e4d02d567b98240.js"/><script src="/app/_next/static/chunks/5cd7e3a9-404fd6b8d0ecd44c.js" async=""></script><script src="/app/_next/static/chunks/3170-7ec60a56fa0e4728.js" async=""></script><script src="/app/_next/static/chunks/main-app-f0fe2d7477845181.js" async=""></script><script src="/app/_next/static/chunks/7777-79f845045aa1ed86.js" async=""></script><script src="/app/_next/static/chunks/9538-2816b90923606459.js" async=""></script><script src="/app/_next/static/chunks/1829-b453a1b22d3999bb.js" async=""></script><script src="/app/_next/static/chunks/6048-4c5c33579bc4ef78.js" async=""></script><script src="/app/_next/static/chunks/9656-c1540088f5859c80.js" async=""></script><script src="/app/_next/static/chunks/3454-988a53dac60a1763.js" async=""></script><script src="/app/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js" async=""></script><script src="/app/_next/static/chunks/9906-482c6619b3fdda20.js" async=""></script><script src="/app/_next/static/chunks/3869-a39d1d9921e10d43.js" async=""></script><script src="/app/_next/static/chunks/2176-c379e3ebce874151.js" async=""></script><script src="/app/_next/static/chunks/5845-e6c003ce8d5fd36a.js" async=""></script><script src="/app/_next/static/chunks/8421-1c4acfb1395a0edf.js" async=""></script><script src="/app/_next/static/chunks/4685-c3c1c625b71accd1.js" async=""></script><script src="/app/_next/static/chunks/app/layout-d6b1d156fb95e74b.js" async=""></script><script src="/app/_next/static/chunks/3638-aa80b4641ea439db.js" async=""></script><script src="/app/_next/static/chunks/app/not-found-e7a529e0507ac86c.js" async=""></script><script src="/app/_next/static/chunks/3278-ae6ef084769f6195.js" async=""></script><script src="/app/_next/static/chunks/7551-a0e0707b79164ddd.js" async=""></script><script src="/app/_next/static/chunks/4215-c9d91dd644ec1719.js" async=""></script><script src="/app/_next/static/chunks/7274-19b7279f18b47ab3.js" async=""></script><script src="/app/_next/static/chunks/2310-7a59f043f6db207e.js" async=""></script><script src="/app/_next/static/chunks/app/settings/page-53f80edc6b8dc07c.js" async=""></script><meta name="next-size-adjust" content=""/><link rel="preload" as="font" type="font/ttf" href="/app/fonts/JetBrainsMonoNerdFontMono-Regular.ttf" crossorigin="anonymous"/><meta name="theme-color" content="#1e1e2e"/><title>elanous</title><meta name="description" content="elanous — voice · chat · intake · control · terminal."/><meta name="application-name" content="elanous"/><link rel="manifest" href="/app/manifest.webmanifest"/><link rel="icon" href="/app/icons/elanous-32.png" sizes="32x32" type="image/png"/><link rel="icon" href="/app/icons/elanous-16.png" sizes="16x16" type="image/png"/><link rel="apple-touch-icon" href="/app/icons/elanous-180.png" sizes="180x180" type="image/png"/><script src="/app/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="min-h-screen bg-background text-foreground antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-screen w-full flex-col bg-background text-foreground"><header class="flex h-9 shrink-0 items-center gap-1 border-b border-border bg-background px-2 text-xs"><button type="button" aria-label="open menu" title="open menu" class="flex shrink-0 items-center gap-1.5 rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu h-4 w-4" aria-hidden="true"><path d="M4 5h16"></path><path d="M4 12h16"></path><path d="M4 19h16"></path></svg><span class="hidden text-[11px] font-medium leading-none sm:inline">메뉴</span></button><div class="ml-auto flex items-center gap-1"><button type="button" data-share-capture-ui="true" aria-label="공유용 캡처" title="공유용 캡처 (beta) — 주소·토큰을 가린 사진을 데몬에 저장" class="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-50"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera h-4 w-4" aria-hidden="true"><path d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"></path><circle cx="12" cy="13" r="3"></circle></svg></button><a aria-label="voice" title="voice (HTTPS Tailscale Serve 필요)" class="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground" href="/app/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mic h-4 w-4" aria-hidden="true"><path d="M12 19v3"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><rect x="9" y="2" width="6" height="13" rx="3"></rect></svg></a><div class="relative"><button type="button" aria-label="settings" title="session — · theme catppuccin-mocha" class="rounded-md p-1.5 hover:bg-accent text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4" aria-hidden="true"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg></button></div></div></header><div class="flex flex-1 min-h-0"><aside class="hidden md:flex md:w-10 md:flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground"><nav class="flex h-full flex-col"><div class="flex-1 space-y-2 px-1 py-2"><section aria-label="오늘"><a title="오늘" aria-label="오늘" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/today/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-inbox h-4 w-4" aria-hidden="true"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg></a></section><section aria-label="대화"><a title="대화" aria-label="대화" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/chat/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square h-4 w-4" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"></path></svg></a></section><section aria-label="일"><a title="일" aria-label="일" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/live/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass h-4 w-4" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></a></section><section aria-label="만들기"><a title="만들기" aria-label="만들기" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/term/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-terminal h-4 w-4" aria-hidden="true"><path d="m7 11 2-2-2-2"></path><path d="M11 13h4"></path><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect></svg></a></section><section aria-label="자료"><a title="자료" aria-label="자료" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/market/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open h-4 w-4" aria-hidden="true"><path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path></svg></a></section><section aria-label="설정"><a title="설정" aria-label="설정" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/settings/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4" aria-hidden="true"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg></a></section></div></nav></aside><main class="flex-1 overflow-auto min-w-0"><div role="status" class="border-b border-border bg-muted px-4 py-2 text-sm text-foreground">베타 — 화면과 동작이 바뀔 수 있습니다.</div><div class="mx-auto max-w-2xl px-6 pt-6"><section aria-label="화면 역할" class="rounded-lg border border-border bg-card p-4"><h2 class="text-base font-semibold">화면 역할</h2><p class="mt-1 text-sm text-muted-foreground">이 기기에서 메뉴에 표시할 화면을 선택하세요. 주소를 직접 입력하면 다른 화면도 열 수 있습니다.</p><div class="mt-3 grid gap-2 sm:grid-cols-3"><button type="button" aria-pressed="false" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-border"><span class="block font-medium">오너</span><span class="mt-1 block text-xs text-muted-foreground">모든 화면과 운영 화면을 봅니다.</span></button><button type="button" aria-pressed="false" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-border"><span class="block font-medium">기여자</span><span class="mt-1 block text-xs text-muted-foreground">베타 화면과 개발 도구를 함께 봅니다.</span></button><button type="button" aria-pressed="true" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-primary bg-primary/10"><span class="block font-medium">일반</span><span class="mt-1 block text-xs text-muted-foreground">사용할 준비가 된 화면을 봅니다.</span></button></div><label class="mt-4 flex items-center justify-between gap-3 border-t border-border pt-4 text-sm"><span>실험 기능 켜기</span><input type="checkbox" role="switch" class="h-5 w-5 accent-primary"/></label></section></div><div class="mx-auto max-w-2xl space-y-8 p-6"><header class="space-y-1"><h1 class="text-xl font-semibold tracking-tight">Settings</h1><p class="text-sm text-muted-foreground">Daemon connection, provider default, theme. Stored in localStorage.</p></header><section class="space-y-2 rounded border border-border bg-card p-4" data-testid="child-llm-preference-card"><p class="text-xs text-muted-foreground">불러오는 중…</p></section><section class="space-y-4 rounded border border-border bg-card p-4" data-testid="answer-depth-card"><header><h2 class="text-sm font-semibold">답변 깊이</h2><p class="text-xs text-muted-foreground">한 번 답할 때 도구를 얼마나 깊게 사용할지 선택하세요.</p></header></section><div id="channels" class="scroll-mt-8" aria-hidden="true"></div><div id="advanced" class="scroll-mt-8" aria-hidden="true"></div><section class="space-y-2" data-testid="llm-catalog-card"><header class="flex items-center justify-between"><h2 class="text-sm font-medium">LLM Catalog</h2><div class="flex items-center gap-2 text-[11px] text-muted-foreground"><span data-testid="llm-catalog-summary">0 providers · 0 models</span><button type="button" aria-label="Toggle view: list vs capability matrix" data-testid="llm-catalog-view-toggle" class="rounded px-1.5 py-0.5 text-[10px] uppercase font-medium hover:bg-surface-elevated">matrix</button><button type="button" aria-label="Run discovery refresh" data-testid="llm-catalog-refresh" class="rounded p-1 hover:bg-surface-elevated disabled:opacity-50"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-3 w-3" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg></button></div></header></section><section data-testid="chat-routing-settings" class="rounded-lg border bg-card p-4 shadow-sm"><header class="space-y-1"><h2 class="text-sm font-medium">Chat input classification</h2><p class="text-xs text-muted-foreground">입력 중 자동 분류를 켜거나 끕니다. 전송은 기존 ACP 경로를 유지합니다.</p></header><div class="mt-3 space-y-2"><label data-testid="chat-routing-auto" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="checkbox" class="mt-0.5 h-4 w-4"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">Automatic routing</span><span class="text-xs text-muted-foreground">입력 중 mission router 가 plan / build / review / research / quick / vision 으로 자동 분류합니다. OFF (default) 시 분류 요청을 보내지 않습니다.</span></span></label></div></section><section class="space-y-3 rounded-lg border border-border bg-card p-4" data-testid="fast-reply-card"><h2 class="text-sm font-medium">짧은 물음은 빠르게</h2><p class="text-xs text-muted-foreground">인사·짧은 물음은 도구 없이 먼저 답합니다 — 확인이 필요하면 "확인해 볼까요?"</p><label class="flex items-center gap-2 text-sm"><input type="checkbox" disabled="" aria-label="빠른 답변 켜기/끄기"/>불러오는 중</label></section><section data-testid="intent-panel-settings" class="rounded-lg border bg-card p-4 shadow-sm"><header class="space-y-1"><h2 class="text-sm font-medium">Intent Panel</h2><p class="text-xs text-muted-foreground">Showroom 의 intent 6-button 패널 표시 방식을 선택합니다.</p></header><div role="radiogroup" aria-label="intent panel display mode" class="mt-3 space-y-2"><label data-testid="intent-panel-mode-fixed" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="fixed"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">고정 (Fixed)</span><span class="text-xs text-muted-foreground">입력 바 위에 항상 표시. 키보드 위주 dogfood 에 좋음.</span></span></label><label data-testid="intent-panel-mode-popup" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="popup"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">팝업 (Popup)</span><span class="text-xs text-muted-foreground">턴이 끝날 때마다 잠깐 (~6초) 나타나고 자동 dismiss. 모바일 화면 절약.</span></span></label><label data-testid="intent-panel-mode-off" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="off"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">끔 (Off)</span><span class="text-xs text-muted-foreground">완전 숨김. 입력만으로 진행하고 싶을 때.</span></span></label></div></section><section data-testid="notes-metrics-card" class="rounded-lg border border-border bg-card p-4 shadow-sm"><header class="mb-3 flex items-center justify-between gap-2"><div><h3 class="font-heading text-sm font-medium">카메라 노트 metric</h3><p class="text-xs text-muted-foreground">카메라 → markdown 노트 파이프라인 사용량 (daemon 재시작 시 0 으로 리셋).</p></div><button type="button" tabindex="0" data-slot="button" aria-label="refresh notes metrics" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-3.5 w-3.5" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg></button></header><p data-testid="notes-metrics-not-wired" class="mb-3 rounded bg-muted/50 px-2 py-1 text-xs text-muted-foreground">collector 미wire — runNexus 재기동 후 측정 시작.</p><dl class="grid grid-cols-2 gap-x-4 gap-y-1 text-xs"><dt class="text-muted-foreground">OCR 총 / 성공 / 실패</dt><dd data-testid="notes-metrics-ocr">0<!-- --> / <!-- -->0<!-- --> / <!-- -->0</dd><dt class="text-muted-foreground">OCR provider</dt><dd data-testid="notes-metrics-ocr-providers">—</dd><dt class="text-muted-foreground">OCR polishMode</dt><dd data-testid="notes-metrics-ocr-polish">—</dd><dt class="text-muted-foreground">Save 총 / 성공 / 실패</dt><dd data-testid="notes-metrics-save">0<!-- --> / <!-- -->0<!-- --> / <!-- -->0</dd><dt class="text-muted-foreground">Save polishMode</dt><dd data-testid="notes-metrics-save-polish">—</dd><dt class="text-muted-foreground">Client cancel · edit · discard</dt><dd data-testid="notes-metrics-client">0<!-- --> · <!-- -->0<!-- --> · <!-- -->0</dd></dl></section><section data-testid="ocr-prefs-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">📷 OCR 기본 설정</h3><p class="text-xs text-muted-foreground">사진 → 노트 모달의 초기 토글 상태. 매번 같은 옵션을 켜고 있다면 default 로 저장.</p></header><div class="space-y-2"><label class="flex items-center justify-between gap-3 rounded-md border border-input bg-background px-3 py-2 text-xs"><span class="flex items-center gap-2"><span>LLM 비전 default</span><span class="text-muted-foreground">· 더 정확하지만 느림 + 비쌈</span></span><input type="checkbox" data-testid="ocr-prefs-llm-vision" aria-label="LLM 비전 default"/></label><label class="flex items-center justify-between gap-3 rounded-md border border-input bg-background px-3 py-2 text-xs"><span class="flex items-center gap-2"><span>손글씨 default</span><span class="text-muted-foreground">· handwriting strength 자동 추가</span></span><input type="checkbox" data-testid="ocr-prefs-handwriting" aria-label="손글씨 default"/></label></div><div class="mt-3"><button type="button" tabindex="0" data-slot="button" data-testid="ocr-prefs-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">기본값으로 리셋</button></div></section><div id="voice" class="scroll-mt-8" aria-hidden="true"></div><section data-testid="voice-prefs-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🎙️ Voice barge-in 튜닝</h3><p class="text-xs text-muted-foreground">BI-2 ducking 강도 — TTS 재생 중 자기-에코 false-fire 를 막는 RMS multiplier. 변경은 voice toggle off → on 또는 새로고침 시 적용.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">speaking threshold multiplier</span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="voice-prefs-multiplier-value">2.0×</span></div><input type="range" min="1" max="5" step="0.1" data-testid="voice-prefs-multiplier-slider" aria-label="Speaking threshold multiplier" aria-valuemin="1" aria-valuemax="5" aria-valuenow="2" class="w-full" value="2"/><p class="mt-1 text-[11px] text-muted-foreground" data-testid="voice-prefs-hint">기본값 — 대부분 환경에서 균형</p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="voice-prefs-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">기본값으로 리셋 (<!-- -->2.0<!-- -->×)</button></div></section><section data-testid="preset-card-grid" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2 flex items-start justify-between"><div><h3 class="text-sm font-semibold">⚡ Quick presets</h3><p class="text-xs text-muted-foreground">One-click bundles for common use cases — applies STT, LLM, TTS, voice id, and budget cap together. You can still fine-tune any slider after applying.</p></div></header><div class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3" data-testid="preset-card-list"><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-casual_chat"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">💬<!-- --> <!-- -->Casual chat</span></div><p class="text-[11px] text-muted-foreground">Day-to-day messaging · cheap STT / LLM · no read-back.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-meeting"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">📋<!-- --> <!-- -->Meeting notes</span></div><p class="text-[11px] text-muted-foreground">Balanced accuracy for transcripts · standard LLM summarization.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->5</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-medical_dictation"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🏥<!-- --> <!-- -->Medical / legal dictation</span></div><p class="text-[11px] text-muted-foreground">Loaded STT (timestamps + jargon adaptation) · Best LLM · ElevenLabs voice.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->loaded</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->best</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->best</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->20</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-live_caption"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🎬<!-- --> <!-- -->Live captioning</span></div><p class="text-[11px] text-muted-foreground">Low-latency STT · LLM disabled · no read-back.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-sleep_mode"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🌙<!-- --> <!-- -->Sleep mode</span></div><p class="text-[11px] text-muted-foreground">Cost zero · local-only models · no API calls.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->0</span></div></button></div></section><section data-testid="voice-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🎚️ Voice transcription quality</h3><p class="text-xs text-muted-foreground">Pick how accurate vs. cheap the speech-to-text should be — elanous picks the model. Switching takes effect on the next voice call.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="voice-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="voice-model-tier-cost">0.003/min</span></div><input type="range" min="0" max="4" step="1" data-testid="voice-model-tier-slider" aria-label="Voice transcription tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="voice-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="voice-model-tier-rationale">Sensible default · streaming · $0.003/min</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="voice-model-tier-model-id">Model: <span class="font-mono">gpt-4o-mini-transcribe</span></p></div></div><div class="mt-3 flex items-center gap-2"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="voice-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="llm-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🧠 AI assistant quality</h3><p class="text-xs text-muted-foreground">Pick how careful vs. fast the model should think. elanous chooses the right model on your active provider · the slider stays the same across providers.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="llm-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="llm-model-tier-provider">Anthropic</span></div><input type="range" min="0" max="4" step="1" data-testid="llm-model-tier-slider" aria-label="AI assistant tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="llm-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="llm-model-tier-rationale">Default · fast multi-turn</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="llm-model-tier-model-id">Model: <span class="font-mono">claude-haiku-4-5</span><span class="ml-1 text-muted-foreground">· reasoning: <span class="font-mono">off</span></span></p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="llm-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="tts-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🔊 Voice playback quality</h3><p class="text-xs text-muted-foreground">Pick text-to-speech quality vs. cost. Voice identity (Rachel · SoYoung · custom) lives in a separate picker (Phase 2 M2-2b).</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="tts-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="tts-model-tier-rate">$15/M chars</span></div><input type="range" min="0" max="4" step="1" data-testid="tts-model-tier-slider" aria-label="Voice playback tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="tts-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="tts-model-tier-rationale">Default · $15/M chars · multi-voice</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="tts-model-tier-model-id">Provider: <span class="font-mono">openai-tts</span><span class="ml-1">·</span><span class="ml-1">Model: <span class="font-mono">tts-1</span></span></p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="tts-voice-id-picker-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2 flex items-start justify-between"><div><h3 class="text-sm font-semibold">🗣️ Voice identity (per context)</h3><p class="text-xs text-muted-foreground">Pick a different voice per surface (chat / morning digest / alerts / Discord). Browse the ElevenLabs library or paste a voice id directly.</p></div></header><div class="space-y-2" data-testid="tts-voice-rows"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-default-label">Default</span></div><p class="mb-1 text-[10px] text-muted-foreground">Fallback when a specific context isn't set</p><div class="flex gap-2"><input id="base-ui-_R_1pdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-default-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-default-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-default-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-chat-label">Chat reply</span></div><p class="mb-1 text-[10px] text-muted-foreground">Used by the PWA / TUI chat surface</p><div class="flex gap-2"><input id="base-ui-_R_1qdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-chat-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-chat-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-chat-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-digest-label">Morning digest</span></div><p class="mb-1 text-[10px] text-muted-foreground">Daily summary read-back (P2-D7)</p><div class="flex gap-2"><input id="base-ui-_R_1rdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-digest-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-digest-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-digest-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-alert-label">Push alerts</span></div><p class="mb-1 text-[10px] text-muted-foreground">Urgency-driven voice for push notifications</p><div class="flex gap-2"><input id="base-ui-_R_1sdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-alert-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-alert-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-alert-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-discord-label">Discord bot</span></div><p class="mb-1 text-[10px] text-muted-foreground">X9 Discord voice channel + DM voice replies</p><div class="flex gap-2"><input id="base-ui-_R_1tdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-discord-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-discord-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-discord-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div></div><div class="mt-3 flex items-center justify-between gap-2"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-reset-all" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset all</button><p class="text-[10px] text-muted-foreground/80">Paste voice id manually until daemon library is reachable</p></div></section><section class="space-y-4 rounded-md border border-border bg-card p-4" data-testid="embedding-vision-card"><header class="space-y-1"><h2 class="text-sm font-medium">Embedding · Vision tier</h2><p class="text-xs text-muted-foreground">Phase 3 scaffolding — model selection for RAG embedding + image vision. Resolvers wired; call-site integration follows as RAG / vision pipelines come online.</p></header><div class="space-y-1.5" data-testid="embedding-vision-row-embedding"><div class="flex items-center justify-between"><h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Embedding</h3><span class="text-[10px] text-zinc-400 dark:text-zinc-500">Smart default</span></div><p class="text-[11px] text-zinc-500 dark:text-zinc-400">RAG retrieval · similarity. Most users never touch this.</p><div class="flex flex-wrap gap-1"><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-budget" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Budget</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-balanced" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Balanced</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-better" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Better</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-best" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Best</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-loaded" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Loaded</button></div></div><div class="space-y-1.5" data-testid="embedding-vision-row-vision"><div class="flex items-center justify-between"><h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Vision</h3><span class="text-[10px] text-zinc-400 dark:text-zinc-500">Smart default</span></div><p class="text-[11px] text-zinc-500 dark:text-zinc-400">OCR · screenshot analysis · note-from-image.</p><div class="flex flex-wrap gap-1"><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-budget" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Budget</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-balanced" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Balanced</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-better" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Better</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-best" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Best</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-loaded" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Loaded</button></div></div></section><section class="space-y-3"><h2 class="text-sm font-medium">데몬 연결</h2><label class="block space-y-1"><span class="text-xs text-muted-foreground">Base URL</span><input id="base-ui-_R_29p5fivemtb_" data-slot="input" placeholder="http://localhost:31415" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40" value=""/></label><label class="block space-y-1"><span class="text-xs text-muted-foreground">연결 토큰</span><input id="bearer-token" type="password" data-slot="input" placeholder="다른 기기에서 만든 연결 토큰을 붙여 넣으세요" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40" value=""/></label><label class="block space-y-1"><span class="text-xs text-muted-foreground">Default provider</span><select class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs focus:outline-none focus:ring-2 focus:ring-ring"><option value="" selected="">(none — server default)</option><option value="claude">claude</option><option value="gemini">gemini</option><option value="grok">grok</option><option value="codex">codex</option></select></label></section><section class="space-y-3"><div class="flex items-center justify-between"><h2 class="text-sm font-medium">Daemon health</h2><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">Recheck</button></div><div class="rounded-md border border-border bg-card p-3 text-xs"><p class="text-muted-foreground">Set Base URL above to probe.</p></div></section><div id="tools" class="scroll-mt-8" aria-hidden="true"></div><div id="ios" class="scroll-mt-8" aria-hidden="true"></div><section class="space-y-3"><h2 class="text-sm font-medium">대화</h2><div class="rounded-md border border-border bg-card px-3 py-2 font-mono text-xs">(no session yet)</div><p class="text-xs text-muted-foreground">A new session id is allocated on first load. Use Chat’s<code class="mx-1 rounded bg-muted px-1.5 py-0.5">:fork</code>meta-command to start fresh once U-3 ships.</p></section><section class="space-y-3"><h2 class="text-sm font-medium">Theme</h2><div class="flex flex-wrap gap-2"><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">catppuccin-mocha</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">mocha-pastel-accent</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">catppuccin-latte</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">rose-pine-dawn</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">nord-light</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">elanous-pastel-default</button></div></section><section data-testid="advanced-setup-map" class="space-y-2"><h2 class="text-sm font-medium">Advanced setup map</h2><div class="rounded-md border border-border bg-card p-3 text-xs"><p class="mb-2 text-muted-foreground">NEXUS native 셋업 영역은 PWA 에서 직접 · 그 외 advanced 셋업은 desktop wizard 또는 NEXUS subcommand 에서.</p><table class="w-full text-left text-[11px]"><thead><tr class="border-b border-border text-muted-foreground"><th class="py-1 pr-2 font-medium">영역</th><th class="py-1 pr-2 font-medium">상태</th><th class="py-1 font-medium">셋업 위치</th></tr></thead><tbody><tr data-testid="advanced-setup-row-Chat 백엔드" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Chat 백엔드</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Quick Setup card</td></tr><tr data-testid="advanced-setup-row-Telegram bot token" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Telegram bot token</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Secret modal</td></tr><tr data-testid="advanced-setup-row-Discord bot token" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Discord bot token</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Secret modal</td></tr><tr data-testid="advanced-setup-row-Telegram allowlist" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Telegram allowlist</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ Wizard 전용</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous legacy → /setup</code></td></tr><tr data-testid="advanced-setup-row-Discord guild · voice" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Discord guild · voice</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ Wizard 전용</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous legacy → /setup</code></td></tr><tr data-testid="advanced-setup-row-OS 자동 부팅" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">OS 자동 부팅</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ NEXUS subcommand</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous nexus install --launchd</code></td></tr></tbody></table></div></section><section class="space-y-3 rounded-2xl border border-border bg-card p-4" aria-label="메뉴"><h2 class="text-base font-semibold">메뉴</h2><p class="text-xs text-muted-foreground">메뉴에는 주요 탭만 보입니다. Labs(베타)와 숨긴 탭은 이 기기에서만 켤 수 있고, 숨긴 탭도 주소로는 열립니다.</p><label class="flex items-start gap-2 text-sm"><input type="checkbox" data-elanous-action="menu-show-labs"/><span>Labs 탭 보기 <span class="text-xs text-muted-foreground">(<!-- -->편집기 · 여러 탭 · 보드 · Showroom<!-- -->)</span></span></label><label class="flex items-start gap-2 text-sm"><input type="checkbox" data-elanous-action="menu-show-hidden"/><span>숨긴 탭 보기 <span class="text-xs text-muted-foreground">(<!-- -->봇 · 관측 · 작업 트리 · 제어 · Tasks · 대화 카드 · Reflection<!-- -->)</span></span></label></section><section class="space-y-3 rounded-2xl border border-border bg-card p-4"><div><h2 class="text-base font-semibold">빌드 정보</h2><p class="text-xs text-muted-foreground">배포 최신 여부 판별 — 새로고침 후 시각/SHA 가 안 바뀌면 옛 캐시.</p></div><div class="grid gap-3 sm:grid-cols-2"><div class="rounded-xl bg-muted/40 p-3"><div class="text-[11px] uppercase tracking-wide text-muted-foreground">PWA 프론트 빌드</div><div class="mt-1 font-mono text-sm">26. 10. 04. 04:37<!-- --> · e61a984</div></div><div class="rounded-xl bg-muted/40 p-3"><div class="text-[11px] uppercase tracking-wide text-muted-foreground">데몬(백엔드) 시작</div><div class="mt-1 font-mono text-sm ">…</div></div></div></section><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2">Saved</button></div><!--$--><!--/$--></main></div><!--$!--><template data-dgst="BAILOUT_TO_CLIENT_SIDE_RENDERING"></template><!--/$--></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/app/_next/static/chunks/webpack-9e4d02d567b98240.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n"])</script><script>self.__next_f.push([1,"2:I[27365,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"ServiceWorkerRegister\"]\n"])</script><script>self.__next_f.push([1,"3:I[50179,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"NewBuildBanner\"]\n"])</script><script>self.__next_f.push([1,"4:I[36581,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"DaemonProvider\"]\n"])</script><script>self.__next_f.push([1,"5:I[78401,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"OperatorRoleDefault\"]\n"])</script><script>self.__next_f.push([1,"6:I[24969,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"NexusClientProvider\"]\n"])</script><script>self.__next_f.push([1,"7:I[70090,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"ThemeProvider\"]\n"])</script><script>self.__next_f.push([1,"8:I[50977,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"TooltipProvider\"]\n"])</script><script>self.__next_f.push([1,"9:I[34485,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"ToastProvider\"]\n"])</script><script>self.__next_f.push([1,"a:I[37370,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"AppShell\"]\n"])</script><script>self.__next_f.push([1,"b:I[14381,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-d6b1d156fb95e74b.js\"],\"MaturityBanner\"]\n"])</script><script>self.__next_f.push([1,"c:I[56429,[],\"\"]\nd:I[59193,[],\"\"]\ne:I[33568,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"3638\",\"static/chunks/3638-aa80b4641ea439db.js\",\"4345\",\"static/chunks/app/not-found-e7a529e0507ac86c.js\"],\"default\"]\nf:I[76132,[],\"ClientPageRoot\"]\n"])</script><script>self.__next_f.push([1,"10:I[43591,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"3278\",\"static/chunks/3278-ae6ef084769f6195.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"7551\",\"static/chunks/7551-a0e0707b79164ddd.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-a39d1d9921e10d43.js\",\"4215\",\"static/chunks/4215-c9d91dd644ec1719.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"7274\",\"static/chunks/7274-19b7279f18b47ab3.js\",\"2310\",\"static/chunks/2310-7a59f043f6db207e.js\",\"4662\",\"static/chunks/app/settings/page-53f80edc6b8dc07c.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"13:I[38032,[],\"OutletBoundary\"]\n15:I[55369,[],\"AsyncMetadataOutlet\"]\n17:I[38032,[],\"ViewportBoundary\"]\n19:I[38032,[],\"MetadataBoundary\"]\n1a:\"$Sreact.suspense\"\n1c:I[9551,[],\"\"]\n:HL[\"/app/_next/static/media/22a5144ee8d83bca-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/app/_next/static/css/543f56bcb1f79fca.css\",\"style\"]\n:HL[\"/app/_next/static/css/04dabcbcc4bfa6db.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Y4zKzL62sakG5momz3SoQ\",\"p\":\"/app\",\"c\":[\"\",\"settings\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"settings\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/app/_next/static/css/543f56bcb1f79fca.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/app/_next/static/css/04dabcbcc4bfa6db.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"font-sans __variable_45c93f\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"link\",null,{\"rel\":\"preload\",\"as\":\"font\",\"type\":\"font/ttf\",\"href\":\"/app/fonts/JetBrainsMonoNerdFontMono-Regular.ttf\",\"crossOrigin\":\"anonymous\"}]}],[\"$\",\"body\",null,{\"className\":\"min-h-screen bg-background text-foreground antialiased\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"$L3\",null,{}],[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$L8\",null,{\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$La\",null,{\"children\":[[\"$\",\"$Lb\",null,{}],[\"$\",\"$Lc\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Ld\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"$Le\",null,{}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]}]}]}]}]]}]]}]]}]]}],{\"children\":[\"settings\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$Lc\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Ld\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$Lf\",null,{\"Component\":\"$10\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@11\",\"$@12\"]}],null,[\"$\",\"$L13\",null,{\"children\":[\"$L14\",[\"$\",\"$L15\",null,{\"promise\":\"$@16\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$L17\",null,{\"children\":\"$L18\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$L19\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$1a\",null,{\"fallback\":null,\"children\":\"$L1b\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$1c\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"11:{}\n12:\"$0:f:0:1:2:children:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"18:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#1e1e2e\"}]]\n14:null\n"])</script><script>self.__next_f.push([1,"1d:I[35241,[],\"IconMark\"]\n"])</script><script>self.__next_f.push([1,"16:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"elanous\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"elanous — voice · chat · intake · control · terminal.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"elanous\"}],[\"$\",\"link\",\"3\",{\"rel\":\"manifest\",\"href\":\"/app/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/app/icons/elanous-32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/app/icons/elanous-16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"6\",{\"rel\":\"apple-touch-icon\",\"href\":\"/app/icons/elanous-180.png\",\"sizes\":\"180x180\",\"type\":\"image/png\"}],[\"$\",\"$L1d\",\"7\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"1b:\"$16:metadata\"\n"])</script></body></html>
|
|
1
|
+
<!DOCTYPE html><!--_6XrAoD3eU7NyMHAE4xPS--><html lang="ko" class="font-sans __variable_45c93f"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/><link rel="preload" href="/app/_next/static/media/22a5144ee8d83bca-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/app/_next/static/css/128fb7fb670b2fbf.css" data-precedence="next"/><link rel="stylesheet" href="/app/_next/static/css/04dabcbcc4bfa6db.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/app/_next/static/chunks/webpack-9e4d02d567b98240.js"/><script src="/app/_next/static/chunks/5cd7e3a9-404fd6b8d0ecd44c.js" async=""></script><script src="/app/_next/static/chunks/3170-7ec60a56fa0e4728.js" async=""></script><script src="/app/_next/static/chunks/main-app-f0fe2d7477845181.js" async=""></script><script src="/app/_next/static/chunks/7777-79f845045aa1ed86.js" async=""></script><script src="/app/_next/static/chunks/9538-2816b90923606459.js" async=""></script><script src="/app/_next/static/chunks/1829-b453a1b22d3999bb.js" async=""></script><script src="/app/_next/static/chunks/6048-4c5c33579bc4ef78.js" async=""></script><script src="/app/_next/static/chunks/9656-c1540088f5859c80.js" async=""></script><script src="/app/_next/static/chunks/3454-988a53dac60a1763.js" async=""></script><script src="/app/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js" async=""></script><script src="/app/_next/static/chunks/9906-482c6619b3fdda20.js" async=""></script><script src="/app/_next/static/chunks/3869-3cd46526879f454c.js" async=""></script><script src="/app/_next/static/chunks/2176-c379e3ebce874151.js" async=""></script><script src="/app/_next/static/chunks/5845-e6c003ce8d5fd36a.js" async=""></script><script src="/app/_next/static/chunks/8421-1c4acfb1395a0edf.js" async=""></script><script src="/app/_next/static/chunks/4685-c3c1c625b71accd1.js" async=""></script><script src="/app/_next/static/chunks/app/layout-e71c84189e8c683e.js" async=""></script><script src="/app/_next/static/chunks/3638-aa80b4641ea439db.js" async=""></script><script src="/app/_next/static/chunks/app/not-found-490653e8d4cc8852.js" async=""></script><script src="/app/_next/static/chunks/3278-ae6ef084769f6195.js" async=""></script><script src="/app/_next/static/chunks/7551-a0e0707b79164ddd.js" async=""></script><script src="/app/_next/static/chunks/4215-c9d91dd644ec1719.js" async=""></script><script src="/app/_next/static/chunks/7274-19b7279f18b47ab3.js" async=""></script><script src="/app/_next/static/chunks/7758-0b018a9e4fc56200.js" async=""></script><script src="/app/_next/static/chunks/app/settings/page-db14d0be7f1c460c.js" async=""></script><meta name="next-size-adjust" content=""/><link rel="preload" as="font" type="font/ttf" href="/app/fonts/JetBrainsMonoNerdFontMono-Regular.ttf" crossorigin="anonymous"/><meta name="theme-color" content="#1e1e2e"/><title>elanous</title><meta name="description" content="elanous — voice · chat · intake · control · terminal."/><meta name="application-name" content="elanous"/><link rel="manifest" href="/app/manifest.webmanifest"/><link rel="icon" href="/app/icons/elanous-32.png" sizes="32x32" type="image/png"/><link rel="icon" href="/app/icons/elanous-16.png" sizes="16x16" type="image/png"/><link rel="apple-touch-icon" href="/app/icons/elanous-180.png" sizes="180x180" type="image/png"/><script src="/app/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="min-h-screen bg-background text-foreground antialiased"><div hidden=""><!--$--><!--/$--></div><div class="flex h-screen w-full flex-col bg-background text-foreground"><header class="flex h-9 shrink-0 items-center gap-1 border-b border-border bg-background px-2 text-xs"><button type="button" aria-label="open menu" title="open menu" class="flex shrink-0 items-center gap-1.5 rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu h-4 w-4" aria-hidden="true"><path d="M4 5h16"></path><path d="M4 12h16"></path><path d="M4 19h16"></path></svg><span class="hidden text-[11px] font-medium leading-none sm:inline">메뉴</span></button><div class="ml-auto flex items-center gap-1"><button type="button" data-share-capture-ui="true" aria-label="공유용 캡처" title="공유용 캡처 (beta) — 주소·토큰을 가린 사진을 데몬에 저장" class="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-50"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera h-4 w-4" aria-hidden="true"><path d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"></path><circle cx="12" cy="13" r="3"></circle></svg></button><a aria-label="voice" title="voice (HTTPS Tailscale Serve 필요)" class="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground" href="/app/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mic h-4 w-4" aria-hidden="true"><path d="M12 19v3"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><rect x="9" y="2" width="6" height="13" rx="3"></rect></svg></a><div class="relative"><button type="button" aria-label="settings" title="session — · theme catppuccin-mocha" class="rounded-md p-1.5 hover:bg-accent text-muted-foreground hover:text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4" aria-hidden="true"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg></button></div></div></header><div class="flex flex-1 min-h-0"><aside class="hidden md:flex md:w-10 md:flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground"><nav class="flex h-full flex-col"><div class="flex-1 space-y-2 px-1 py-2"><section aria-label="오늘"><a title="오늘" aria-label="오늘" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/today/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-inbox h-4 w-4" aria-hidden="true"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg></a></section><section aria-label="대화"><a title="대화" aria-label="대화" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/chat/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square h-4 w-4" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"></path></svg></a></section><section aria-label="일"><a title="일" aria-label="일" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/live/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-compass h-4 w-4" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"></path></svg></a></section><section aria-label="만들기"><a title="만들기" aria-label="만들기" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/term/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-terminal h-4 w-4" aria-hidden="true"><path d="m7 11 2-2-2-2"></path><path d="M11 13h4"></path><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect></svg></a></section><section aria-label="자료"><a title="자료" aria-label="자료" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/market/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open h-4 w-4" aria-hidden="true"><path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path></svg></a></section><section aria-label="설정"><a title="설정" aria-label="설정" class="relative flex justify-center rounded-md px-1.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent" href="/app/settings/"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4" aria-hidden="true"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg></a></section></div></nav></aside><main class="flex-1 overflow-auto min-w-0"><div role="status" class="border-b border-border bg-muted px-4 py-2 text-sm text-foreground">베타 — 화면과 동작이 바뀔 수 있습니다.</div><div class="mx-auto max-w-2xl px-6 pt-6"><section aria-label="화면 역할" class="rounded-lg border border-border bg-card p-4"><h2 class="text-base font-semibold">화면 역할</h2><p class="mt-1 text-sm text-muted-foreground">이 기기에서 메뉴에 표시할 화면을 선택하세요. 주소를 직접 입력하면 다른 화면도 열 수 있습니다.</p><div class="mt-3 grid gap-2 sm:grid-cols-3"><button type="button" aria-pressed="false" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-border"><span class="block font-medium">오너</span><span class="mt-1 block text-xs text-muted-foreground">모든 화면과 운영 화면을 봅니다.</span></button><button type="button" aria-pressed="false" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-border"><span class="block font-medium">기여자</span><span class="mt-1 block text-xs text-muted-foreground">베타 화면과 개발 도구를 함께 봅니다.</span></button><button type="button" aria-pressed="true" class="rounded-lg border p-3 text-left transition-colors hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring border-primary bg-primary/10"><span class="block font-medium">일반</span><span class="mt-1 block text-xs text-muted-foreground">사용할 준비가 된 화면을 봅니다.</span></button></div><label class="mt-4 flex items-center justify-between gap-3 border-t border-border pt-4 text-sm"><span>실험 기능 켜기</span><input type="checkbox" role="switch" class="h-5 w-5 accent-primary"/></label></section></div><div class="mx-auto max-w-2xl space-y-8 p-6"><header class="space-y-1"><h1 class="text-xl font-semibold tracking-tight">Settings</h1><p class="text-sm text-muted-foreground">Daemon connection, provider default, theme. Stored in localStorage.</p></header><section class="space-y-2 rounded border border-border bg-card p-4" data-testid="child-llm-preference-card"><p class="text-xs text-muted-foreground">불러오는 중…</p></section><section class="space-y-4 rounded border border-border bg-card p-4" data-testid="answer-depth-card"><header><h2 class="text-sm font-semibold">답변 깊이</h2><p class="text-xs text-muted-foreground">한 번 답할 때 도구를 얼마나 깊게 사용할지 선택하세요.</p></header></section><div id="channels" class="scroll-mt-8" aria-hidden="true"></div><div id="advanced" class="scroll-mt-8" aria-hidden="true"></div><section class="space-y-2" data-testid="llm-catalog-card"><header class="flex items-center justify-between"><h2 class="text-sm font-medium">LLM Catalog</h2><div class="flex items-center gap-2 text-[11px] text-muted-foreground"><span data-testid="llm-catalog-summary">0 providers · 0 models</span><button type="button" aria-label="Toggle view: list vs capability matrix" data-testid="llm-catalog-view-toggle" class="rounded px-1.5 py-0.5 text-[10px] uppercase font-medium hover:bg-surface-elevated">matrix</button><button type="button" aria-label="Run discovery refresh" data-testid="llm-catalog-refresh" class="rounded p-1 hover:bg-surface-elevated disabled:opacity-50"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-3 w-3" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg></button></div></header></section><section data-testid="chat-routing-settings" class="rounded-lg border bg-card p-4 shadow-sm"><header class="space-y-1"><h2 class="text-sm font-medium">Chat input classification</h2><p class="text-xs text-muted-foreground">입력 중 자동 분류를 켜거나 끕니다. 전송은 기존 ACP 경로를 유지합니다.</p></header><div class="mt-3 space-y-2"><label data-testid="chat-routing-auto" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="checkbox" class="mt-0.5 h-4 w-4"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">Automatic routing</span><span class="text-xs text-muted-foreground">입력 중 mission router 가 plan / build / review / research / quick / vision 으로 자동 분류합니다. OFF (default) 시 분류 요청을 보내지 않습니다.</span></span></label></div></section><section class="space-y-3 rounded-lg border border-border bg-card p-4" data-testid="fast-reply-card"><h2 class="text-sm font-medium">짧은 물음은 빠르게</h2><p class="text-xs text-muted-foreground">인사·짧은 물음은 도구 없이 먼저 답합니다 — 확인이 필요하면 "확인해 볼까요?"</p><label class="flex items-center gap-2 text-sm"><input type="checkbox" disabled="" aria-label="빠른 답변 켜기/끄기"/>불러오는 중</label></section><section data-testid="intent-panel-settings" class="rounded-lg border bg-card p-4 shadow-sm"><header class="space-y-1"><h2 class="text-sm font-medium">Intent Panel</h2><p class="text-xs text-muted-foreground">Showroom 의 intent 6-button 패널 표시 방식을 선택합니다.</p></header><div role="radiogroup" aria-label="intent panel display mode" class="mt-3 space-y-2"><label data-testid="intent-panel-mode-fixed" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="fixed"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">고정 (Fixed)</span><span class="text-xs text-muted-foreground">입력 바 위에 항상 표시. 키보드 위주 dogfood 에 좋음.</span></span></label><label data-testid="intent-panel-mode-popup" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="popup"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">팝업 (Popup)</span><span class="text-xs text-muted-foreground">턴이 끝날 때마다 잠깐 (~6초) 나타나고 자동 dismiss. 모바일 화면 절약.</span></span></label><label data-testid="intent-panel-mode-off" class="flex cursor-pointer items-start gap-3 rounded-md border border-border/60 p-3 hover:border-border" data-active="false"><input type="radio" class="mt-0.5 h-4 w-4" name="intent-panel-display-mode" value="off"/><span class="flex flex-col gap-0.5"><span class="text-sm font-medium">끔 (Off)</span><span class="text-xs text-muted-foreground">완전 숨김. 입력만으로 진행하고 싶을 때.</span></span></label></div></section><section data-testid="notes-metrics-card" class="rounded-lg border border-border bg-card p-4 shadow-sm"><header class="mb-3 flex items-center justify-between gap-2"><div><h3 class="font-heading text-sm font-medium">카메라 노트 metric</h3><p class="text-xs text-muted-foreground">카메라 → markdown 노트 파이프라인 사용량 (daemon 재시작 시 0 으로 리셋).</p></div><button type="button" tabindex="0" data-slot="button" aria-label="refresh notes metrics" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-3.5 w-3.5" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg></button></header><p data-testid="notes-metrics-not-wired" class="mb-3 rounded bg-muted/50 px-2 py-1 text-xs text-muted-foreground">collector 미wire — runNexus 재기동 후 측정 시작.</p><dl class="grid grid-cols-2 gap-x-4 gap-y-1 text-xs"><dt class="text-muted-foreground">OCR 총 / 성공 / 실패</dt><dd data-testid="notes-metrics-ocr">0<!-- --> / <!-- -->0<!-- --> / <!-- -->0</dd><dt class="text-muted-foreground">OCR provider</dt><dd data-testid="notes-metrics-ocr-providers">—</dd><dt class="text-muted-foreground">OCR polishMode</dt><dd data-testid="notes-metrics-ocr-polish">—</dd><dt class="text-muted-foreground">Save 총 / 성공 / 실패</dt><dd data-testid="notes-metrics-save">0<!-- --> / <!-- -->0<!-- --> / <!-- -->0</dd><dt class="text-muted-foreground">Save polishMode</dt><dd data-testid="notes-metrics-save-polish">—</dd><dt class="text-muted-foreground">Client cancel · edit · discard</dt><dd data-testid="notes-metrics-client">0<!-- --> · <!-- -->0<!-- --> · <!-- -->0</dd></dl></section><section data-testid="ocr-prefs-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">📷 OCR 기본 설정</h3><p class="text-xs text-muted-foreground">사진 → 노트 모달의 초기 토글 상태. 매번 같은 옵션을 켜고 있다면 default 로 저장.</p></header><div class="space-y-2"><label class="flex items-center justify-between gap-3 rounded-md border border-input bg-background px-3 py-2 text-xs"><span class="flex items-center gap-2"><span>LLM 비전 default</span><span class="text-muted-foreground">· 더 정확하지만 느림 + 비쌈</span></span><input type="checkbox" data-testid="ocr-prefs-llm-vision" aria-label="LLM 비전 default"/></label><label class="flex items-center justify-between gap-3 rounded-md border border-input bg-background px-3 py-2 text-xs"><span class="flex items-center gap-2"><span>손글씨 default</span><span class="text-muted-foreground">· handwriting strength 자동 추가</span></span><input type="checkbox" data-testid="ocr-prefs-handwriting" aria-label="손글씨 default"/></label></div><div class="mt-3"><button type="button" tabindex="0" data-slot="button" data-testid="ocr-prefs-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">기본값으로 리셋</button></div></section><div id="voice" class="scroll-mt-8" aria-hidden="true"></div><section data-testid="voice-prefs-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🎙️ Voice barge-in 튜닝</h3><p class="text-xs text-muted-foreground">BI-2 ducking 강도 — TTS 재생 중 자기-에코 false-fire 를 막는 RMS multiplier. 변경은 voice toggle off → on 또는 새로고침 시 적용.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">speaking threshold multiplier</span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="voice-prefs-multiplier-value">2.0×</span></div><input type="range" min="1" max="5" step="0.1" data-testid="voice-prefs-multiplier-slider" aria-label="Speaking threshold multiplier" aria-valuemin="1" aria-valuemax="5" aria-valuenow="2" class="w-full" value="2"/><p class="mt-1 text-[11px] text-muted-foreground" data-testid="voice-prefs-hint">기본값 — 대부분 환경에서 균형</p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="voice-prefs-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">기본값으로 리셋 (<!-- -->2.0<!-- -->×)</button></div></section><section data-testid="preset-card-grid" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2 flex items-start justify-between"><div><h3 class="text-sm font-semibold">⚡ Quick presets</h3><p class="text-xs text-muted-foreground">One-click bundles for common use cases — applies STT, LLM, TTS, voice id, and budget cap together. You can still fine-tune any slider after applying.</p></div></header><div class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3" data-testid="preset-card-list"><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-casual_chat"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">💬<!-- --> <!-- -->Casual chat</span></div><p class="text-[11px] text-muted-foreground">Day-to-day messaging · cheap STT / LLM · no read-back.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-meeting"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">📋<!-- --> <!-- -->Meeting notes</span></div><p class="text-[11px] text-muted-foreground">Balanced accuracy for transcripts · standard LLM summarization.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->5</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-medical_dictation"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🏥<!-- --> <!-- -->Medical / legal dictation</span></div><p class="text-[11px] text-muted-foreground">Loaded STT (timestamps + jargon adaptation) · Best LLM · ElevenLabs voice.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->loaded</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->best</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->best</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->20</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-live_caption"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🎬<!-- --> <!-- -->Live captioning</span></div><p class="text-[11px] text-muted-foreground">Low-latency STT · LLM disabled · no read-back.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->balanced</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span></div></button><button type="button" class="rounded-md border px-3 py-2 text-left transition-colors border-border/60 bg-background hover:bg-muted/40" data-testid="preset-card-sleep_mode"><div class="mb-1 flex items-center justify-between"><span class="text-sm font-semibold">🌙<!-- --> <!-- -->Sleep mode</span></div><p class="text-[11px] text-muted-foreground">Cost zero · local-only models · no API calls.</p><div class="mt-2 flex flex-wrap gap-1 text-[9px] text-muted-foreground"><span class="rounded bg-muted px-1 py-0.5 font-mono">stt:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">llm:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">tts:<!-- -->budget</span><span class="rounded bg-muted px-1 py-0.5 font-mono">cap:$<!-- -->0</span></div></button></div></section><section data-testid="voice-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🎚️ Voice transcription quality</h3><p class="text-xs text-muted-foreground">Pick how accurate vs. cheap the speech-to-text should be — elanous picks the model. Switching takes effect on the next voice call.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="voice-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="voice-model-tier-cost">0.003/min</span></div><input type="range" min="0" max="4" step="1" data-testid="voice-model-tier-slider" aria-label="Voice transcription tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="voice-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="voice-model-tier-rationale">Sensible default · streaming · $0.003/min</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="voice-model-tier-model-id">Model: <span class="font-mono">gpt-4o-mini-transcribe</span></p></div></div><div class="mt-3 flex items-center gap-2"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="voice-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="llm-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🧠 AI assistant quality</h3><p class="text-xs text-muted-foreground">Pick how careful vs. fast the model should think. elanous chooses the right model on your active provider · the slider stays the same across providers.</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="llm-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="llm-model-tier-provider">Anthropic</span></div><input type="range" min="0" max="4" step="1" data-testid="llm-model-tier-slider" aria-label="AI assistant tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="llm-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="llm-model-tier-rationale">Default · fast multi-turn</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="llm-model-tier-model-id">Model: <span class="font-mono">claude-haiku-4-5</span><span class="ml-1 text-muted-foreground">· reasoning: <span class="font-mono">off</span></span></p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="llm-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="tts-model-tier-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2"><h3 class="text-sm font-semibold">🔊 Voice playback quality</h3><p class="text-xs text-muted-foreground">Pick text-to-speech quality vs. cost. Voice identity (Rachel · SoYoung · custom) lives in a separate picker (Phase 2 M2-2b).</p></header><div class="space-y-3"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-center justify-between text-xs"><span class="font-medium">Balanced<span class="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground" data-testid="tts-model-tier-default-badge">Smart default</span></span><span class="rounded bg-muted px-2 py-0.5 font-mono text-[11px]" data-testid="tts-model-tier-rate">$15/M chars</span></div><input type="range" min="0" max="4" step="1" data-testid="tts-model-tier-slider" aria-label="Voice playback tier" aria-valuemin="0" aria-valuemax="4" aria-valuenow="1" aria-valuetext="Balanced" class="w-full" value="1"/><div class="mt-1 flex justify-between text-[10px] text-muted-foreground" data-testid="tts-model-tier-tick-labels"><span>Budget</span><span class="font-semibold text-foreground">Balanced</span><span>Better</span><span>Best</span><span>Loaded</span></div><p class="mt-2 text-[11px] text-muted-foreground" data-testid="tts-model-tier-rationale">Default · $15/M chars · multi-voice</p><p class="mt-1 text-[10px] text-muted-foreground/80" data-testid="tts-model-tier-model-id">Provider: <span class="font-mono">openai-tts</span><span class="ml-1">·</span><span class="ml-1">Model: <span class="font-mono">tts-1</span></span></p></div></div><div class="mt-3"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-model-tier-reset" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset to default (<!-- -->Balanced<!-- -->)</button></div></section><section data-testid="tts-voice-id-picker-card" class="rounded border border-border/60 bg-card/40 p-4 shadow-sm"><header class="mb-2 flex items-start justify-between"><div><h3 class="text-sm font-semibold">🗣️ Voice identity (per context)</h3><p class="text-xs text-muted-foreground">Pick a different voice per surface (chat / morning digest / alerts / Discord). Browse the ElevenLabs library or paste a voice id directly.</p></div></header><div class="space-y-2" data-testid="tts-voice-rows"><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-default-label">Default</span></div><p class="mb-1 text-[10px] text-muted-foreground">Fallback when a specific context isn't set</p><div class="flex gap-2"><input id="base-ui-_R_1pdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-default-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-default-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-default-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-chat-label">Chat reply</span></div><p class="mb-1 text-[10px] text-muted-foreground">Used by the PWA / TUI chat surface</p><div class="flex gap-2"><input id="base-ui-_R_1qdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-chat-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-chat-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-chat-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-digest-label">Morning digest</span></div><p class="mb-1 text-[10px] text-muted-foreground">Daily summary read-back (P2-D7)</p><div class="flex gap-2"><input id="base-ui-_R_1rdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-digest-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-digest-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-digest-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-alert-label">Push alerts</span></div><p class="mb-1 text-[10px] text-muted-foreground">Urgency-driven voice for push notifications</p><div class="flex gap-2"><input id="base-ui-_R_1sdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-alert-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-alert-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-alert-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div><div class="rounded-md border border-input bg-background px-3 py-2"><div class="mb-1 flex items-baseline justify-between gap-2 text-xs"><span class="font-medium" data-testid="tts-voice-row-discord-label">Discord bot</span></div><p class="mb-1 text-[10px] text-muted-foreground">X9 Discord voice channel + DM voice replies</p><div class="flex gap-2"><input id="base-ui-_R_1tdl5fivemtb_" data-slot="input" placeholder="Voice id (paste) or use Browse →" data-testid="tts-voice-row-discord-input" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 text-xs" value=""/><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-discord-browse" title="Library not loaded yet" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs">Browse</button><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-row-discord-clear" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Clear</button></div></div></div><div class="mt-3 flex items-center justify-between gap-2"><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" data-testid="tts-voice-reset-all" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-xs text-muted-foreground">Reset all</button><p class="text-[10px] text-muted-foreground/80">Paste voice id manually until daemon library is reachable</p></div></section><section class="space-y-4 rounded-md border border-border bg-card p-4" data-testid="embedding-vision-card"><header class="space-y-1"><h2 class="text-sm font-medium">Embedding · Vision tier</h2><p class="text-xs text-muted-foreground">Phase 3 scaffolding — model selection for RAG embedding + image vision. Resolvers wired; call-site integration follows as RAG / vision pipelines come online.</p></header><div class="space-y-1.5" data-testid="embedding-vision-row-embedding"><div class="flex items-center justify-between"><h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Embedding</h3><span class="text-[10px] text-zinc-400 dark:text-zinc-500">Smart default</span></div><p class="text-[11px] text-zinc-500 dark:text-zinc-400">RAG retrieval · similarity. Most users never touch this.</p><div class="flex flex-wrap gap-1"><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-budget" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Budget</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-balanced" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Balanced</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-better" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Better</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-best" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Best</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-embedding-loaded" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Loaded</button></div></div><div class="space-y-1.5" data-testid="embedding-vision-row-vision"><div class="flex items-center justify-between"><h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Vision</h3><span class="text-[10px] text-zinc-400 dark:text-zinc-500">Smart default</span></div><p class="text-[11px] text-zinc-500 dark:text-zinc-400">OCR · screenshot analysis · note-from-image.</p><div class="flex flex-wrap gap-1"><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-budget" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Budget</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-balanced" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Balanced</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-better" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Better</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-best" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Best</button><button type="button" tabindex="0" data-slot="button" data-testid="embedding-vision-vision-loaded" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5 text-[11px]">Loaded</button></div></div></section><section class="space-y-3"><h2 class="text-sm font-medium">데몬 연결</h2><label class="block space-y-1"><span class="text-xs text-muted-foreground">Base URL</span><input id="base-ui-_R_29p5fivemtb_" data-slot="input" placeholder="http://localhost:31415" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40" value=""/></label><label class="block space-y-1"><span class="text-xs text-muted-foreground">연결 토큰</span><input id="bearer-token" type="password" data-slot="input" placeholder="다른 기기에서 만든 연결 토큰을 붙여 넣으세요" class="h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40" value=""/></label><label class="block space-y-1"><span class="text-xs text-muted-foreground">Default provider</span><select class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs focus:outline-none focus:ring-2 focus:ring-ring"><option value="" selected="">(none — server default)</option><option value="claude">claude</option><option value="gemini">gemini</option><option value="grok">grok</option><option value="codex">codex</option></select></label></section><section class="space-y-3"><div class="flex items-center justify-between"><h2 class="text-sm font-medium">Daemon health</h2><button type="button" data-disabled="" tabindex="0" disabled="" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">Recheck</button></div><div class="rounded-md border border-border bg-card p-3 text-xs"><p class="text-muted-foreground">Set Base URL above to probe.</p></div></section><div id="tools" class="scroll-mt-8" aria-hidden="true"></div><div id="ios" class="scroll-mt-8" aria-hidden="true"></div><section class="space-y-3"><h2 class="text-sm font-medium">대화</h2><div class="rounded-md border border-border bg-card px-3 py-2 font-mono text-xs">(no session yet)</div><p class="text-xs text-muted-foreground">A new session id is allocated on first load. Use Chat’s<code class="mx-1 rounded bg-muted px-1.5 py-0.5">:fork</code>meta-command to start fresh once U-3 ships.</p></section><section class="space-y-3"><h2 class="text-sm font-medium">Theme</h2><div class="flex flex-wrap gap-2"><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border border-transparent bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">catppuccin-mocha</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">mocha-pastel-accent</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">catppuccin-latte</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">rose-pine-dawn</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">nord-light</button><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center border bg-clip-padding font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5">elanous-pastel-default</button></div></section><section data-testid="advanced-setup-map" class="space-y-2"><h2 class="text-sm font-medium">Advanced setup map</h2><div class="rounded-md border border-border bg-card p-3 text-xs"><p class="mb-2 text-muted-foreground">NEXUS native 셋업 영역은 PWA 에서 직접 · 그 외 advanced 셋업은 desktop wizard 또는 NEXUS subcommand 에서.</p><table class="w-full text-left text-[11px]"><thead><tr class="border-b border-border text-muted-foreground"><th class="py-1 pr-2 font-medium">영역</th><th class="py-1 pr-2 font-medium">상태</th><th class="py-1 font-medium">셋업 위치</th></tr></thead><tbody><tr data-testid="advanced-setup-row-Chat 백엔드" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Chat 백엔드</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Quick Setup card</td></tr><tr data-testid="advanced-setup-row-Telegram bot token" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Telegram bot token</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Secret modal</td></tr><tr data-testid="advanced-setup-row-Discord bot token" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Discord bot token</td><td class="py-1.5 pr-2 font-mono text-[10px]">✓ NEXUS native</td><td class="py-1.5 text-muted-foreground">PWA Secret modal</td></tr><tr data-testid="advanced-setup-row-Telegram allowlist" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Telegram allowlist</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ Wizard 전용</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous legacy → /setup</code></td></tr><tr data-testid="advanced-setup-row-Discord guild · voice" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">Discord guild · voice</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ Wizard 전용</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous legacy → /setup</code></td></tr><tr data-testid="advanced-setup-row-OS 자동 부팅" class="border-b border-border/50 last:border-0"><td class="py-1.5 pr-2 font-medium">OS 자동 부팅</td><td class="py-1.5 pr-2 font-mono text-[10px]">◯ NEXUS subcommand</td><td class="py-1.5 text-muted-foreground">desktop<!-- --> · <code class="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">elanous nexus install --launchd</code></td></tr></tbody></table></div></section><section class="space-y-3 rounded-2xl border border-border bg-card p-4" aria-label="메뉴"><h2 class="text-base font-semibold">메뉴</h2><p class="text-xs text-muted-foreground">메뉴에는 주요 탭만 보입니다. Labs(베타)와 숨긴 탭은 이 기기에서만 켤 수 있고, 숨긴 탭도 주소로는 열립니다.</p><label class="flex items-start gap-2 text-sm"><input type="checkbox" data-elanous-action="menu-show-labs"/><span>Labs 탭 보기 <span class="text-xs text-muted-foreground">(<!-- -->편집기 · 여러 탭 · 보드 · Showroom<!-- -->)</span></span></label><label class="flex items-start gap-2 text-sm"><input type="checkbox" data-elanous-action="menu-show-hidden"/><span>숨긴 탭 보기 <span class="text-xs text-muted-foreground">(<!-- -->봇 · 관측 · 작업 트리 · 제어 · Tasks · 대화 카드 · Reflection<!-- -->)</span></span></label></section><section class="space-y-3 rounded-2xl border border-border bg-card p-4"><div><h2 class="text-base font-semibold">빌드 정보</h2><p class="text-xs text-muted-foreground">배포 최신 여부 판별 — 새로고침 후 시각/SHA 가 안 바뀌면 옛 캐시.</p></div><div class="grid gap-3 sm:grid-cols-2"><div class="rounded-xl bg-muted/40 p-3"><div class="text-[11px] uppercase tracking-wide text-muted-foreground">PWA 프론트 빌드</div><div class="mt-1 font-mono text-sm">26. 10. 04. 10:05<!-- --> · 27045f4</div></div><div class="rounded-xl bg-muted/40 p-3"><div class="text-[11px] uppercase tracking-wide text-muted-foreground">데몬(백엔드) 시작</div><div class="mt-1 font-mono text-sm ">…</div></div></div></section><button type="button" tabindex="0" data-slot="button" class="group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 bg-primary text-primary-foreground [a]:hover:bg-primary/80 h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2">Saved</button></div><!--$--><!--/$--></main></div><!--$!--><template data-dgst="BAILOUT_TO_CLIENT_SIDE_RENDERING"></template><!--/$--></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/app/_next/static/chunks/webpack-9e4d02d567b98240.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n"])</script><script>self.__next_f.push([1,"2:I[27365,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"ServiceWorkerRegister\"]\n"])</script><script>self.__next_f.push([1,"3:I[50179,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"NewBuildBanner\"]\n"])</script><script>self.__next_f.push([1,"4:I[36581,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"DaemonProvider\"]\n"])</script><script>self.__next_f.push([1,"5:I[78401,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"OperatorRoleDefault\"]\n"])</script><script>self.__next_f.push([1,"6:I[24969,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"NexusClientProvider\"]\n"])</script><script>self.__next_f.push([1,"7:I[70090,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"ThemeProvider\"]\n"])</script><script>self.__next_f.push([1,"8:I[50977,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"TooltipProvider\"]\n"])</script><script>self.__next_f.push([1,"9:I[34485,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"ToastProvider\"]\n"])</script><script>self.__next_f.push([1,"a:I[37370,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"AppShell\"]\n"])</script><script>self.__next_f.push([1,"b:I[14381,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"8025\",\"static/chunks/8025-cc24ee5d8f2fb6f8.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"5845\",\"static/chunks/5845-e6c003ce8d5fd36a.js\",\"8421\",\"static/chunks/8421-1c4acfb1395a0edf.js\",\"4685\",\"static/chunks/4685-c3c1c625b71accd1.js\",\"7177\",\"static/chunks/app/layout-e71c84189e8c683e.js\"],\"MaturityBanner\"]\n"])</script><script>self.__next_f.push([1,"c:I[56429,[],\"\"]\nd:I[59193,[],\"\"]\ne:I[33568,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"6048\",\"static/chunks/6048-4c5c33579bc4ef78.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"3638\",\"static/chunks/3638-aa80b4641ea439db.js\",\"4345\",\"static/chunks/app/not-found-490653e8d4cc8852.js\"],\"default\"]\nf:I[76132,[],\"ClientPageRoot\"]\n"])</script><script>self.__next_f.push([1,"10:I[43591,[\"7777\",\"static/chunks/7777-79f845045aa1ed86.js\",\"9538\",\"static/chunks/9538-2816b90923606459.js\",\"3278\",\"static/chunks/3278-ae6ef084769f6195.js\",\"1829\",\"static/chunks/1829-b453a1b22d3999bb.js\",\"9656\",\"static/chunks/9656-c1540088f5859c80.js\",\"7551\",\"static/chunks/7551-a0e0707b79164ddd.js\",\"3454\",\"static/chunks/3454-988a53dac60a1763.js\",\"9906\",\"static/chunks/9906-482c6619b3fdda20.js\",\"3869\",\"static/chunks/3869-3cd46526879f454c.js\",\"4215\",\"static/chunks/4215-c9d91dd644ec1719.js\",\"2176\",\"static/chunks/2176-c379e3ebce874151.js\",\"7274\",\"static/chunks/7274-19b7279f18b47ab3.js\",\"7758\",\"static/chunks/7758-0b018a9e4fc56200.js\",\"4662\",\"static/chunks/app/settings/page-db14d0be7f1c460c.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"13:I[38032,[],\"OutletBoundary\"]\n15:I[55369,[],\"AsyncMetadataOutlet\"]\n17:I[38032,[],\"ViewportBoundary\"]\n19:I[38032,[],\"MetadataBoundary\"]\n1a:\"$Sreact.suspense\"\n1c:I[9551,[],\"\"]\n:HL[\"/app/_next/static/media/22a5144ee8d83bca-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/app/_next/static/css/128fb7fb670b2fbf.css\",\"style\"]\n:HL[\"/app/_next/static/css/04dabcbcc4bfa6db.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"-6XrAoD3eU7NyMHAE4xPS\",\"p\":\"/app\",\"c\":[\"\",\"settings\",\"\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"settings\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/app/_next/static/css/128fb7fb670b2fbf.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/app/_next/static/css/04dabcbcc4bfa6db.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"ko\",\"className\":\"font-sans __variable_45c93f\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"link\",null,{\"rel\":\"preload\",\"as\":\"font\",\"type\":\"font/ttf\",\"href\":\"/app/fonts/JetBrainsMonoNerdFontMono-Regular.ttf\",\"crossOrigin\":\"anonymous\"}]}],[\"$\",\"body\",null,{\"className\":\"min-h-screen bg-background text-foreground antialiased\",\"children\":[[\"$\",\"$L2\",null,{}],[\"$\",\"$L3\",null,{}],[\"$\",\"$L4\",null,{\"children\":[[\"$\",\"$L5\",null,{}],[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$L8\",null,{\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$La\",null,{\"children\":[[\"$\",\"$Lb\",null,{}],[\"$\",\"$Lc\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Ld\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"$Le\",null,{}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]}]}]}]}]]}]]}]]}]]}],{\"children\":[\"settings\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$Lc\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Ld\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"$Lf\",null,{\"Component\":\"$10\",\"searchParams\":{},\"params\":{},\"promises\":[\"$@11\",\"$@12\"]}],null,[\"$\",\"$L13\",null,{\"children\":[\"$L14\",[\"$\",\"$L15\",null,{\"promise\":\"$@16\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$L17\",null,{\"children\":\"$L18\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$L19\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$1a\",null,{\"fallback\":null,\"children\":\"$L1b\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$1c\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"11:{}\n12:\"$0:f:0:1:2:children:2:children:1:props:children:0:props:params\"\n"])</script><script>self.__next_f.push([1,"18:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#1e1e2e\"}]]\n14:null\n"])</script><script>self.__next_f.push([1,"1d:I[35241,[],\"IconMark\"]\n"])</script><script>self.__next_f.push([1,"16:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"elanous\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"elanous — voice · chat · intake · control · terminal.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"application-name\",\"content\":\"elanous\"}],[\"$\",\"link\",\"3\",{\"rel\":\"manifest\",\"href\":\"/app/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/app/icons/elanous-32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/app/icons/elanous-16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"6\",{\"rel\":\"apple-touch-icon\",\"href\":\"/app/icons/elanous-180.png\",\"sizes\":\"180x180\",\"type\":\"image/png\"}],[\"$\",\"$L1d\",\"7\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"1b:\"$16:metadata\"\n"])</script></body></html>
|