claude-tempo 0.28.0-beta.8 → 0.28.0
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/CLAUDE.md +45 -4
- package/README.md +2 -2
- package/dashboard/dist/assets/index-BaGGZoKH.css +2 -0
- package/dashboard/dist/assets/index-SJrm2xz5.js +62 -0
- package/dashboard/dist/assets/index-SJrm2xz5.js.map +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dashboard/package.json +6 -4
- package/dist/activities/maestro.js +18 -5
- package/dist/activities/outbox.d.ts +38 -0
- package/dist/activities/outbox.js +180 -9
- package/dist/activities/resolve.d.ts +18 -1
- package/dist/activities/resolve.js +87 -44
- package/dist/activities/schedule-fire.d.ts +10 -0
- package/dist/activities/schedule-fire.js +49 -22
- package/dist/adapters/base.js +14 -0
- package/dist/adapters/claude-api/adapter.d.ts +168 -0
- package/dist/adapters/claude-api/adapter.js +797 -0
- package/dist/adapters/claude-api/api-error.d.ts +96 -0
- package/dist/adapters/claude-api/api-error.js +191 -0
- package/dist/adapters/claude-api/index.d.ts +16 -0
- package/dist/adapters/claude-api/index.js +21 -0
- package/dist/adapters/claude-api/mcp-bridge.d.ts +50 -0
- package/dist/adapters/claude-api/mcp-bridge.js +157 -0
- package/dist/adapters/claude-code-headless/adapter.d.ts +131 -0
- package/dist/adapters/claude-code-headless/adapter.js +710 -0
- package/dist/adapters/claude-code-headless/error-mapper.d.ts +107 -0
- package/dist/adapters/claude-code-headless/error-mapper.js +281 -0
- package/dist/adapters/claude-code-headless/index.d.ts +17 -0
- package/dist/adapters/claude-code-headless/index.js +26 -0
- package/dist/adapters/claude-code-headless/pre-flight.d.ts +51 -0
- package/dist/adapters/claude-code-headless/pre-flight.js +207 -0
- package/dist/adapters/claude-code-headless/prompt.d.ts +93 -0
- package/dist/adapters/claude-code-headless/prompt.js +79 -0
- package/dist/adapters/claude-code-headless/stream-json.d.ts +242 -0
- package/dist/adapters/claude-code-headless/stream-json.js +208 -0
- package/dist/adapters/claude-code-headless/types.d.ts +28 -0
- package/dist/adapters/claude-code-headless/types.js +36 -0
- package/dist/adapters/copilot/adapter.js +12 -13
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.js +48 -1
- package/dist/adapters/opencode/adapter.d.ts +82 -0
- package/dist/adapters/opencode/adapter.js +710 -0
- package/dist/adapters/opencode/config.d.ts +90 -0
- package/dist/adapters/opencode/config.js +137 -0
- package/dist/adapters/opencode/helpers.d.ts +40 -0
- package/dist/adapters/opencode/helpers.js +144 -0
- package/dist/adapters/opencode/index.d.ts +12 -0
- package/dist/adapters/opencode/index.js +17 -0
- package/dist/adapters/opencode/server-bridge.d.ts +124 -0
- package/dist/adapters/opencode/server-bridge.js +216 -0
- package/dist/adapters/sdk/system-prompt.d.ts +64 -0
- package/dist/adapters/sdk/system-prompt.js +78 -0
- package/dist/cli/commands.d.ts +114 -3
- package/dist/cli/commands.js +259 -25
- package/dist/cli/dev-banner.d.ts +38 -1
- package/dist/cli/dev-banner.js +89 -7
- package/dist/cli/dev-verbs.d.ts +43 -0
- package/dist/cli/dev-verbs.js +254 -0
- package/dist/cli/help-text.js +11 -3
- package/dist/cli/removed-verbs.js +12 -9
- package/dist/cli.js +51 -6
- package/dist/client/core.d.ts +9 -0
- package/dist/client/core.js +247 -62
- package/dist/client/interface.d.ts +48 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.js +83 -13
- package/dist/daemon-adapter-versions.d.ts +24 -0
- package/dist/daemon-adapter-versions.js +36 -5
- package/dist/daemon.d.ts +43 -1
- package/dist/daemon.js +100 -6
- package/dist/ensemble/schema.d.ts +12 -0
- package/dist/http/aggregate.d.ts +160 -2
- package/dist/http/aggregate.js +240 -22
- package/dist/http/body.d.ts +14 -5
- package/dist/http/body.js +26 -6
- package/dist/http/event-types.d.ts +18 -1
- package/dist/http/server.d.ts +7 -0
- package/dist/http/server.js +2 -0
- package/dist/http/snapshot.d.ts +12 -7
- package/dist/http/snapshot.js +37 -9
- package/dist/palette/index.d.ts +138 -0
- package/dist/palette/index.js +221 -0
- package/dist/reconcile/orphans.d.ts +56 -2
- package/dist/reconcile/orphans.js +94 -23
- package/dist/scripts/check-components-css-sync.js +199 -0
- package/dist/server-tools.d.ts +87 -0
- package/dist/server-tools.js +134 -0
- package/dist/server.js +32 -100
- package/dist/spawn.d.ts +162 -0
- package/dist/spawn.js +210 -0
- package/dist/tools/clear-state.d.ts +3 -0
- package/dist/tools/clear-state.js +37 -0
- package/dist/tools/cue.d.ts +40 -0
- package/dist/tools/cue.js +165 -1
- package/dist/tools/ensemble.d.ts +28 -0
- package/dist/tools/ensemble.js +123 -39
- package/dist/tools/fetch-state.d.ts +13 -0
- package/dist/tools/fetch-state.js +78 -0
- package/dist/tools/recruit.js +129 -2
- package/dist/tools/restart.d.ts +4 -0
- package/dist/tools/restart.js +9 -1
- package/dist/tools/save-state.d.ts +3 -0
- package/dist/tools/save-state.js +57 -0
- package/dist/tools/worktree.js +1 -1
- package/dist/tui/commands.d.ts +9 -104
- package/dist/tui/commands.js +117 -165
- package/dist/tui/index.js +14 -7
- package/dist/types.d.ts +128 -2
- package/dist/types.js +19 -1
- package/dist/utils/default-part.d.ts +43 -0
- package/dist/utils/default-part.js +104 -0
- package/dist/utils/duration.d.ts +15 -0
- package/dist/utils/duration.js +30 -0
- package/dist/utils/query-timeout.d.ts +103 -0
- package/dist/utils/query-timeout.js +113 -0
- package/dist/utils/restore-format.d.ts +49 -0
- package/dist/utils/restore-format.js +91 -0
- package/dist/utils/sdk-probe.d.ts +9 -0
- package/dist/utils/sdk-probe.js +45 -0
- package/dist/utils/validation.d.ts +10 -0
- package/dist/utils/validation.js +20 -1
- package/dist/utils/visibility-deadline.d.ts +186 -0
- package/dist/utils/visibility-deadline.js +158 -0
- package/dist/workflows/session.js +79 -1
- package/dist/workflows/signals.d.ts +50 -2
- package/dist/workflows/signals.js +45 -1
- package/examples/ensembles/tempo-headless-jam.yaml +77 -0
- package/examples/ensembles/tempo-mock-jam.yaml +12 -5
- package/package.json +20 -3
- package/workflow-bundle.js +287 -4
- package/dashboard/dist/assets/index-Cyx6Elit.js +0 -18
- package/dashboard/dist/assets/index-Cyx6Elit.js.map +0 -1
- package/dashboard/dist/assets/index-DfAhEKBz.css +0 -2
package/CLAUDE.md
CHANGED
|
@@ -25,21 +25,27 @@ src/
|
|
|
25
25
|
│ ├── daemon.ts # Daemon management utilities (start, stop, status, heartbeat, isDaemonRunning)
|
|
26
26
|
│ ├── daemon-command.ts # daemon subcommand handler — crash-proof, no Temporal deps
|
|
27
27
|
│ ├── dashboard-command.ts # dashboard subcommand — crash-proof; opens the web dashboard, optionally minting a QR-code pairing token (#340)
|
|
28
|
+
│ ├── dev-banner.ts # [DEV MODE] banner formatter (ADR 0014 §5.4) — gate 4 production-safety line
|
|
29
|
+
│ ├── dev-mode-bootstrap.ts # pre-import side-effect: promotes top-level `--dev` flag to `CLAUDE_TEMPO_DEV_MODE=1` before any other module loads
|
|
28
30
|
│ ├── help-text.ts # help output — crash-proof, no Temporal deps
|
|
29
31
|
│ ├── mcp.ts # MCP server registration helpers (init, global vs project)
|
|
30
32
|
│ ├── output.ts # Shared CLI output formatting helpers
|
|
31
33
|
│ ├── preflight.ts # Environment preflight checks
|
|
32
34
|
│ ├── removed-verbs.ts # lookup table for the 10 CLI verbs removed in #288 — dispatches migration hints before loading Temporal surface
|
|
35
|
+
│ ├── scenarios-command.ts # scenarios subcommand (dev mode only) — list/show shipped YAML scenario library (ADR 0014 §4.8)
|
|
33
36
|
│ ├── startup.ts # auto-provisioning bootstrap state machine (#289) — six-step idempotent sequence used by bare `claude-tempo` invocation
|
|
34
37
|
│ └── upgrade-command.ts # upgrade subcommand — crash-proof; dynamic-imports Temporal only for active-session warning
|
|
35
38
|
├── adapters/
|
|
36
39
|
│ ├── README.md # Adapter contract documentation
|
|
37
40
|
│ ├── index.ts # Adapter registry bootstrap + barrel exports (mock registered iff isDevMode())
|
|
38
41
|
│ ├── base.ts # BaseAttachment + SdkAttachment base classes (lifecycle skeleton)
|
|
42
|
+
│ ├── terminal-error.ts # Shared terminal-class error classifier for signal/query failures (#249)
|
|
39
43
|
│ ├── claude-code/ # InteractiveAttachment — Claude Code CLI adapter
|
|
40
44
|
│ ├── copilot/ # CopilotSdkAttachment — Copilot bridge adapter
|
|
45
|
+
│ ├── claude-api/ # ClaudeApiAttachment — headless adapter via Anthropic Messages API (#131)
|
|
46
|
+
│ ├── opencode/ # OpenCodeAttachment — headless multi-provider adapter via SST OpenCode subprocess (#449)
|
|
41
47
|
│ ├── mock/ # MockAttachment — dev-mode-only SDK adapter (ADR 0014 PR-2). prepack strips dist/adapters/mock from npm tarball.
|
|
42
|
-
│ └── sdk/ # SDK-style adapter base (used by Copilot bridge)
|
|
48
|
+
│ └── sdk/ # SDK-style adapter base (used by Copilot bridge and opencode)
|
|
43
49
|
├── client/
|
|
44
50
|
│ ├── interface.ts # TempoClient TypeScript interface and related types
|
|
45
51
|
│ └── index.ts # TempoClient factory implementation and barrel re-exports
|
|
@@ -83,7 +89,8 @@ src/
|
|
|
83
89
|
│ ├── load-lineup.ts / save-lineup.ts / agent-types.ts / resolve.ts
|
|
84
90
|
│ ├── set-name.ts / set-part.ts / who-am-i.ts / release.ts
|
|
85
91
|
│ ├── pause.ts / play.ts / shutdown.ts / restore.ts
|
|
86
|
-
│ ├── hosts.ts
|
|
92
|
+
│ ├── hosts.ts / set-ensemble-description.ts
|
|
93
|
+
│ ├── save-state.ts / fetch-state.ts / clear-state.ts
|
|
87
94
|
│ └── helpers.ts # Zod/MCP tool registration wrapper
|
|
88
95
|
├── tui/
|
|
89
96
|
│ ├── App.tsx / store.ts / commands.ts # TUI root, state, slash commands
|
|
@@ -94,6 +101,7 @@ src/
|
|
|
94
101
|
│ ├── validation.ts / worktree.ts / safe-path.ts / duration.ts / search-attributes.ts
|
|
95
102
|
│ ├── attachment-format.ts / recall-format.ts # Shared display formatters (attachment-info, recall)
|
|
96
103
|
│ ├── hosts.ts / format-hosts.ts # Host enumeration + shared hosts display formatter (#274)
|
|
104
|
+
│ └── sdk-probe.ts # Filesystem-walk probe for installed optional npm deps (used by opencode adapter + recruit preflight, #449)
|
|
97
105
|
├── types.ts # Shared type definitions
|
|
98
106
|
├── git-info.ts # Git repository detection helper
|
|
99
107
|
└── config.ts # Env var handling
|
|
@@ -106,8 +114,9 @@ touching `src/tui/`.
|
|
|
106
114
|
|
|
107
115
|
```bash
|
|
108
116
|
npm install
|
|
109
|
-
npm run build
|
|
117
|
+
npm run build # compiles TS, scripts/*.ts → dist/scripts/, and pre-bundles workflow code into workflow-bundle.js
|
|
110
118
|
npm test
|
|
119
|
+
npm run check:all # runs every CI gate locally (build, tests, drift checks, lints, dashboard, size-limit, tarball). Run before pushing to catch CI failures up front.
|
|
111
120
|
```
|
|
112
121
|
|
|
113
122
|
> **Always run `npm run build` after changing workflow code (`src/workflows/`).** The build
|
|
@@ -126,6 +135,16 @@ npm test
|
|
|
126
135
|
> production code"; the hook's doc-comment should restate that explicitly. Hooks
|
|
127
136
|
> are never surfaced through barrels or `TempoClient`.
|
|
128
137
|
|
|
138
|
+
> **Project standard is npm** (declared via `package.json#packageManager`,
|
|
139
|
+
> enforced in CI by `lint:lockfile-canonical`). If `npm` is blocked locally
|
|
140
|
+
> (e.g. corp networks), `pnpm` works as a personal workaround — `pnpm-lock.yaml`
|
|
141
|
+
> is gitignored, so it can exist on disk but must NOT be committed. The
|
|
142
|
+
> `lint:lockfile-canonical` step inside `check:all` fails if any non-npm
|
|
143
|
+
> lockfile (`pnpm-lock.yaml`, `yarn.lock`, or their `dashboard/` counterparts)
|
|
144
|
+
> appears in `git ls-files`. The `dashboard/` subworkspace also uses npm and
|
|
145
|
+
> ships its own `package-lock.json` — see `.github/workflows/ci.yml` for why
|
|
146
|
+
> the install is intentionally independent.
|
|
147
|
+
|
|
129
148
|
See [docs/development.md](docs/development.md) for full setup (Temporal dev server command,
|
|
130
149
|
daemon worker notes, `npx ts-node` dev runner).
|
|
131
150
|
|
|
@@ -145,7 +164,13 @@ daemon worker notes, `npx ts-node` dev runner).
|
|
|
145
164
|
- **Wire protocol**: All signal/query/update names are documented in [`docs/WIRE-PROTOCOL.md`](docs/WIRE-PROTOCOL.md) and are stable — renaming or removing any is a breaking change. **Process**: update `docs/WIRE-PROTOCOL.md` in the same commit as any new signal, query, or update.
|
|
146
165
|
- **Daemon**: Standalone background process (`src/daemon.ts`) that runs all Temporal workers and the HTTP/SSE event source (`src/http/`). Auto-started by any `claude-tempo` command. PID at `~/.claude-tempo/daemon.pid`; logs at `~/.claude-tempo/daemon.log`. Exposes local HTTP endpoints (`/v1/health`, `/v1/ensembles`, `/v1/state/:ensemble`, `/v1/events/:ensemble` SSE stream, etc.) consumed by the TUI and `TempoClient.subscribe()`. See [docs/SSE-PROTOCOL.md](docs/SSE-PROTOCOL.md).
|
|
147
166
|
- **Player types**: Reusable agent definitions in Claude Code's subagent format (`.md` files with YAML frontmatter). Three-tier lookup: project `.claude/agents/` → user `~/.claude/agents/` → shipped `examples/agents/`. Discover via `agent_types` tool or `claude-tempo agent-types` CLI. Shipped types: tempo-conductor, tempo-composer, tempo-soloist, tempo-tuner, tempo-critic, tempo-roadie, tempo-improv, tempo-liner.
|
|
148
|
-
- **
|
|
167
|
+
- **Dev mode** (`--dev` flag or `CLAUDE_TEMPO_DEV_MODE=1`): Isolated testing profile — flips home dir to `~/.claude-tempo-dev/`, HTTP port to 8474, Temporal namespace to `claude-tempo-dev`, task queue to `claude-tempo-dev`. Required to use the mock adapter. Post-#423 isolation guarantees: (1) `TEMPORAL_NAMESPACE` / `TEMPORAL_ADDRESS` shell env vars are ignored in dev mode — the dev namespace is not overridable by shell config, only CLI flags and `~/.claude-tempo-dev/config.json`. (2) `--dev down` will not kill the Temporal server if the prod profile is alive; use `--kill-shared-temporal` to override. Canonical entry point (no global install required): `node dist/cli.js --dev <verb>`. Quick E2E: `node dist/cli.js --dev daemon start && node dist/cli.js --dev up --lineup tempo-mock-jam`. See [docs/dev-mode.md](docs/dev-mode.md) for the full reference.
|
|
168
|
+
- **Claude API adapter** (`agent: 'claude-api'`, #131): Headless adapter that drives sessions via the Anthropic Messages API (`@anthropic-ai/sdk`) — no terminal, no Claude Code CLI. Requires `ANTHROPIC_API_KEY` env var and the `@anthropic-ai/sdk` optional dependency. Default model `claude-opus-4-7` (overridable via `model` recruit arg or `CLAUDE_TEMPO_API_MODEL` env). Claude-API players have access to claude-tempo MCP tools (cue, report, recall, ensemble, …) but not file-edit/shell/web tools. See `src/adapters/claude-api/`.
|
|
169
|
+
- **OpenCode adapter** (`agent: 'opencode'`, #449): Headless multi-provider adapter that drives sessions via [SST OpenCode](https://opencode.ai) as a managed subprocess — supports Anthropic, OpenAI, Bedrock, Vertex, Ollama, and ~70 other providers via OpenCode's `provider/model` selector. Requires OpenCode CLI (`npm install -g opencode-ai`) and the `@opencode-ai/sdk` optional dependency. Recruit with `model: 'provider/name'` (e.g. `'anthropic/claude-opus-4-7'`). Tool bridging is MCP-native — OpenCode spawns `dist/server.js` as its own stdio MCP child. Session state is persisted server-side by OpenCode; the adapter stashes the session id on workflow metadata for reconnect across `opencode serve` restarts. See `src/adapters/opencode/`.
|
|
170
|
+
- **Claude Code headless adapter** (`agent: 'claude-code-headless'`, #520): Headless adapter that drives sessions via the official `claude` CLI as a per-turn `claude -p --output-format stream-json` subprocess. The whole point: turns bill against the host's existing Claude Code subscription extra-usage credits (Pro / Max plans) rather than a Console workspace API key — the only ToS-clean way for a third-party tool to tap that pool. Requires the `claude` binary on PATH AND a logged-in Claude Code session (`claude auth login`); recruit pre-flight rejects with an actionable error otherwise. Tool surface is the union of full Claude Code built-ins (Bash / Read / Write / Edit / Glob / Grep / WebSearch / WebFetch) and the claude-tempo MCP surface — registered via inline `--mcp-config` so `claude` spawns `dist/server.js` as its own MCP child (no in-process bridge). Recruit knobs: `permissionMode` (default `'acceptEdits'`) or `dangerouslySkipPermissions: true` (mutually exclusive). Sessions resume across restart via the existing `sessionId` metadata field — the same UUID is shared with the interactive `claude-code` adapter (per-cwd JSONL is per-cwd, not per-adapter). See `src/adapters/claude-code-headless/` and `examples/ensembles/tempo-headless-jam.yaml`.
|
|
171
|
+
- **Mock adapter** (`agent: 'mock'`, dev mode only): Four modes: `echo` (echoes input), `scripted` (replays YAML scenario rules), `silent` (drains messages without replying — heartbeat-stale validation), `chaos` (probabilistic fail/crash injection via seeded PRNG). Only registered when `isDevMode()` is true; stripped from the npm tarball by `prepack`. See `src/adapters/mock/`.
|
|
172
|
+
- **Saveable state** (#334, ADR 0011): Per-player curated state slots — the player itself decides what context survives a restart. Three MCP tools: `save_state` (owner-only write, max 4 slots × 32 KiB), `fetch_state` (read self or peer; audit identity recorded on each entry's `savedBy`), `clear_state` (owner-only). `restart` accepts `loadFromState: true | 'someKey'` to seed the new session from a saved-state slot instead of (or, with `transcript: 'replay'`, alongside) transcript replay. Saved-state delivery uses `from: 'self-restart'` as a stable system identity. Empty-slot fallback: graceful — falls through to transcript replay with a log line. See [docs/design/334-player-saveable-state.md](docs/design/334-player-saveable-state.md).
|
|
173
|
+
- **Lineup examples**: Six pre-built ensemble YAML files in `examples/ensembles/` — `tempo-big-band`, `tempo-dev-team`, `tempo-review-squad`, `tempo-jam-session`, `tempo-mock-jam` (dev-mode all-mock ensemble), `tempo-headless-jam` (#520 — all-`claude-code-headless` subscription-billed ensemble). Load with `claude-tempo up --lineup <name>` or the `load_lineup` tool.
|
|
149
174
|
- **GitHub App identity** (`claude-tempo[bot]`): When a player writes to GitHub — issue comments, PR creation/merge, commits, labels, check runs — **use `./scripts/ensemble-gh`** instead of `gh`. The wrapper mints a short-lived installation token so the action is attributed to `claude-tempo[bot]`, not to the human maintainer, making the AI authorship visible. Plain `gh` is still correct for read-only local dev (`gh pr view`, `gh repo clone`, `gh auth status`). Every bot-authored comment/PR body must include the AI attribution footer documented in [docs/github-app.md](docs/github-app.md).
|
|
150
175
|
|
|
151
176
|
See [docs/concepts.md](docs/concepts.md) for the full glossary (Adapter, Attachment phases, Restart, Detach/Destroy, Migrate, Broadcast, Recall, Schedule, Lineup, Quality Gate, Worktree, Stage, Hold/Release, Pause/Resume, Maestro, TempoClient, and more).
|
|
@@ -159,6 +184,22 @@ Examples:
|
|
|
159
184
|
- `fix(workflow): handle signal delivery edge case`
|
|
160
185
|
- `docs: update getting started guide`
|
|
161
186
|
|
|
187
|
+
## PR Body Conventions
|
|
188
|
+
|
|
189
|
+
GitHub's auto-close keywords (`Closes`, `Fixes`, `Resolves`) ignore any trailing qualifier text. They cannot express "this PR closes part of an issue" — they always close the full issue.
|
|
190
|
+
|
|
191
|
+
For multi-PR efforts tracked under a single issue, use these conventions in PR bodies:
|
|
192
|
+
|
|
193
|
+
| Form | When to use |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `Refs #N` | Any intermediate PR of a multi-PR effort. No auto-close. |
|
|
196
|
+
| `Implements PR-K of #N` | Same as above, more explicit. No keyword match → no auto-close. |
|
|
197
|
+
| `Closes #N` | Final PR of the effort (or single-PR efforts). Triggers auto-close on merge. |
|
|
198
|
+
|
|
199
|
+
**Avoid `Closes #N PR-K`** — GitHub ignores the `PR-K` qualifier and auto-closes #N prematurely. If you find yourself wanting to express "closes part of," use `Refs #N` and add a manual close on the final PR.
|
|
200
|
+
|
|
201
|
+
When sequencing multi-PR work, name the issue's open question explicitly in the first PR's body (e.g., "PR-1 of 2: foundation; PR-2 follows for the user-visible payoff") so reviewers know more is coming.
|
|
202
|
+
|
|
162
203
|
## Release Process
|
|
163
204
|
|
|
164
205
|
> **Release rule**: Bump `package.json` + CHANGELOG before tagging. Never tag a commit that
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Each session registers as a **player** in Temporal. Players discover each other
|
|
|
37
37
|
| 🖥️ **Terminal UI** | Chat-focused TUI with slash commands, overlays, and interactive wizards |
|
|
38
38
|
| 🌐 **Cross-machine** | Any session that can reach your Temporal server can join the ensemble |
|
|
39
39
|
| ⏸️ **Hold / Pause / Resume** | Pre-warm a full team before delivering tasks; pause and resume mid-session |
|
|
40
|
-
| 🤖 **
|
|
40
|
+
| 🤖 **Headless adapters** | Copilot bridge, Claude API, OpenCode, and Claude Code headless (`claude -p` subprocess — bills against your Claude Code subscription, no Console API key needed) — mix providers and headless agents in the same ensemble |
|
|
41
41
|
|
|
42
42
|
## Installation
|
|
43
43
|
|
|
@@ -202,7 +202,7 @@ players:
|
|
|
202
202
|
type: tempo-soloist
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
-
Eight types ship out of the box: `tempo-conductor`, `tempo-composer`, `tempo-soloist`, `tempo-tuner`, `tempo-critic`, `tempo-roadie`, `tempo-improv`, `tempo-liner`.
|
|
205
|
+
Eight types ship out of the box: `tempo-conductor`, `tempo-composer`, `tempo-soloist`, `tempo-tuner`, `tempo-critic`, `tempo-roadie`, `tempo-improv`, `tempo-liner`. Five lineup presets are included: `tempo-big-band`, `tempo-dev-team`, `tempo-review-squad`, `tempo-jam-session`, `tempo-mock-jam`.
|
|
206
206
|
|
|
207
207
|
```bash
|
|
208
208
|
claude-tempo agent-types list # discover available types
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.\@container{container-type:inline-size}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-1{margin:calc(var(--spacing) * 1)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.flex-shrink,.shrink{flex-shrink:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.flex-wrap{flex-wrap:wrap}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.border{border-style:var(--tw-border-style);border-width:1px}.pr-8{padding-right:calc(var(--spacing) * 8)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.\[claude-tempo\:adapter\]{claude-tempo:adapter}.\[claude-tempo\:dashboard\]{claude-tempo:dashboard}}:root,[data-theme=dark]{--accent:#e07a5f;--accent-soft:oklch(72% .12 28/.18);--accent-ink:oklch(92% .05 28);--bg:#0f1117;--bg-1:#141722;--bg-2:#1a1e2b;--bg-3:#20253417;--bg-chat-out:#1b2030;--text:#f5eee6;--text-2:#c5c1b9;--dim:#7d8090;--muted:#4b5064;--muted-2:var(--muted);--rule:#262b3a;--rule-strong:#343a4f;--ok:#8cc79a;--warn:#e9c888;--err:#ef5c5c;--info:#7fb3d5;--shadow-1:0 1px 0 #ffffff05 inset, 0 1px 0 #0000004d;--shadow-2:0 10px 30px -16px #0009;--ff-ui:"Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--ff-display:"Instrument Serif", "Times New Roman", serif;--ff-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace}[data-theme=light]{--accent:#c05a3d;--accent-soft:oklch(72% .12 28/.14);--accent-ink:oklch(38% .12 28);--bg:#f7f3ec;--bg-1:#fffcf4;--bg-2:#fbf6eb;--bg-3:#efe9db;--bg-chat-out:#f1eadc;--text:#1b2838;--text-2:#3d4758;--dim:#6b7280;--muted:#98a0ae;--muted-2:var(--muted);--rule:#e2d9c7;--rule-strong:#c8bda7;--ok:#4a8a5c;--warn:#b5862a;--err:#b9493f;--info:#346389}:root{--density-pad:14px;--density-pad-y:10px;--density-gap:14px;--density-fs:13px;--density-fs-sm:11.5px;--density-line:1.5}html[data-density="4"]{--density-pad:22px;--density-pad-y:16px;--density-gap:22px;--density-fs:15px;--density-fs-sm:13px;--density-line:1.7}html[data-density="5"]{--density-pad:18px;--density-pad-y:13px;--density-gap:18px;--density-fs:14px;--density-fs-sm:12px;--density-line:1.6}html[data-density="6"]{--density-pad:14px;--density-pad-y:10px;--density-gap:14px;--density-fs:13px;--density-fs-sm:11.5px;--density-line:1.5}html[data-density="7"]{--density-pad:11px;--density-pad-y:8px;--density-gap:11px;--density-fs:12.5px;--density-fs-sm:11px;--density-line:1.45}html[data-density="8"]{--density-pad:9px;--density-pad-y:6px;--density-gap:9px;--density-fs:12px;--density-fs-sm:10.5px;--density-line:1.4}html[data-density="9"]{--density-pad:7px;--density-pad-y:5px;--density-gap:7px;--density-fs:11.5px;--density-fs-sm:10px;--density-line:1.35}.panel-body{padding:var(--density-pad);gap:var(--density-gap)}.panel-head{padding:var(--density-pad-y) var(--density-pad)}.roster-item{padding:var(--density-pad-y) var(--density-pad);gap:var(--density-gap)}.event-row{padding:calc(var(--density-pad-y) * .6) var(--density-pad);gap:var(--density-gap);font-size:var(--density-fs-sm)}.msg{padding:var(--density-pad-y) var(--density-pad);gap:var(--density-gap)}.chat-log{gap:calc(var(--density-gap) * .6);padding:var(--density-pad)}.kv{padding:calc(var(--density-pad-y) * .5) 0}.table th,.table td{padding:var(--density-pad-y) var(--density-pad);font-size:var(--density-fs-sm)}.page-header{padding:var(--density-pad) calc(var(--density-pad) * 1.6)}.workspace{gap:var(--density-gap);padding:0 calc(var(--density-pad) * 1.6) calc(var(--density-pad) * 1.6)}.brandmark{color:var(--text);align-items:center;gap:10px;display:inline-flex}.brandmark-word{font-family:var(--ff-mono);letter-spacing:-.02em;color:var(--text);font-weight:600}.brandmark-dash{color:var(--accent)}.tempo-metronome{color:var(--text);display:inline-flex}.tempo-metronome svg{display:block;overflow:visible}.tempo-metronome .pendulum{transform-origin:32px 46px;animation:pendulum var(--bpm-dur,.65s) ease-in-out infinite alternate}.tempo-metronome:not(.is-running) .pendulum{animation:none}@keyframes pendulum{0%{transform:rotate(-28deg)}to{transform:rotate(28deg)}}.tempo-strip{background:var(--bg-1);border:1px solid var(--rule);border-radius:8px;padding:8px 12px 4px;position:relative;overflow:hidden}.tempo-strip-label{letter-spacing:.08em;text-transform:uppercase;pointer-events:none;z-index:2;justify-content:space-between;font-size:10.5px;display:flex;position:absolute;top:8px;left:12px;right:12px}.tempo-bpm{color:var(--accent);align-items:baseline;gap:6px;font-weight:600;display:inline-flex}.tempo-strip-svg{margin-top:14px;display:block}.section-head{justify-content:space-between;align-items:baseline;gap:16px;margin:0 0 14px;display:flex}.section-head.is-tight{margin-bottom:8px}.section-kicker{letter-spacing:.12em;text-transform:uppercase;color:var(--dim);margin-bottom:4px;font-size:10.5px}.section-title{font-family:var(--ff-display);letter-spacing:-.01em;color:var(--text);font-size:22px;line-height:1.1}.section-head-right{align-items:center;gap:6px;display:inline-flex}.kv{border-bottom:1px dashed var(--rule);justify-content:space-between;gap:12px;min-width:0;padding:5px 0;font-size:12px;display:flex}.kv:last-child{border-bottom:0}.kv-k{color:var(--dim);letter-spacing:.02em}.kv-v{color:var(--text);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.btn{font-family:var(--ff-ui);border:1px solid var(--rule-strong);cursor:pointer;background:var(--bg-1);color:var(--text);border-radius:6px;justify-content:center;align-items:center;gap:6px;padding:6px 11px;font-size:13px;font-weight:500;line-height:1.2;transition:transform .12s,background .12s,border-color .12s;display:inline-flex}.btn:hover{border-color:var(--accent)}.btn:active{transform:translateY(1px)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-sm{padding:4px 8px;font-size:12px}.btn-lg{padding:9px 14px;font-size:14px}.btn-primary{background:var(--accent);border-color:var(--accent);color:#14151a;font-weight:600}.btn-primary:hover{filter:brightness(1.07);border-color:var(--accent)}.btn-ghost{color:var(--text-2);background:0 0;border-color:#0000}.btn-ghost:hover{background:var(--bg-1);color:var(--text);border-color:var(--rule)}.btn-danger{border-color:var(--rule-strong);color:var(--err);background:0 0}.btn-danger:hover{border-color:var(--err)}.btn-icon{font-family:var(--ff-mono);font-size:13px}.kbd{font-family:var(--ff-mono);border:1px solid var(--rule-strong);color:var(--text-2);background:var(--bg-1);border-bottom-width:2px;border-radius:4px;padding:1px 6px;font-size:10.5px;line-height:1.4;display:inline-block}.app-shell{background:var(--bg);grid-template-columns:244px 1fr;height:100%;min-height:0;display:grid}.sidebar{background:var(--bg-1);border-right:1px solid var(--rule);flex-direction:column;display:flex;overflow:hidden}.sidebar-brand{border-bottom:1px solid var(--rule);padding:16px 18px 14px}.sidebar-section{padding:14px 10px 8px}.sidebar-section+.sidebar-section{border-top:1px solid var(--rule)}.sidebar-kicker{font-family:var(--ff-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim);justify-content:space-between;align-items:center;padding:0 10px 8px;font-size:10px;display:flex}.sidebar-kicker .count{color:var(--muted);font-weight:500}.ensemble-row{cursor:pointer;color:var(--text-2);border-radius:6px;grid-template-columns:14px 1fr auto;align-items:center;gap:10px;padding:7px 10px;font-size:13px;display:grid}.ensemble-row:hover{background:var(--bg-2);color:var(--text)}.ensemble-row.is-active{background:var(--accent-soft);color:var(--text);box-shadow:inset 2px 0 0 var(--accent);border-radius:0 6px 6px 0;margin-left:-2px;padding-left:12px}.ensemble-row .er-dot{background:var(--muted);border-radius:50%;width:7px;height:7px;margin-left:4px}.ensemble-row.has-active .er-dot{background:var(--ok);box-shadow:0 0 0 3px var(--ok)}@supports (color:color-mix(in lab, red, red)){.ensemble-row.has-active .er-dot{box-shadow:0 0 0 3px color-mix(in oklch, var(--ok), transparent 78%)}}.ensemble-row .col{min-width:0}.ensemble-row .er-name{letter-spacing:-.005em;text-overflow:ellipsis;white-space:nowrap;font-weight:500;overflow:hidden}.ensemble-row .er-meta{font-family:var(--ff-mono);color:var(--dim);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.ensemble-row .er-initial{display:none}.nav-row{color:var(--text-2);cursor:pointer;border-radius:6px;align-items:center;gap:10px;padding:7px 14px;font-size:13px;display:flex}.nav-row .nav-icon{font-family:var(--ff-mono);color:var(--dim);width:14px;display:inline-block}.nav-row:hover{background:var(--bg-2);color:var(--text)}.nav-row.is-active{color:var(--text);background:var(--bg-2)}.sidebar-footer{border-top:1px solid var(--rule);font-family:var(--ff-mono);color:var(--dim);justify-content:space-between;align-items:center;margin-top:auto;padding:10px 14px;font-size:10.5px;display:flex}.conn-ok{color:var(--ok)}.main{background:var(--bg);flex-direction:column;height:100%;min-height:0;display:flex;overflow:hidden}.page-header{grid-template-columns:1fr auto;align-items:start;gap:16px;padding:16px 26px 0;display:grid}.page-header>.page-actions{align-self:start;margin-top:2px}.page-title-row{flex-wrap:wrap;align-items:center;gap:16px;min-height:34px;display:flex}.page-title{font-family:var(--ff-display);letter-spacing:-.02em;color:var(--text);overflow-wrap:break-word;align-items:baseline;gap:0;min-width:0;margin:0;font-size:34px;line-height:1;display:inline-flex}.page-title .at{color:var(--accent)}.page-title .prefix{font-family:var(--ff-mono);color:var(--dim);letter-spacing:0;align-self:center;margin-right:8px;font-size:14px;font-weight:500;transform:translateY(1px)}.page-subtitle{color:var(--dim);font-size:13px}.page-pills{align-items:center;gap:8px;display:inline-flex}.page-pill{background:var(--bg-1);border:1px solid var(--rule);font-family:var(--ff-mono);color:var(--text-2);border-radius:999px;align-items:center;gap:7px;padding:3px 10px;font-size:11.5px;display:inline-flex}.page-pill .pill-num{color:var(--text);font-variant-numeric:tabular-nums;font-weight:600}.page-pill .pill-dot{background:var(--ok);border-radius:50%;width:6px;height:6px}.page-pill.warn{color:var(--warn);border-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.page-pill.warn{border-color:color-mix(in oklch, var(--warn), transparent 60%)}}.page-actions{align-items:center;gap:8px;display:inline-flex}.page-tempo{padding:14px 26px 0}.workspace{flex:1;grid-template-columns:1fr 340px;gap:18px;min-height:0;padding:18px 26px 26px;display:grid}.workspace-main{flex-direction:column;gap:14px;min-width:0;display:flex}.workspace-side{flex-direction:column;gap:16px;min-width:0;min-height:0;display:flex;overflow-y:auto}.workspace-side>.panel{flex:none}.ws-side-sheet-grip,.ws-side-sheet-close,.ws-side-scrim{display:none}.workspace.workspace-collapsed{grid-template-columns:1fr}.side-toggle{background:var(--bg-1);border:1px solid var(--rule);color:var(--text-2);font-family:var(--ff-mono);cursor:pointer;border-radius:6px;align-items:center;gap:6px;margin-left:6px;padding:5px 10px;font-size:11px;transition:background .12s,border-color .12s,color .12s;display:inline-flex}.side-toggle:hover{background:var(--bg-2);color:var(--text);border-color:var(--rule-strong)}.side-toggle.is-active{background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.side-toggle.is-active{background:color-mix(in oklch, var(--accent), transparent 88%)}}.side-toggle.is-active{border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.side-toggle.is-active{border-color:color-mix(in oklch, var(--accent), transparent 60%)}}.side-toggle.is-active{color:var(--accent)}.side-toggle .st-icon{opacity:.85;align-items:center;line-height:1;display:inline-flex}.side-toggle.is-active .st-icon{opacity:1}.side-toggle .st-badge{background:var(--bg-2);border:1px solid var(--rule);color:var(--text-2);border-radius:4px;margin-left:2px;padding:1px 5px;font-size:10px}.panel{background:var(--bg-1);border:1px solid var(--rule);border-radius:10px;flex-direction:column;min-height:0;display:flex}.panel-head{border-bottom:1px solid var(--rule);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;padding:12px 16px;display:flex}.panel-head-title{align-items:baseline;gap:10px;min-width:0;display:inline-flex}.panel-head-title .h{font-family:var(--ff-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--dim);font-size:11px;font-weight:600}.panel-head-title .subj{font-family:var(--ff-display);color:var(--text);text-overflow:ellipsis;white-space:nowrap;font-size:18px;overflow:hidden}.panel-body{padding:14px 16px}.panel-body.tight{padding:10px 14px}.panel-body.flush{padding:0}.chat{flex-direction:column;flex:1 1 0;min-height:0;display:flex}.chat-log{scrollbar-width:thin;flex-direction:column;flex:1 1 0;gap:14px;min-height:0;padding:14px 18px;display:flex;overflow:auto}.chat .composer{flex:none}.msg{grid-template-columns:28px 1fr;align-items:start;gap:10px;display:grid}.msg-avatar{padding-top:2px}.msg-head{font-family:var(--ff-mono);color:var(--dim);align-items:baseline;gap:8px;margin-bottom:3px;font-size:11.5px;display:flex}.msg-head .sender{color:var(--accent);font-weight:600}.msg-head .arrow{color:var(--muted)}.msg-head .target{color:var(--text-2)}.msg-head .time{color:var(--muted);margin-left:4px;font-size:10.5px}.msg-body{color:var(--text);text-wrap:pretty;max-width:72ch;font-size:13.5px;line-height:1.55}.msg-body pre{white-space:pre;max-width:100%;display:block;overflow-x:auto}.msg-body code{overflow-wrap:anywhere}.msg.route .msg-body{color:var(--text-2);font-size:12.5px;font-style:italic}.msg.route{margin-left:22px;padding:4px 0;position:relative}.msg.route:before{content:"";background:var(--rule);width:2px;position:absolute;top:8px;bottom:8px;left:-10px}@supports (color:color-mix(in lab, red, red)){.msg.route:before{background:color-mix(in oklch, var(--rule), transparent 20%)}}.msg.route:before{border-radius:2px}.msg.route .msg-avatar{filter:saturate(.6);padding-top:1px}.msg.route .msg-avatar>*{width:20px!important;height:20px!important;font-size:11px!important}.msg.route .msg-head{font-size:10.5px}.msg.route .msg-head .sender{font-weight:500;color:currentColor!important}@supports (color:color-mix(in lab, red, red)){.msg.route .msg-head .sender{color:color-mix(in oklch, currentColor 80%, var(--text-2))!important}}.msg.route .msg-head .arrow,.msg.route .msg-head .target,.msg.route .msg-head .time{color:var(--text-2)}.msg.out{background:var(--bg-chat-out);border:1px solid var(--accent);border-radius:10px 10px 4px;margin:4px 0 4px 56px;padding:10px 14px}@supports (color:color-mix(in lab, red, red)){.msg.out{border:1px solid color-mix(in oklch, var(--accent), transparent 75%)}}.msg.out{border-right:3px solid var(--accent);align-self:flex-end;max-width:78%;display:block}.msg.out .msg-head{justify-content:flex-end}.msg.out .msg-head .sender{color:var(--accent);text-transform:lowercase;font-weight:600}.msg.out .msg-head .target{color:var(--text-2)}.msg.out .msg-body{color:var(--text)}.msg.out .msg-avatar{display:none}.chat-log{flex-direction:column;display:flex}.composer{border-top:1px solid var(--rule);background:var(--bg-1);padding:14px 18px 16px}.composer-frame{background:var(--bg-2);border:1px solid var(--rule-strong);border-radius:8px;flex-direction:column;transition:border-color .15s,box-shadow .15s;display:flex}.composer-frame:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent)}@supports (color:color-mix(in lab, red, red)){.composer-frame:focus-within{box-shadow:0 0 0 3px color-mix(in oklch, var(--accent), transparent 80%)}}.composer-input{resize:none;color:var(--text);font-family:var(--ff-ui);background:0 0;border:0;outline:0;width:100%;min-height:24px;max-height:200px;padding:10px 14px 4px;font-size:14px;line-height:1.55;overflow-y:auto}.composer-input::placeholder{color:var(--muted)}.composer-toolbar{justify-content:space-between;align-items:center;padding:4px 8px 6px;display:flex}.composer-tools{gap:6px;display:flex}.composer-send{align-items:center;gap:8px;display:flex}.composer-hint{font-size:10.5px}.composer-icon{background:var(--bg-2);border:1px solid var(--rule);width:30px;height:30px;color:var(--text-2);font-family:var(--ff-mono);cursor:pointer;border-radius:7px;justify-content:center;align-items:center;font-size:15px;font-weight:600;line-height:1;transition:background .12s,color .12s,border-color .12s,transform 60ms;display:inline-flex}.composer-icon:hover{background:var(--bg-3);color:var(--text);border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.composer-icon:hover{border-color:color-mix(in oklch, var(--accent), transparent 70%)}}.composer-icon:active{transform:translateY(1px)}.roster{flex-direction:column;display:flex}.roster-item{border-bottom:1px solid var(--rule);cursor:pointer;grid-template-columns:32px 1fr auto;align-items:center;gap:10px;padding:10px 14px;display:grid;position:relative}.roster-item:last-child{border-bottom:0}.roster-item:hover{background:var(--bg-2)}.roster-item .rn{align-items:center;gap:8px;font-size:13px;font-weight:500;display:flex}.roster-item .rn .conductor-star{color:var(--warn);font-size:11px}.roster-item .rp{font-family:var(--ff-mono);color:var(--dim);margin-top:2px;font-size:11px}.roster-item .rmeta{text-align:right;font-family:var(--ff-mono);color:var(--dim);font-size:10.5px}.roster-item .rmeta .heartbeat{color:var(--text-2)}.event-log{font-family:var(--ff-mono);flex-direction:column;font-size:11.5px;display:flex}.event-row{color:var(--text-2);grid-template-columns:62px 72px 1fr;gap:10px;padding:4px 16px;line-height:1.5;display:grid}.event-row:nth-child(2n){background:var(--bg-2)}@supports (color:color-mix(in lab, red, red)){.event-row:nth-child(2n){background:color-mix(in oklch, var(--bg-2), transparent 50%)}}.event-row .t{color:var(--dim)}.event-row .k{color:var(--accent);text-transform:uppercase;letter-spacing:.08em;padding-top:1px;font-size:10px;font-weight:600}.event-row .k.phase{color:var(--warn)}.event-row .k.heartbeat{color:var(--info)}.event-row .k.ensemble{color:var(--ok)}.table{border-collapse:collapse;width:100%;font-size:13px}.table th,.table td{text-align:left;border-bottom:1px solid var(--rule);vertical-align:middle;padding:10px 14px}.table th{font-family:var(--ff-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--dim);background:var(--bg-2);border-top:1px solid var(--rule);font-size:10.5px;font-weight:600}.table tr.is-active{background:var(--accent-soft)}.table td.mono,.table td .mono{font-family:var(--ff-mono);font-size:12.5px}.table td.num{font-variant-numeric:tabular-nums}.table td:first-child.mono{text-overflow:ellipsis;white-space:nowrap;max-width:240px;overflow:hidden}.dialog{background:var(--bg-1);border:1px solid var(--rule);width:100%;max-width:580px;box-shadow:var(--shadow-2);border-radius:12px;flex-direction:column;display:flex;overflow:hidden}.dialog-head{border-bottom:1px solid var(--rule);justify-content:space-between;align-items:baseline;padding:14px 18px 12px;display:flex}.dialog-head .dialog-title{font-family:var(--ff-display);color:var(--text);letter-spacing:-.01em;font-size:22px}.dialog-head .steps{font-family:var(--ff-mono);color:var(--dim);font-size:11px}.dialog-body{flex-direction:column;gap:14px;padding:18px;display:flex}.dialog-foot{border-top:1px solid var(--rule);background:var(--bg-2);justify-content:space-between;align-items:center;gap:8px;padding:12px 18px;display:flex}.dialog-foot .hint{font-family:var(--ff-mono);color:var(--dim);font-size:11px}.field{flex-direction:column;gap:6px;display:flex}.field-label{font-family:var(--ff-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--dim);justify-content:space-between;align-items:baseline;font-size:10.5px;display:flex}.input,.textarea,.select{background:var(--bg-2);border:1px solid var(--rule);font-family:var(--ff-mono);color:var(--text);border-radius:6px;outline:none;width:100%;padding:8px 11px;font-size:12.5px}.input:focus,.textarea:focus,.select:focus{border-color:var(--accent)}.textarea{resize:vertical;min-height:80px;font-family:var(--ff-ui);font-size:13px;line-height:1.55}.chipset{flex-wrap:wrap;gap:6px;display:flex}.chip{border:1px solid var(--rule);font-family:var(--ff-mono);color:var(--text-2);cursor:pointer;background:var(--bg-2);border-radius:999px;padding:4px 9px;font-size:11px}.chip.is-active{background:var(--accent-soft);color:var(--accent);border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.chip.is-active{border-color:color-mix(in oklch, var(--accent), transparent 55%)}}.picker-list{border:1px solid var(--rule);background:var(--bg-2);border-radius:8px;flex-direction:column;gap:4px;padding:6px;display:flex}.picker-row{cursor:pointer;border-radius:6px;grid-template-columns:18px 1fr auto;align-items:center;gap:10px;padding:7px 10px;font-size:13px;display:grid}.picker-row.is-active{background:var(--accent-soft);color:var(--text)}.picker-row .marker{color:var(--accent);font-family:var(--ff-mono)}.picker-row.is-active .marker:before{content:"▸"}.picker-row .name{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:500;overflow:hidden}.picker-row .desc{color:var(--dim);font-size:11.5px;font-family:var(--ff-mono)}.ensemble-grid{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;display:grid}.ensemble-card{background:var(--bg-1);border:1px solid var(--rule);cursor:pointer;border-radius:10px;flex-direction:column;gap:12px;padding:16px;transition:border-color .15s,transform .15s;display:flex}.ensemble-card:hover{border-color:var(--accent);transform:translateY(-1px)}.ensemble-card.is-empty{opacity:.6}.ec-head{justify-content:space-between;align-items:baseline;gap:8px;display:flex;overflow:hidden}.ec-name{font-family:var(--ff-display);color:var(--text);letter-spacing:-.01em;text-overflow:ellipsis;white-space:nowrap;flex:1 1 0;min-width:0;font-size:22px;overflow:hidden}.ec-name .at{color:var(--accent)}.ec-tempo{font-family:var(--ff-mono);color:var(--dim);flex-shrink:0;align-items:baseline;gap:4px;font-size:11px;display:inline-flex}.ec-tempo .bpm{color:var(--accent);font-size:13px;font-weight:700}.ec-desc{color:var(--text-2);overflow-wrap:break-word;word-break:break-word;min-height:40px;font-size:13px;line-height:1.5}.ec-stats{font-family:var(--ff-mono);grid-template-columns:repeat(3,1fr);gap:6px;font-size:11px;display:grid}.ec-stat .n{color:var(--text);font-size:15px;font-weight:600}.ec-stat .l{color:var(--dim);letter-spacing:.1em;text-transform:uppercase;font-size:10px}.ec-roster{gap:4px;margin-top:2px;display:flex}.ec-meta{justify-content:space-between;font-size:11px;display:flex}.ec-meta>span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.ec-meta>span:first-child{flex:1 1 0}.ec-meta>span:last-child{flex:0 auto}.ec-flags{gap:6px;display:flex}.ec-flag{background:var(--bg-2);border:1px solid var(--rule);font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);border-radius:4px;padding:1px 6px;font-size:11px}.artboard-body{background:var(--bg);flex-direction:column;width:100%;height:100%;display:flex;position:relative;overflow:hidden;container:artboard/inline-size}@container artboard (width<=1200px){.workspace{grid-template-columns:1fr 300px;gap:14px;padding:14px 18px 18px}.page-header{padding:14px 18px 0}.page-tempo{padding:0 18px}.app-shell{grid-template-columns:220px 1fr}}@container artboard (width<=900px){.app-shell{grid-template-columns:64px 1fr}.sidebar-brand{justify-content:center;padding:14px 0 12px;display:flex}.sidebar-brand .brandmark-word,.sidebar-kicker,.sidebar-footer,.sidebar-maestro span:not(.maestro-mark):not(.maestro-mark *):not(.maestro-avatar):not(.maestro-avatar *),.ensemble-row .er-meta,.ensemble-row .col,.ensemble-row>span:last-child,.ensemble-row--new .er-name,.nav-row>span:not(.nav-icon){display:none}.ensemble-row{grid-template-columns:1fr;justify-items:center;padding:8px 6px;position:relative}.ensemble-row .er-dot{display:none}.ensemble-row .er-initial{background:var(--bg-2);width:32px;height:32px;color:var(--text);font-family:var(--ff-mono);border:1px solid var(--rule);border-radius:8px;place-items:center;font-size:13px;font-weight:600;display:grid}.ensemble-row.has-active .er-initial:after{content:"";background:var(--ok);width:6px;height:6px;box-shadow:0 0 0 2px var(--bg-1);border-radius:50%;position:absolute;top:6px;right:12px}.ensemble-row.is-active .er-initial{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}.ensemble-row--new .icon-g{border:1px dashed var(--rule-strong);width:32px;height:32px;color:var(--accent);border-radius:8px;place-items:center;font-size:18px;line-height:1;display:grid}.nav-row{justify-content:center;padding:10px 6px}.nav-row .nav-icon{font-size:16px}.sidebar-section{padding:10px 6px 6px}.workspace{grid-template-columns:1fr;gap:14px;padding:14px 16px 18px}.workspace-side{flex-direction:column}.page-header{grid-template-columns:1fr;gap:8px;padding:14px 16px 0}.page-actions{flex-wrap:wrap}.page-pills{flex-wrap:wrap;gap:4px}.page-tempo{padding:0 16px}.sidebar-maestro{justify-content:center;padding:8px 4px}.sidebar-maestro>:not(.maestro-mark):not(.maestro-avatar){display:none}}.phone-appbar,.phone-tabbar{display:none}@container artboard (width<=520px){.popout-btn,.composer-hint{display:none}.app-shell{grid-template-rows:auto 1fr 64px;grid-template-columns:1fr}.sidebar{display:none}.phone-appbar{background:var(--bg-1);border-bottom:1px solid var(--rule);flex-direction:column;grid-area:1/1;height:auto;min-height:52px;display:flex}.phone-appbar-row{align-items:center;gap:8px;height:52px;padding:0 8px;display:flex}.phone-appbar-status{color:var(--dim);flex-wrap:wrap;align-items:center;gap:10px;padding:0 16px 8px;font-size:10.5px;display:flex}.phone-stat{white-space:nowrap;align-items:center;gap:4px;display:inline-flex}.phone-stat.ok{color:var(--text-2)}.phone-stat.warn{color:var(--warn)}.phone-stat-dot{background:var(--ok);width:6px;height:6px;box-shadow:0 0 0 2px var(--ok);border-radius:50%}@supports (color:color-mix(in lab, red, red)){.phone-stat-dot{box-shadow:0 0 0 2px color-mix(in oklch, var(--ok), transparent 80%)}}.phone-appbar-btn{width:40px;height:40px;color:var(--text-2);cursor:pointer;-webkit-tap-highlight-color:transparent;background:0 0;border:1px solid #0000;border-radius:10px;justify-content:center;align-items:center;display:inline-flex}.phone-appbar-btn:active{background:var(--bg-2)}.phone-appbar-btn.is-active{background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.phone-appbar-btn.is-active{background:color-mix(in oklch, var(--accent), transparent 86%)}}.phone-appbar-btn.is-active{color:var(--accent)}.phone-appbar-title{text-align:center;flex-direction:column;flex:1;align-items:center;gap:0;min-width:0;line-height:1.1;display:flex}.phone-appbar-kicker{font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:.08em;color:var(--dim);font-size:9.5px}.phone-appbar-name{font-family:var(--ff-display);color:var(--text);white-space:nowrap;text-overflow:ellipsis;max-width:220px;font-size:16px;overflow:hidden}.phone-appbar-name .at{color:var(--accent)}.main{grid-area:2/1;min-height:0;position:relative}.phone-tabbar{background:var(--bg-1);border-top:1px solid var(--rule);height:64px;padding:6px 4px calc(6px + env(safe-area-inset-bottom,0px));grid-area:3/1;gap:2px;display:flex}.phone-tab{color:var(--dim);cursor:pointer;-webkit-tap-highlight-color:transparent;background:0 0;border:none;border-radius:10px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3px;padding:4px 6px;transition:color .12s;display:flex;position:relative}.phone-tab:active{background:var(--bg-2)}.phone-tab.is-active{color:var(--accent)}.phone-tab.is-active:before{content:"";background:var(--accent);border-radius:0 0 3px 3px;width:22px;height:3px;position:absolute;top:-7px;left:50%;transform:translate(-50%)}.phone-tab-icon{display:inline-flex}.phone-tab-label{font-family:var(--ff-mono);letter-spacing:.02em;white-space:nowrap;font-size:10px;line-height:1}.app-shell--workspace .page-header{padding:0;display:none}.app-shell:not(.app-shell--workspace) .page-header{grid-template-columns:1fr;gap:6px;padding:12px 14px 0}.app-shell:not(.app-shell--workspace) .page-title{font-size:20px}.app-shell:not(.app-shell--workspace) .page-pills{flex-wrap:wrap;gap:4px}.app-shell:not(.app-shell--workspace) .page-pill{padding:2px 6px;font-size:10px}.app-shell:not(.app-shell--workspace) .page-actions{flex-wrap:wrap;justify-content:flex-end;gap:4px;width:100%}.app-shell:not(.app-shell--workspace) .page-actions .btn{padding:6px 8px;font-size:11px}.workspace{gap:10px;padding:10px 14px 14px}.page-tempo{padding:12px 14px 0}.panel{border-radius:10px}.panel-head{padding:10px 12px}.panel-head .panel-head-title .subj{display:none}.chat-log{padding:10px 12px}.composer{padding:8px 10px}.roster-item{grid-template-columns:28px 1fr;padding:8px 10px}.roster-item>:nth-child(3){grid-column:1/-1;justify-self:end}.event-row{grid-template-columns:60px 1fr;gap:6px;padding:4px 14px}.event-row>:nth-child(2){display:none}.ensemble-grid{grid-template-columns:1fr}.ws-side-scrim{z-index:40;background:oklch(0% none none/.45);animation:.16s fadeIn;display:block;position:absolute;inset:0}.workspace-side{background:var(--bg-1);border-top:1px solid var(--rule);z-index:41;border-top-left-radius:16px;border-top-right-radius:16px;gap:12px;max-height:78%;padding:8px 12px 14px;animation:.2s slideUp;position:absolute;bottom:64px;left:0;right:0;overflow-y:auto;box-shadow:0 -10px 30px -8px #00000073}.ws-side-sheet-grip{background:var(--rule);border-radius:2px;flex-shrink:0;width:36px;height:4px;margin:6px auto;display:block}.ws-side-sheet-close{width:32px;height:32px;color:var(--dim);cursor:pointer;z-index:1;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;font-size:22px;line-height:1;display:inline-flex;position:absolute;top:8px;right:10px}.ws-side-sheet-close:active{background:var(--bg-2)}}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:var(--rule-strong);border:2px solid var(--bg);border-radius:6px}::-webkit-scrollbar-track{background:0 0}.icon-g{font-family:var(--ff-mono);text-align:center;width:14px;color:var(--dim);font-size:13px;display:inline-block}.empty{color:var(--dim);font-family:var(--ff-mono);flex-direction:column;justify-content:center;align-items:center;gap:10px;padding:32px 24px;font-size:12px;display:flex}.row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.col{flex-direction:column;gap:8px;display:flex}.spacer{flex:1}[data-theme=light] .msg.out{background:var(--bg-chat-out)}[data-theme=light] .page-pill{background:var(--bg-1)}.popout-window{background:var(--bg-1);border:1px solid var(--rule-strong);z-index:51;border-radius:12px;flex-direction:column;width:440px;height:560px;max-height:calc(100% - 56px);animation:.22s cubic-bezier(.2,.8,.2,1) popout-in;display:flex;position:absolute;bottom:28px;right:28px;overflow:hidden;box-shadow:inset 0 1px #ffffff0a,0 30px 60px #0000008c,0 60px 120px #00000073,0 0 0 1px #0006}@keyframes popout-in{0%{opacity:0;transform:translate(8px,16px)scale(.96)}to{opacity:1;transform:translate(0)scale(1)}}.popout-chrome{background:linear-gradient(180deg, var(--bg-2), var(--bg-1));border-bottom:1px solid var(--rule);cursor:grab;-webkit-user-select:none;user-select:none;align-items:center;gap:10px;padding:9px 12px;font-size:11px;display:flex}.popout-dots{gap:6px;display:flex}.popout-dot{border:1px solid #00000040;border-radius:50%;width:12px;height:12px;display:inline-block;box-shadow:inset 0 1px #ffffff14}.popout-dot.r{cursor:pointer;background:#ed6a5e}.popout-dot.r:hover:after{content:"×";color:#0000008c;text-align:center;font-size:11px;font-weight:700;line-height:10px;display:block}.popout-dot.y{background:#f4bf4f}.popout-dot.g{background:#61c554}.popout-title{text-align:center;flex:1;font-size:11px}.popout-right{align-items:center;gap:6px;font-size:10px;display:flex}.popout-pin{color:var(--accent)}.popout-log{background:radial-gradient(circle at 50% 0%, #d977570a, transparent 60%), var(--bg-1);flex:1;padding:14px;overflow:auto}.popout-composer{border-top:1px solid var(--rule);background:var(--bg-2);padding:10px 12px}@container artboard (width<=520px){.popout-window{border:none;border-radius:0;width:100%;height:100%;max-height:100%;inset:0}}.sidebar-maestro{border-top:1px solid var(--rule);justify-content:space-between;align-items:center;padding:12px 16px 10px;display:flex}.chat-stub{cursor:pointer;background:var(--bg-1);opacity:.55;justify-content:center;align-items:center;min-height:560px;border:1px dashed var(--rule-strong)!important;display:flex!important}.chat-stub:hover{opacity:.8}.chat-stub-inner{text-align:center;max-width:320px;padding:24px}.chat-stub-icon{color:var(--accent);margin-bottom:10px;font-size:32px}.chat-stub-title{font-family:var(--ff-display);color:var(--text);margin-bottom:6px;font-size:20px}.chat-stub-sub{font-size:11.5px;line-height:1.5}.page-pad{flex:1;min-height:0;padding:18px 26px 26px}.page-pad.scroll{overflow:auto}.field-grid-2{grid-template-columns:1fr 1fr;gap:12px;display:grid}.types-grid{grid-template-columns:1fr 1fr;grid-auto-rows:max-content;align-content:start;gap:14px;display:grid}.subj.display{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.sheet-overlay{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:50;background:oklch(0% none none/.6);position:absolute;inset:0}.player-sheet{z-index:51;width:1080px;max-width:100%;max-height:82%;box-shadow:0 24px 80px #0009, 0 0 0 1px var(--rule-strong);border-radius:14px;flex-direction:column;display:flex;position:absolute;top:50%;left:50%;overflow:hidden;transform:translate(-50%,-50%)}.player-sheet-head{background:var(--bg-2)}.player-sheet-body{background:var(--bg-1);flex:1;grid-template-columns:1fr 280px;min-height:0;display:grid}.player-sheet-main{border-right:1px solid var(--rule);padding:16px 20px;overflow:auto}.player-sheet-side{background:var(--bg-2);padding:16px 20px;overflow:auto}@container artboard (width<=900px){.page-pad{padding:14px 16px 18px}.types-grid{grid-template-columns:1fr;gap:12px;padding:14px 16px 18px}.field-grid-2{grid-template-columns:1fr}.player-sheet{width:92%;max-height:86%}.player-sheet-body{grid-template-rows:1fr auto;grid-template-columns:1fr}.player-sheet-main{border-right:none;border-bottom:1px solid var(--rule)}.player-sheet-side{max-height:280px}.player-sheet-head,.player-sheet-head .row{flex-wrap:wrap}}@container artboard (width<=520px){.page-pad{padding:10px 12px 14px}.types-grid{gap:10px;padding:10px 12px 14px}.panel:has(>.table){overflow-x:visible}.table,.table thead,.table tbody,.table tr,.table th,.table td{width:auto;min-width:0;display:block}.table{border-collapse:separate;border-spacing:0;width:100%;min-width:0}.table thead{display:none}.table tr{border-top:1px solid var(--rule);grid-template-columns:1fr;row-gap:6px;padding:14px 14px 12px;display:grid}.table tr:first-child{border-top:none}.table tr.is-active{background:var(--accent-soft)}.table td{white-space:normal;border:none;padding:0;font-size:13px;line-height:1.4}.table td:first-child{margin-bottom:2px;font-size:14px;font-weight:600}.table td:last-child{border-top:1px dashed var(--rule);gap:8px;margin-top:8px;padding-top:8px;text-align:left!important;display:flex!important}.table tbody tr td:not(:first-child):not(:last-child){grid-template-columns:84px 1fr;align-items:baseline;column-gap:12px;font-size:12.5px;display:grid!important}.table tbody tr td:not(:first-child):not(:last-child):before{content:attr(data-label);font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:.06em;color:var(--text-2);font-size:10px;line-height:1.6}.table .type-badge,.table .mono.dim{white-space:nowrap;display:inline-block}.table td:last-child .btn{flex:1;justify-content:center}.dialog{border-radius:12px;width:calc(100% - 16px);max-width:none;max-height:calc(100% - 16px)}.dialog-head{flex-direction:column;align-items:flex-start;gap:4px;padding:12px 14px 10px}.dialog-head .dialog-title{font-size:18px}.dialog-body{gap:10px;padding:14px}.dialog-foot{flex-direction:column;align-items:stretch;gap:8px;padding:10px 14px}.dialog-foot .hint{display:none}.dialog-foot .row{justify-content:flex-end}.player-sheet{border-radius:0;width:100%;max-width:100%;height:100%;max-height:100%;top:0;left:0;transform:none}.player-sheet-head{gap:8px;padding:10px 12px}.player-sheet-head .panel-head-title .display{font-size:17px!important}.player-sheet-head .row .btn{padding:6px 8px;font-size:11px}.player-sheet-head .row .btn:nth-of-type(3),.player-sheet-head .row .btn:nth-of-type(4),.player-sheet-head .row .btn:nth-of-type(5){display:none}.player-sheet-main{padding:12px 14px}.player-sheet-side{max-height:220px;padding:12px 14px}.sheet-overlay-label{padding:3px 8px!important;font-size:10px!important}.input,.select,.textarea{padding:8px 10px;font-size:13px}.picker-row{padding:8px 10px}.picker-row .name{font-size:12.5px}.picker-row .desc{font-size:11px}.ensemble-card{gap:8px;padding:12px}.ec-name,.ec-stat .n{font-size:16px}.types-grid>.panel{padding:12px!important}.types-grid>.panel>.row:first-child{flex-wrap:wrap;gap:6px}.types-grid>.panel>.row:last-child{flex-wrap:wrap;row-gap:6px}.types-grid>.panel>.row:last-child>.row{flex-wrap:wrap}.section-head .title{font-size:14px}.page-subtitle{font-size:11.5px}}.ens-switcher{z-index:50;background:oklch(0% none none/.5);align-items:end;animation:.16s fadeIn;display:grid;position:absolute;inset:0}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.ens-switcher-sheet{background:var(--bg-1);border:1px solid var(--rule);padding:8px 0 calc(8px + env(safe-area-inset-bottom,0px));border-bottom:none;border-top-left-radius:16px;border-top-right-radius:16px;flex-direction:column;max-height:80%;animation:.18s slideUp;display:flex}.ens-switcher-grip{background:var(--rule);border-radius:2px;width:36px;height:4px;margin:6px auto 8px}.ens-switcher-head{border-bottom:1px solid var(--rule);justify-content:space-between;align-items:center;padding:6px 16px 12px;display:flex}.ens-switcher-title{font-family:var(--ff-display);color:var(--text);font-size:18px}.ens-switcher-close{width:32px;height:32px;color:var(--dim);cursor:pointer;background:0 0;border:none;border-radius:8px;font-size:22px;line-height:1}.ens-switcher-close:active{background:var(--bg-2)}.ens-switcher-list{padding:6px 8px;overflow-y:auto}.ens-switcher-row{cursor:pointer;text-align:left;width:100%;color:var(--text);-webkit-tap-highlight-color:transparent;background:0 0;border:none;border-radius:10px;grid-template-columns:16px 1fr auto;align-items:center;gap:12px;padding:12px;display:grid}.ens-switcher-row+.ens-switcher-row{border-top:1px solid var(--rule-soft,var(--rule))}.ens-switcher-row:active{background:var(--bg-2)}.ens-switcher-row.is-active{background:var(--accent)}@supports (color:color-mix(in lab, red, red)){.ens-switcher-row.is-active{background:color-mix(in oklch, var(--accent), transparent 88%)}}.ens-switcher-row.is-active:before{display:none}.ens-switcher-dot{background:var(--bg-2);border:1px solid var(--rule);border-radius:50%;width:10px;height:10px}.ens-switcher-dot.on{background:var(--ok);border-color:var(--ok);box-shadow:0 0 0 2px var(--ok)}@supports (color:color-mix(in lab, red, red)){.ens-switcher-dot.on{box-shadow:0 0 0 2px color-mix(in oklch, var(--ok), transparent 80%)}}.ens-switcher-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.ens-switcher-name{font-family:var(--ff-display);color:var(--text);white-space:nowrap;text-overflow:ellipsis;font-size:16px;overflow:hidden}.ens-switcher-name .at{color:var(--accent)}.ens-switcher-sub{font-family:var(--ff-mono);color:var(--dim);font-size:11px}.ens-switcher-check{color:var(--accent);font-size:16px}.ens-switcher-new{border:1px dashed var(--rule);color:var(--accent);font-family:var(--ff-display);cursor:pointer;-webkit-tap-highlight-color:transparent;background:0 0;border-radius:10px;align-items:center;gap:12px;margin:6px 12px 4px;padding:14px 12px;font-size:15px;display:flex}.ens-switcher-new:active{background:var(--bg-2)}.ens-switcher-plus{text-align:center;width:20px;font-size:18px}@container artboard (width>=521px){.ens-switcher{place-items:center;padding:24px}.ens-switcher-sheet{border:1px solid var(--rule);border-radius:14px;width:100%;max-width:480px;max-height:70%;animation:.16s slideUp}.ens-switcher-grip{display:none}}.settings-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;display:grid}.settings-panel .panel-body{padding:12px 16px 14px}.settings-danger-row{justify-content:space-between;align-items:center;gap:12px;padding:10px 0;display:flex}.settings-danger-row+.settings-danger-row{border-top:1px solid var(--rule)}@container artboard (width<=720px){.settings-grid{grid-template-columns:1fr}}.notif-badge{min-width:18px;height:18px;font-family:var(--ff-mono);color:#14151a;background:var(--accent);letter-spacing:0;border-radius:999px;flex-shrink:0;justify-content:center;align-items:center;padding:0 5px;font-size:10px;font-weight:600;line-height:1;display:inline-flex}.notif-dot{background:var(--accent);border-radius:50%;flex-shrink:0;width:6px;height:6px;display:inline-block}.ensemble-row.has-unread .er-name{color:var(--text);font-weight:600}.ensemble-row.has-unread .er-meta{color:var(--text-2)}.toast-stack{z-index:80;pointer-events:none;flex-direction:column-reverse;gap:10px;width:360px;max-width:360px;display:flex;position:fixed;bottom:20px;right:20px}.toast-overflow{background:var(--bg-2);border:1px solid var(--rule);color:var(--dim);pointer-events:auto;border-radius:999px;align-self:flex-end;padding:4px 10px;font-size:11px}.toast{pointer-events:auto;background:var(--bg-1);border:1px solid var(--rule-strong);cursor:pointer;transform-origin:100% 100%;border-radius:10px;gap:12px;padding:12px 14px;transition:transform .15s,border-color .15s;display:flex;position:relative;box-shadow:0 12px 28px -8px #00000080,0 2px 8px -2px #0000004d}@media (prefers-reduced-motion:no-preference){.toast{animation:.24s cubic-bezier(.2,.9,.3,1.2) toast-in}}.toast:hover{border-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.toast:hover{border-color:color-mix(in oklch, var(--accent), var(--rule-strong) 50%)}}.toast:hover{transform:translateY(-1px)}.toast[data-stack-index="1"]{opacity:.92;transform:scale(.985)}.toast[data-stack-index="2"]{opacity:.82;transform:scale(.97)}.toast[data-stack-index="2"]:hover{transform:scale(.97)translateY(-1px)}@keyframes toast-in{0%{opacity:0;transform:translate(20px)scale(.96)}to{opacity:1;transform:translate(0)scale(1)}}.toast-avatar{width:32px;height:32px;font-family:var(--ff-display);letter-spacing:-.02em;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.toast-body{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.toast-head{color:var(--dim);white-space:nowrap;align-items:center;gap:6px;font-size:11.5px;display:flex;overflow:hidden}.toast-sender{color:var(--text);font-size:12px;font-weight:600}.toast-divider{color:var(--muted)}.toast-ensemble{color:var(--accent);font-family:var(--ff-mono);text-overflow:ellipsis;font-size:11px;overflow:hidden}.toast-count{background:var(--accent-soft);color:var(--accent);border-radius:4px;padding:0 5px;font-size:10px;font-weight:600}.toast-time{color:var(--muted);flex-shrink:0;margin-left:auto;font-size:10px}.toast-message{color:var(--text);-webkit-line-clamp:2;text-wrap:pretty;-webkit-box-orient:vertical;font-size:13px;line-height:1.45;display:-webkit-box;overflow:hidden}.toast-actions{gap:4px;margin-top:4px;margin-left:-6px;display:flex}.toast-action{font-family:var(--ff-mono);color:var(--accent);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:3px 6px;font-size:11px;transition:background .12s}.toast-action:hover{background:var(--accent-soft)}.toast-action--ghost{color:var(--dim)}.toast-action--ghost:hover{background:var(--bg-2);color:var(--text-2)}.toast-close{width:22px;height:22px;color:var(--dim);cursor:pointer;opacity:0;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;font-size:16px;line-height:1;transition:opacity .15s,background .12s,color .12s;display:flex;position:absolute;top:6px;right:6px}.toast:hover .toast-close{opacity:1}.toast-close:hover{background:var(--bg-2);color:var(--text)}*{box-sizing:border-box}html,body{background:var(--bg);height:100%;color:var(--text);font-family:var(--ff-ui);font-size:var(--density-fs);line-height:var(--density-line);font-feature-settings:"ss01";-webkit-font-smoothing:antialiased;margin:0}#root{min-height:100%}.artboard-body{height:100vh}.mono{font-family:var(--ff-mono);font-variant-ligatures:none;font-feature-settings:"zero"}.display{font-family:var(--ff-display);letter-spacing:-.01em;overflow-wrap:break-word;word-break:break-word;min-width:0;font-weight:400}.dim{color:var(--dim)}.muted{color:var(--muted)}.num{font-variant-numeric:tabular-nums}.accent{color:var(--accent)}@keyframes phase-dot-pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes tempo-strip-pulse{0%,to{opacity:1}50%{opacity:.6}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
|