@ola-893/agentpay-cli 0.0.0-stage → 0.2.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/LICENSE +23 -0
- package/README.md +54 -2
- package/artifacts/agentpay_vault.wasm +0 -0
- package/artifacts/manifest.json +6 -0
- package/bin/agentpay.mjs +7 -0
- package/package.json +11 -4
- package/src/agent.mjs +49 -0
- package/src/cli.mjs +195 -0
- package/src/config.mjs +75 -0
- package/src/files.mjs +28 -0
- package/src/install.mjs +64 -0
- package/src/mcp.mjs +38 -0
- package/src/settings.mjs +101 -0
- package/src/setup.mjs +73 -0
- package/src/ui.mjs +44 -0
- package/ui/agentpay.svg +1 -0
- package/ui/assets/index-D7tPv-yG.css +1 -0
- package/ui/assets/index-DBHTJ1PQ.js +331 -0
- package/ui/index.html +18 -0
- package/ui/near/sandbox.json +528 -0
- package/ui/near/testnet.json +481 -0
package/src/settings.mjs
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { resolve, join } from 'node:path';
|
|
2
|
+
import { mkdir, open, unlink } from 'node:fs/promises';
|
|
3
|
+
import { liveProfile } from './config.mjs';
|
|
4
|
+
import { atomicWrite, readOptional } from './files.mjs';
|
|
5
|
+
import { readConfig, readKey } from '@ola-893/agentpay-core/internal-config';
|
|
6
|
+
import { runtimePolicy, serviceConfig } from '@ola-893/agentpay-core/internal-runtime-policy';
|
|
7
|
+
import { inspectNearProfile, NearAgentPayClient } from '@ola-893/agentpay-core/near';
|
|
8
|
+
|
|
9
|
+
export function usdc(value) {
|
|
10
|
+
if (typeof value !== 'string' || !/^(0|[1-9][0-9]{0,24})(\.[0-9]{1,6})?$/.test(value)) throw new Error('Use a nonnegative USDC amount with at most six decimal places.');
|
|
11
|
+
const [whole, fraction = ''] = value.split('.');
|
|
12
|
+
return (BigInt(whole) * 1000000n + BigInt(fraction.padEnd(6, '0'))).toString();
|
|
13
|
+
}
|
|
14
|
+
export async function settings(project) {
|
|
15
|
+
const profile = await liveProfile(project);
|
|
16
|
+
return { profile, config: await readConfig(profile.configPath) };
|
|
17
|
+
}
|
|
18
|
+
export async function showSettings(project) {
|
|
19
|
+
const { profile, config } = await settings(project);
|
|
20
|
+
const { client, summary } = await inspectNearProfile(profile.configPath, profile.stateRoot);
|
|
21
|
+
return { network: config.network, vaultId: config.vaultId, agentId: config.agentId, recipientId: config.recipientId, paymentsEnabled: profile.paymentsEnabled,
|
|
22
|
+
financialPolicy: (await client.getVault()).policy, financialUnits: 'raw USDC (1 USDC = 1000000)', runtimePolicy: config.runtimePolicy,
|
|
23
|
+
service: { url: config.serviceUrl, ...config.service }, inference: profile.inference || null, ...summary };
|
|
24
|
+
}
|
|
25
|
+
export async function setRuntime(project, patch) {
|
|
26
|
+
if (!Object.keys(patch).length) throw new Error('Specify at least one runtime guardrail. See --help.');
|
|
27
|
+
const { profile, config } = await settings(project);
|
|
28
|
+
config.runtimePolicy = runtimePolicy({ ...config.runtimePolicy, ...patch });
|
|
29
|
+
await atomicWrite(profile.configPath, JSON.stringify(config, null, 2));
|
|
30
|
+
return { runtimePolicy: config.runtimePolicy, enforcement: 'local payment worker; thresholds reload on the next checkpoint', restartRequired: 'Restart running agents/MCP servers after changing reuse, polling or exit behavior.' };
|
|
31
|
+
}
|
|
32
|
+
export async function setService(project, patch) {
|
|
33
|
+
const { profile, config } = await settings(project);
|
|
34
|
+
const { summary, client } = await inspectNearProfile(profile.configPath, profile.stateRoot);
|
|
35
|
+
if (summary.activeSession || summary.pendingIntent || summary.executorBusyOrInterrupted) throw new Error('CLOSE_OR_RECONCILE_STREAM_BEFORE_SERVICE_CHANGE');
|
|
36
|
+
const { url, recipient, ...paths } = patch;
|
|
37
|
+
const next = { ...config, serviceUrl: url || config.serviceUrl, recipientId: recipient || config.recipientId, service: serviceConfig({ ...config.service, ...paths }) };
|
|
38
|
+
const temp = profile.configPath + '.candidate.json';
|
|
39
|
+
await atomicWrite(temp, JSON.stringify(next));
|
|
40
|
+
let validated;
|
|
41
|
+
try { validated = await readConfig(temp); } finally { await unlink(temp); }
|
|
42
|
+
if (!(await client.getVault()).policy.recipients.includes(validated.recipientId)) throw new Error('RECIPIENT_NOT_IN_ONCHAIN_POLICY');
|
|
43
|
+
await atomicWrite(profile.configPath, JSON.stringify(validated, null, 2));
|
|
44
|
+
return { service: { url: validated.serviceUrl, recipient: validated.recipientId, ...validated.service }, restartRequired: 'Restart running agents/MCP servers after service changes.' };
|
|
45
|
+
}
|
|
46
|
+
export function inferenceConfig(input) {
|
|
47
|
+
if (!input || typeof input.model !== 'string' || !input.model.trim() || input.model.length > 256) throw new Error('Provide --model.');
|
|
48
|
+
const url = new URL(input.baseUrl);
|
|
49
|
+
if (url.username || url.password || url.search || url.hash || !(url.protocol === 'https:' || (url.protocol === 'http:' && ['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname)))) throw new Error('Inference URL must use HTTPS or loopback without embedded credentials.');
|
|
50
|
+
if (input.apiKeyEnv && !/^[A-Z][A-Z0-9_]{0,127}$/.test(input.apiKeyEnv)) throw new Error('Provide an environment variable NAME via --api-key-env, never the key itself.');
|
|
51
|
+
const maxSteps = input.maxSteps ?? 12;
|
|
52
|
+
if (!Number.isInteger(maxSteps) || maxSteps < 1 || maxSteps > 100) throw new Error('maxSteps must be between 1 and 100.');
|
|
53
|
+
if (input.thinking !== undefined && typeof input.thinking !== 'boolean') throw new Error('thinking must be true or false.');
|
|
54
|
+
return { protocol: 'openai-chat', baseUrl: url.href.replace(/\/$/, ''), model: input.model, ...(input.apiKeyEnv ? { apiKeyEnv: input.apiKeyEnv } : {}), ...(input.thinking !== undefined ? { thinking: input.thinking } : {}), maxSteps };
|
|
55
|
+
}
|
|
56
|
+
export async function setInference(project, input) {
|
|
57
|
+
const profile = await liveProfile(project);
|
|
58
|
+
const inference = inferenceConfig(input);
|
|
59
|
+
const { file, configPath, stateRoot, ...saved } = profile;
|
|
60
|
+
await atomicWrite(file, JSON.stringify({ ...saved, inference }, null, 2));
|
|
61
|
+
return { inference, credentialsStored: false, next: 'agentpay agent run --prompt "Use the configured paid API to answer my question."' };
|
|
62
|
+
}
|
|
63
|
+
export async function setLimits(project, patch, ownerKeyFile) {
|
|
64
|
+
if (!ownerKeyFile) throw new Error('--owner-key is required for an on-chain policy change; it is never saved in the agent profile.');
|
|
65
|
+
if (!Object.keys(patch).length) throw new Error('Specify at least one financial limit.');
|
|
66
|
+
const { profile, config } = await settings(project);
|
|
67
|
+
const { client: reader, stateDir } = await inspectNearProfile(profile.configPath, profile.stateRoot);
|
|
68
|
+
const owner = await readKey(resolve(ownerKeyFile));
|
|
69
|
+
if (owner.accountId !== config.ownerId) throw new Error('OWNER_CREDENTIAL_MISMATCH');
|
|
70
|
+
const client = new NearAgentPayClient({ vaultId: config.vaultId, accountId: owner.accountId, privateKey: owner.privateKey, rpcUrl: config.rpcUrl });
|
|
71
|
+
await mkdir(stateDir, { recursive: true, mode: 0o700 });
|
|
72
|
+
const lock = await open(join(stateDir, 'operation.lock'), 'wx', 0o600);
|
|
73
|
+
try {
|
|
74
|
+
if (await readOptional(join(stateDir, 'pending.json'))) throw new Error('RECONCILIATION_REQUIRED');
|
|
75
|
+
const vault = await reader.getVault();
|
|
76
|
+
if (vault.active_session) throw new Error('CLOSE_STREAM_BEFORE_POLICY_CHANGE');
|
|
77
|
+
const policy = { ...vault.policy, ...patch };
|
|
78
|
+
if (BigInt(policy.budget) < BigInt(vault.spent) || BigInt(policy.max_deposit) <= 0n || BigInt(policy.max_deposit) > BigInt(policy.budget) || BigInt(policy.max_rate) <= 0n || !Number.isInteger(policy.max_duration_seconds) || policy.max_duration_seconds < 1 || policy.max_duration_seconds > 3600 || !policy.recipients.includes(config.recipientId) || policy.recipients.length > 32 || policy.recipients.some(id => !/^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/.test(id) || id.length < 2 || id.length > 64)) throw new Error('INVALID_FINANCIAL_POLICY');
|
|
79
|
+
const pending = join(stateDir, 'policy-pending.json');
|
|
80
|
+
const journal = await open(pending, 'wx', 0o600);
|
|
81
|
+
try { await journal.writeFile(JSON.stringify({ policy, vaultId: config.vaultId, nonceBefore: vault.next_nonce, createdAt: new Date().toISOString() })); await journal.sync(); } finally { await journal.close(); }
|
|
82
|
+
const receipt = await client.execute('configure', { policy });
|
|
83
|
+
await atomicWrite(join(stateDir, `policy-${receipt.hash}.receipt.json`), JSON.stringify(receipt));
|
|
84
|
+
const actual = (await reader.getVault()).policy;
|
|
85
|
+
if (JSON.stringify(actual) !== JSON.stringify(policy)) throw new Error('POLICY_RECONCILIATION_REQUIRED');
|
|
86
|
+
await unlink(pending);
|
|
87
|
+
return { financialPolicy: actual, units: 'raw USDC', transactionHash: receipt.hash, explorerUrl: `https://testnet.nearblocks.io/txns/${receipt.hash}` };
|
|
88
|
+
} finally { await lock.close(); await unlink(join(stateDir, 'operation.lock')); }
|
|
89
|
+
}
|
|
90
|
+
export async function reconcileLimits(project) {
|
|
91
|
+
const { profile } = await settings(project);
|
|
92
|
+
const { client, stateDir } = await inspectNearProfile(profile.configPath, profile.stateRoot);
|
|
93
|
+
const file = join(stateDir, 'policy-pending.json');
|
|
94
|
+
const text = await readOptional(file);
|
|
95
|
+
if (!text) return { resolved: true, reason: 'NO_PENDING_POLICY' };
|
|
96
|
+
const pending = JSON.parse(text), vault = await client.getVault(), actual = vault.policy;
|
|
97
|
+
if (JSON.stringify(actual) !== JSON.stringify(pending.policy) || pending.nonceBefore === undefined || BigInt(vault.next_nonce) <= BigInt(pending.nonceBefore)) return { resolved: false, reason: 'POLICY_OUTCOME_UNCONFIRMED' };
|
|
98
|
+
await atomicWrite(file.replace('.json', '.reconciled.json'), JSON.stringify({ ...pending, verifiedAt: new Date().toISOString() }));
|
|
99
|
+
await unlink(file);
|
|
100
|
+
return { resolved: true, financialPolicy: actual, receiptRecovered: false };
|
|
101
|
+
}
|
package/src/setup.mjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { mkdir, readFile, stat, open, unlink } from 'node:fs/promises';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { JsonRpcProvider } from 'near-api-js';
|
|
6
|
+
import { configHome, initProject, liveProfile } from './config.mjs';
|
|
7
|
+
import { atomicWrite, readOptional, safeTarget } from './files.mjs';
|
|
8
|
+
import { readKey, readConfig } from '@ola-893/agentpay-core/internal-config';
|
|
9
|
+
import { NearAgentPayClient } from '@ola-893/agentpay-core/near';
|
|
10
|
+
import { deployTestnet } from '@ola-893/agentpay-core/internal-deployment';
|
|
11
|
+
|
|
12
|
+
const setupId = project => createHash('sha256').update(project).digest('hex');
|
|
13
|
+
export const bundledWasm = fileURLToPath(new URL('../artifacts/agentpay_vault.wasm', import.meta.url));
|
|
14
|
+
export const publicRecording = fileURLToPath(new URL('../ui/near/testnet.json', import.meta.url));
|
|
15
|
+
|
|
16
|
+
export async function setupTestnet(project, options) {
|
|
17
|
+
if (!options.ownerId || !options.ownerKeyFile) return {
|
|
18
|
+
status: 'OWNER_SETUP_REQUIRED', network: 'testnet', signedTransactions: 0,
|
|
19
|
+
next: 'agentpay init --network testnet --owner-id YOUR.testnet --owner-key /absolute/path/owner.json',
|
|
20
|
+
steps: ['Create/export a named NEAR testnet owner account using your wallet or near-cli-rs. Keep its Ed25519 credential JSON private (0600).', 'Fund it with at least 6 test NEAR after storage reserve. The setup creates a vault and restricted agent; recipient defaults to the owner for the local fixture.', 'Run the command above for read-only preflight, then add --deploy to submit setup transactions. No deployment.json or Rust build is required.', 'After setup, use the Circle faucet (Near Testnet) for the printed owner address, then agentpay fund --amount 100000 --owner-key /absolute/path/owner.json.', 'Run Configure the service, inference and financial/runtime guardrails, then enable payments and run agentpay agent run --prompt "...".'],
|
|
21
|
+
nearAccounts: 'https://docs.near.org/tools/cli', usdcFaucet: 'https://faucet.circle.com/',
|
|
22
|
+
noSponsor: true,
|
|
23
|
+
};
|
|
24
|
+
const { deploymentPlan, inspectTestnet } = await import('@ola-893/agentpay-core/internal-preflight');
|
|
25
|
+
const key = await readKey(resolve(options.ownerKeyFile));
|
|
26
|
+
if (key.accountId !== options.ownerId) throw new Error('OWNER_CREDENTIAL_MISMATCH');
|
|
27
|
+
const plan = deploymentPlan({ ownerId: options.ownerId, recipientId: options.recipientId || options.ownerId, vaultLabel: options.vaultLabel, agentLabel: options.agentLabel, rpcUrl: options.rpcUrl, serviceUrl: options.serviceUrl });
|
|
28
|
+
const provider = new JsonRpcProvider({ url: plan.rpcUrl });
|
|
29
|
+
const preflight = await inspectTestnet(plan, { provider, readWasm: () => readFile(bundledWasm), ownerPublicKey: key.publicKey });
|
|
30
|
+
if (!options.deploy) return { ...preflight, next: preflight.readyToDeploy ? 'Repeat this init command with --deploy. Setup uses up to 6 test NEAR, installs owner-controlled vault/admin keys, and does not fund USDC or enable payments.' : 'Resolve the reported checks, then repeat init. No transaction was signed.' };
|
|
31
|
+
if (!preflight.readyToDeploy) throw new Error('TESTNET_PREFLIGHT_FAILED: ' + preflight.checks.filter(c => c.status !== 'pass').map(c => `${c.id}: ${c.detail}`).join('; '));
|
|
32
|
+
const home = configHome();
|
|
33
|
+
await mkdir(home, { recursive: true, mode: 0o700 });
|
|
34
|
+
if (((await stat(home)).mode & 0o077) !== 0) throw new Error('AGENTPAY_HOME must have permissions 0700.');
|
|
35
|
+
const directory = await safeTarget(home, join('setups', setupId(project)));
|
|
36
|
+
const configPath = join(directory, 'deployment.json');
|
|
37
|
+
if (await readOptional(await safeTarget(project, '.agentpay/config.json'))) throw new Error('PROJECT_ALREADY_INITIALIZED');
|
|
38
|
+
const result = await deployTestnet({ ...plan, ownerKeyFile: resolve(options.ownerKeyFile), vaultLabel: options.vaultLabel, agentLabel: options.agentLabel, directory, wasmFile: bundledWasm, onProgress: event => process.stderr.write(`NEAR setup ${event.step}: ${event.transactionHash}\n`) });
|
|
39
|
+
await initProject(project, { deployment: configPath });
|
|
40
|
+
return {
|
|
41
|
+
status: 'DEPLOYED', network: 'testnet', ownerId: result.config.ownerId, vaultId: result.config.vaultId, agentId: result.config.agentId, recipientId: result.config.recipientId,
|
|
42
|
+
paymentsEnabled: false, ownerUSDCFundingAddress: result.config.ownerId, usdcFaucet: 'https://faucet.circle.com/',
|
|
43
|
+
transactions: result.record.steps.map(s => ({ step: s.name, hash: s.hash, explorerUrl: `https://testnet.nearblocks.io/txns/${s.hash}` })),
|
|
44
|
+
privateSetupDirectory: directory, next: 'Get Circle test USDC for the owner (Near Testnet). Then agentpay fund --amount 100000 --owner-key /absolute/path/owner.json. Owner/admin setup credentials are kept separately from the runtime profile.',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function fundProject(project, { ownerKeyFile, amount }) {
|
|
49
|
+
if (!/^[1-9][0-9]{0,20}$/.test(amount ?? '') || BigInt(amount) > 100000n) throw new Error('Provide --amount in raw six-decimal USDC units, at most 100000 (0.1 test USDC) per funding call.');
|
|
50
|
+
if (!ownerKeyFile) throw new Error('--owner-key is required only for this explicit funding operation.');
|
|
51
|
+
const profile = await liveProfile(project);
|
|
52
|
+
const config = await readConfig(profile.configPath);
|
|
53
|
+
const owner = await readKey(resolve(ownerKeyFile));
|
|
54
|
+
if (owner.accountId !== config.ownerId) throw new Error('OWNER_CREDENTIAL_MISMATCH');
|
|
55
|
+
const provider = new JsonRpcProvider({ url: config.rpcUrl });
|
|
56
|
+
if ((await provider.viewNodeStatus()).chain_id !== 'testnet') throw new Error('RPC_NETWORK_MISMATCH');
|
|
57
|
+
const accessKey = await provider.viewAccessKey({ accountId: config.ownerId, publicKey: owner.publicKey, blockQuery: { finality: 'final' } });
|
|
58
|
+
if (accessKey.permission !== 'FullAccess') throw new Error('OWNER_FULL_ACCESS_REQUIRED');
|
|
59
|
+
const client = new NearAgentPayClient({ vaultId: config.vaultId, accountId: owner.accountId, privateKey: owner.privateKey, provider });
|
|
60
|
+
const vault = await client.getVault();
|
|
61
|
+
if (vault.owner_id !== owner.accountId || vault.token_id !== config.tokenId) throw new Error('VAULT_IDENTITY_MISMATCH');
|
|
62
|
+
if (BigInt(await client.tokenBalance(owner.accountId, config.tokenId)) < BigInt(amount)) throw new Error(`OWNER_USDC_INSUFFICIENT: request Near Testnet USDC at https://faucet.circle.com/ for ${owner.accountId}`);
|
|
63
|
+
const pending = join(configHome(), 'funding', createHash('sha256').update(config.vaultId).digest('hex') + '.json');
|
|
64
|
+
await mkdir(join(configHome(), 'funding'), { recursive: true, mode: 0o700 });
|
|
65
|
+
let journal;
|
|
66
|
+
try { journal = await open(pending, 'wx', 0o600); } catch (e) { if (e.code === 'EEXIST') throw new Error(`FUNDING_RECONCILIATION_REQUIRED: inspect ${pending}. No transaction was resubmitted.`); throw e; }
|
|
67
|
+
try { await journal.writeFile(JSON.stringify({ network: config.network, vaultId: config.vaultId, ownerId: owner.accountId, amount, createdAt: new Date().toISOString() })); await journal.sync(); } finally { await journal.close(); }
|
|
68
|
+
const receipt = await client.fund(amount);
|
|
69
|
+
await atomicWrite(pending.replace('.json', `-${receipt.hash}.receipt.json`), JSON.stringify(receipt));
|
|
70
|
+
if (receipt.receiptFailures.length || receipt.value !== amount) throw new Error(`FUNDING_NOT_CONFIRMED: ${receipt.hash}; inspect ${pending}.`);
|
|
71
|
+
await unlink(pending);
|
|
72
|
+
return { network: 'testnet', amountRawUSDC: amount, transactionHash: receipt.hash, explorerUrl: `https://testnet.nearblocks.io/txns/${receipt.hash}`, next: 'agentpay config show; configure service/inference and guardrails, then agentpay payments --enable and agentpay agent run --prompt "..."' };
|
|
73
|
+
}
|
package/src/ui.mjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { readFile, realpath } from 'node:fs/promises';
|
|
3
|
+
import { resolve, extname, sep } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
6
|
+
import { verifyRun } from '@ola-893/agentpay-core/internal-evidence-audit';
|
|
7
|
+
|
|
8
|
+
const uiRoot = fileURLToPath(new URL('../ui/', import.meta.url));
|
|
9
|
+
const mime = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.woff2': 'font/woff2', '.ico': 'image/x-icon' };
|
|
10
|
+
export async function startUi({ port = 0, recording = 'testnet' } = {}) {
|
|
11
|
+
if (!['testnet', 'sandbox'].includes(recording)) throw new Error('Choose --recording testnet or sandbox.');
|
|
12
|
+
const captured = JSON.parse(await readFile(resolve(uiRoot, 'near', `${recording}.json`), 'utf8'));
|
|
13
|
+
verifyRun(captured);
|
|
14
|
+
if (captured.network !== recording || captured.simulated) throw new Error('REPLAY_PROVENANCE_MISMATCH');
|
|
15
|
+
const server = createServer(async (req, res) => {
|
|
16
|
+
const send = (status, body, type = 'text/plain') => {
|
|
17
|
+
res.writeHead(status, { 'content-type': type, 'cache-control': 'no-store', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'referrer-policy': 'no-referrer' });
|
|
18
|
+
res.end(req.method === 'HEAD' ? undefined : body);
|
|
19
|
+
};
|
|
20
|
+
try {
|
|
21
|
+
if (!['GET', 'HEAD'].includes(req.method)) return send(405, 'Recorded viewer is read-only.');
|
|
22
|
+
if (![`127.0.0.1:${server.address().port}`, `localhost:${server.address().port}`].includes(req.headers.host)) return send(403, 'Host denied.');
|
|
23
|
+
const decoded = decodeURIComponent(req.url.split('?')[0]);
|
|
24
|
+
if (decoded.split('/').some(x => x === '..' || x.startsWith('.')) || decoded.includes('\\') || decoded.includes('\0')) return send(403, 'Path denied.');
|
|
25
|
+
if (decoded.startsWith('/api/') || decoded === '/api') return send(404, 'No signing API is exposed by this viewer.');
|
|
26
|
+
let path = ['/', '/docs'].includes(decoded) ? '/index.html' : decoded;
|
|
27
|
+
if (path === '/near/latest.json') path = `/near/${recording === 'sandbox' ? 'sandbox' : 'testnet'}.json`;
|
|
28
|
+
const file = await realpath(resolve(uiRoot, `.${path}`));
|
|
29
|
+
if (!file.startsWith(resolve(uiRoot) + sep)) return send(403, 'Path denied.');
|
|
30
|
+
let content = await readFile(file);
|
|
31
|
+
if (path === '/index.html') content = content.toString().replace('<head>', '<head><script>window.__AGENTPAY_RECORDED_ONLY__=true;</script>');
|
|
32
|
+
send(200, content, mime[extname(file)] || 'application/octet-stream');
|
|
33
|
+
} catch { send(404, 'Not found. Build the distribution before opening the viewer.'); }
|
|
34
|
+
});
|
|
35
|
+
await new Promise((done, reject) => { server.once('error', reject); server.listen(port, '127.0.0.1', done); });
|
|
36
|
+
return { server, url: `http://127.0.0.1:${server.address().port}`, close: () => new Promise(done => { server.closeAllConnections(); server.close(done); }) };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function openBrowser(url) {
|
|
40
|
+
const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'explorer.exe' : 'xdg-open';
|
|
41
|
+
const child = spawn(command, [url], { stdio: 'ignore', detached: true });
|
|
42
|
+
child.on('error', () => {});
|
|
43
|
+
child.unref();
|
|
44
|
+
}
|
package/ui/agentpay.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="16" fill="#375bd2"/><path d="M18 46 29 18h6l11 28h-8l-2-6H27l-2 6zm11-13h5l-2.5-8z" fill="white"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,ui-sans-serif,system-ui,Avenir,Helvetica,Arial,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,Fira Code,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}[type=text],input:where(:not([type])),[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow: 0 0 #0000}[type=text]:focus,input:where(:not([type])):focus,[type=email]:focus,[type=url]:focus,[type=password]:focus,[type=number]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=month]:focus,[type=search]:focus,[type=tel]:focus,[type=time]:focus,[type=week]:focus,[multiple]:focus,textarea:focus,select:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-top:0;padding-bottom:0}select{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:initial;background-position:initial;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;--tw-shadow: 0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset: var(--tw-empty, );--tw-ring-offset-width: 2px;--tw-ring-offset-color: #fff;--tw-ring-color: #2563eb;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}[type=checkbox]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")}@media (forced-colors: active){[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")}@media (forced-colors: active){[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:hover,[type=checkbox]:checked:focus,[type=radio]:checked:hover,[type=radio]:checked:focus{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:center;background-repeat:no-repeat}@media (forced-colors: active){[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:hover,[type=checkbox]:indeterminate:focus{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}html,body,#root{height:100%}body{--tw-bg-opacity: 1;background-color:rgb(11 15 26 / var(--tw-bg-opacity, 1));font-family:Inter,ui-sans-serif,system-ui,Avenir,Helvetica,Arial,sans-serif;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-image:radial-gradient(1200px 600px at 50% -10%,rgba(59,130,246,.12),transparent 60%),radial-gradient(1000px 600px at 90% 10%,rgba(55,91,210,.1),transparent 60%),radial-gradient(1000px 600px at 10% 10%,rgba(59,130,246,.08),transparent 60%)}::-webkit-scrollbar{width:.5rem}::-webkit-scrollbar-track{--tw-bg-opacity: 1;background-color:rgb(11 15 26 / var(--tw-bg-opacity, 1))}::-webkit-scrollbar-thumb{border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}::-webkit-scrollbar-thumb:hover{background-color:#1e293bcc}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.card-glass{border-radius:.75rem;border-width:1px;border-color:#ffffff1a;background-color:#ffffff0d;--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, .3), 0 2px 4px -2px rgba(0, 0, 0, .2);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.btn-primary{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:.5rem;background-image:linear-gradient(135deg,#3b82f6,#8b5cf6,#375bd2);padding:.625rem 1.25rem;font-weight:600;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1));--tw-shadow: 0 0 20px rgba(59, 130, 246, .35), 0 0 40px rgba(168, 85, 247, .25);--tw-shadow-colored: 0 0 20px var(--tw-shadow-color), 0 0 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn-primary:hover{opacity:.9;--tw-shadow: 0 0 20px rgba(59, 130, 246, .35), 0 0 40px rgba(168, 85, 247, .25);--tw-shadow-colored: 0 0 20px var(--tw-shadow-color), 0 0 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.btn-primary:active{--tw-scale-x: .98;--tw-scale-y: .98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn-outline{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:.5rem;border-width:1px;border-color:#fff3;background-color:transparent;padding:.5rem 1rem;font-weight:500;color:#ffffffe6;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.btn-outline:hover{border-color:#ffffff4d;background-color:#ffffff1a}.chip{border-radius:9999px;background-color:#ffffff1a;padding:.25rem .75rem;font-family:JetBrains Mono,Fira Code,monospace;font-size:.75rem;line-height:1rem;color:#ffffffb3}.panel{border-radius:1rem;border-width:1px;border-color:#ffffff1a;--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.eyebrow{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.16em;--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.page-title{font-size:1.875rem;line-height:2.25rem;font-weight:600;letter-spacing:-.025em;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.page-title{font-size:2.25rem;line-height:2.5rem}}.icon-button{display:inline-flex;height:2.75rem;min-width:2.75rem;align-items:center;justify-content:center;gap:.5rem;border-radius:.5rem;--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.icon-button:hover{background-color:#ffffff1a;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.btn-primary{min-height:2.75rem;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1));background-image:none;padding:.625rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:600;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.btn-primary:hover{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1));--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.btn-primary:active{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.btn-outline,.btn-default{min-height:2.75rem;font-size:.875rem;line-height:1.25rem;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.right-0{right:0}.top-full{top:100%}.z-10{z-index:10}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-9{margin-top:2.25rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-4{height:1rem}.h-8{height:2rem}.max-h-40{max-height:10rem}.min-h-11{min-height:2.75rem}.min-h-\[44px\]{min-height:44px}.min-h-\[50vh\]{min-height:50vh}.min-h-screen{min-height:100vh}.w-12{width:3rem}.w-4{width:1rem}.w-52{width:13rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[560px\]{min-width:560px}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.caption-top{caption-side:top}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.touch-manipulation{touch-action:manipulation}.list-decimal{list-style-type:decimal}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-7{gap:1.75rem}.gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.gap-y-2{row-gap:.5rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-9>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.25rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.break-words{overflow-wrap:break-word}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-agentpay-500\/20{border-color:#3b82f633}.border-error-500\/20{border-color:#ef444433}.border-transparent{border-color:transparent}.border-warning-500\/30{border-color:#f59e0b4d}.border-white\/10{border-color:#ffffff1a}.border-white\/20{border-color:#fff3}.border-t-agentpay-500{--tw-border-opacity: 1;border-top-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.bg-blue-500\/15{background-color:#3b82f626}.bg-error-500\/10{background-color:#ef44441a}.bg-slate-900,.bg-surface-800{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-white\/5{background-color:#ffffff0d}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pl-1{padding-left:.25rem}.pl-5{padding-left:1.25rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.align-top{vertical-align:top}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-relaxed{line-height:1.625}.text-blue-200{--tw-text-opacity: 1;color:rgb(191 219 254 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-error-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-warning-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/40{color:#fff6}.text-white\/50{color:#ffffff80}.text-white\/60{color:#fff9}.text-white\/80{color:#fffc}.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)}.touch-manipulation{touch-action:manipulation;-webkit-tap-highlight-color:transparent}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}:root{--color-primary: #3b82f6;--color-primary-hover: #2563eb;--color-accent: #375bd2;--color-accent-hover: #2a49b0;--color-success: #10b981;--color-warning: #f59e0b;--color-error: #ef4444;--color-surface-base: #0b0f1a;--color-surface-elevated: #0f172a;--color-surface-card: #1e293b;--color-surface-overlay: rgba(15, 23, 42, .8);--color-text-primary: #ffffff;--color-text-secondary: rgba(255, 255, 255, .7);--color-text-muted: rgba(255, 255, 255, .5);--color-border: rgba(255, 255, 255, .1);--color-border-hover: rgba(255, 255, 255, .2);--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 1.5rem;--spacing-xl: 2rem;--radius-sm: .5rem;--radius-md: .75rem;--radius-lg: 1rem;--radius-xl: 1.5rem;--radius-full: 9999px}@keyframes gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}.animated-border{position:relative;z-index:0}.animated-border:before{content:"";position:absolute;inset:-1px;z-index:-1;border-radius:inherit;background:linear-gradient(90deg,#3b82f6,#8b5cf6,#375bd2,#ec4899,#3b82f6);background-size:300% 100%;animation:gradient-shift 4s linear infinite;opacity:.7}.stream-active{position:relative;overflow:hidden}.stream-active:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(59,130,246,.15),transparent);animation:stream-flow 2s ease-in-out infinite}@keyframes shrink{0%{width:100%}to{width:0%}}@keyframes slide-up-toast{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.animate-slide-up-toast{animation:slide-up-toast .2s ease-out}@media (max-width: 640px){.btn-primary,.btn-secondary,.btn-default,.btn-outline,.btn-ghost,.btn-success,.btn-danger{min-height:44px;padding-left:1rem;padding-right:1rem}.input-default{min-height:44px;font-size:1rem;line-height:1.5rem}.card-glass,.card-solid,.card-elevated{padding:1rem}.btn-full-mobile{width:100%}}@media (min-width: 641px) and (max-width: 1024px){.card-glass,.card-solid,.card-elevated{padding:1.25rem}}.no-select{-webkit-user-select:none;-moz-user-select:none;user-select:none}html{scroll-behavior:smooth;-webkit-overflow-scrolling:touch}body{overscroll-behavior-y:none}:root{color-scheme:dark}body{background:#0b101c}main,section,article,aside{min-width:0}:where(a,button,input,select,textarea,summary):focus-visible{outline:2px solid #93c5fd;outline-offset:4px}:where(button,input,select,textarea):disabled{cursor:not-allowed;opacity:.45}button:not(:disabled),summary{touch-action:manipulation}::-moz-selection{background:#2563eb;color:#fff}::selection{background:#2563eb;color:#fff}.app-footer{padding-bottom:calc(6rem + env(safe-area-inset-bottom,0px))}.skip-link{position:fixed;top:.75rem;left:1rem;z-index:200;transform:translateY(-200%);padding:.75rem 1rem;border-radius:.5rem;background:#2563eb}.skip-link:focus{transform:translateY(0)}@media (min-width: 1024px){.app-footer{padding-bottom:2rem}}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}.app-header{position:sticky;top:0;z-index:40;border-bottom:1px solid #ffffff14;background:#0b101cf5}.app-header-inner{max-width:1200px;margin:auto;min-height:64px;padding:8px 16px;display:flex;align-items:center;gap:32px}.app-brand{display:flex;align-items:center;gap:8px;font-size:16px;font-weight:650}.app-brand>span{width:32px;height:32px;display:grid;place-items:center;border:1px solid #ffffff30;border-radius:8px}.app-header nav{display:flex;align-items:center;gap:24px;font-size:13px;color:#94a3b8}.app-header nav a{min-height:40px;display:inline-flex;align-items:center}.app-header nav a[aria-current=page]{color:#f1f5f9}.app-network{margin-left:auto;display:flex;gap:8px;font-size:10px;color:#94a3b8}.app-network span{border:1px solid #ffffff1a;border-radius:32px;padding:4px 8px}.app-main{width:100%;max-width:1200px;min-width:0;margin:auto;padding:24px 16px 32px;outline:none}.workflow-title{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:24px}.workflow-title h1{font-size:clamp(21px,2.1vw,28px);line-height:1.3;font-weight:600;letter-spacing:-.035em}.workflow-title p{font-size:13px;color:#94a3b8;margin-top:8px}.workflow-title>a{display:inline-flex;flex-shrink:0;align-items:center;gap:8px;font-size:12px;color:#94a3b8;min-height:40px}.wf-grid{display:grid;grid-template-columns:340px minmax(0,1fr);align-items:start;gap:24px}.wf-surface{border:1px solid #ffffff1a;border-radius:16px;background:#111827}.wf-controls{position:sticky;top:88px;padding:24px;min-width:0}.wf-agent-heading{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.wf-agent-heading h2{font-size:15px;font-weight:600}.wf-local-chip{color:#94a3b8;font-size:10px}.wf-address{display:flex;align-items:center;gap:4px;min-width:0;font-family:ui-monospace,monospace;font-size:12px;color:#cbd5e1}.wf-address>span{min-width:0;overflow-wrap:anywhere}.wf-address .wf-icon{flex-shrink:0}.wf-address-full{flex-wrap:wrap}.wf-address-full>span:first-child{flex-basis:100%;font-size:11px}.wf-icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;flex-shrink:0;border-radius:8px;color:#94a3b8}.wf-icon:hover:not(:disabled){background:#ffffff09;color:#f1f5f9}.wf-balances{display:flex;justify-content:space-between;gap:8px;font-size:13px;margin-top:8px;font-variant-numeric:tabular-nums;flex-wrap:wrap}.wf-balances small{color:#94a3b8;font-size:10px}.wf-balances>span:last-child{font-size:12px;color:#94a3b8}.wf-agent-details{margin:8px 0 16px;color:#94a3b8;font-size:11px}.wf-agent-details>summary{min-height:32px;display:list-item;align-content:center;cursor:pointer}.wf-agent-details>div{display:grid;gap:16px;padding-top:8px;overflow-wrap:anywhere}.wf-agent-details pre{max-width:100%;overflow:auto;font-size:10px}.wf-mode{display:flex;gap:0;border-bottom:1px solid #ffffff1a}.wf-mode>button{display:flex;align-items:center;justify-content:center;gap:8px;flex:1;min-height:40px;font-size:12px;color:#94a3b8;border-bottom:2px solid transparent}.wf-mode>button[aria-pressed=true]{border-color:#e2e8f0;color:#f1f5f9}.wf-runner-dot{width:8px;height:8px;border-radius:100%;background:#64748b}.wf-runner-dot.is-ready{background:#34d399}.wf-runner-dot.is-busy{background:#fbbf24}.wf-runner-dot.is-offline{background:#64748b}.wf-scenarios{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}.wf-scenarios>button{border:1px solid #ffffff1a;border-radius:32px;padding:8px 10px;min-height:32px;font-size:11px;color:#94a3b8}.wf-scenarios>button[aria-pressed=true]{color:#f8fafc;border-color:#ffffff80}.wf-scenarios>button:hover:not(:disabled){border-color:#ffffff70}.wf-capture-date{font-size:10px;color:#94a3b8;margin:16px 0}.wf-policy-used{padding:16px 0;border-top:1px solid #ffffff12}.wf-policy-used h3{display:flex;align-items:center;gap:8px;font-size:11px;color:#94a3b8}.wf-policy-used dl{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-top:16px}.wf-policy-used dt{font-size:10px;color:#94a3b8}.wf-policy-used dd{margin-top:4px;font-size:12px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.wf-run-button{width:100%;margin-top:8px}.wf-policy-heading{display:flex;justify-content:space-between;align-items:center;margin:8px 0;font-size:12px}.wf-field{display:block;font-size:11px;color:#94a3b8;margin-bottom:16px;min-width:0}.wf-field input{display:block;width:100%;min-width:0;padding:8px;margin-top:8px;height:40px;border:1px solid #ffffff26;border-radius:8px;background:transparent;font-size:13px;color:#f1f5f9}.wf-controls .wf-field input:disabled{opacity:1;color:#e2e8f0;-webkit-text-fill-color:#e2e8f0;cursor:wait}.wf-field-error{display:block;margin-top:6px;color:#fca5a5;font-size:11px}.wf-field-pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}.wf-advanced-policy{font-size:11px;color:#94a3b8}.wf-advanced-policy>summary{cursor:pointer;min-height:32px;align-content:center}.wf-advanced-policy[open]>summary{margin-bottom:16px}.wf-policy-form>.wf-mode{margin-top:16px}.wf-confirm{display:flex;gap:8px;font-size:11px;align-items:flex-start;margin-top:16px;color:#fcd34d}.wf-confirm input{margin-top:2px}.wf-reconnect{font-size:11px;color:#cbd5e1;min-height:40px;width:100%}.wf-offline{padding:16px 0;font-size:12px;color:#94a3b8}.wf-inline-actions{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:11px;margin-top:8px}.wf-inline-actions button{display:inline-flex;gap:8px;align-items:center;min-height:32px}.wf-main{min-width:0}.wf-diagram{position:relative;overflow:hidden}.wf-canvas{position:relative;height:480px}.wf-ghost .wf-input-edge,.wf-ghost .wf-supervision-edge,.wf-ghost .wf-reuse-edge{opacity:.45}.wf-inputs{position:absolute;top:24px;left:16px;right:16px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;z-index:2}.wf-inputs>span{display:flex;align-items:center;justify-content:center;gap:8px;min-height:32px;min-width:0;font-size:10px;color:#cbd5e1;text-align:center;padding:4px 8px;border:1px solid #64748b;border-radius:32px;background:#111827}.wf-inputs>span>svg{flex-shrink:0}.wf-input-pulse{animation:wf-input-flash .65s ease-out}.wf-desktop-diagram{height:100%;position:relative}.wf-connections{width:100%;height:100%;position:absolute;inset:0;overflow:visible}.wf-connections path:not(defs path){fill:none;stroke:#475569;stroke-width:1;vector-effect:non-scaling-stroke}.wf-connections .wf-supervision-edge{stroke:#5578db;stroke-dasharray:4 5;marker-end:url(#wf-arrow)}.wf-connections .wf-main-edge{stroke:#94a3b8;stroke-width:1.5;marker-end:url(#wf-arrow)}.wf-connections .wf-reuse-edge{stroke-dasharray:2 5}.wf-connections text{fill:#94a3b8;font-size:10px;text-anchor:middle}.wf-connections .wf-settlement-label{fill:#e2e8f0;font-size:10px}.wf-connections .wf-fund-label{fill:#e2e8f0;font-size:11px}.wf-hub{position:absolute;top:104px;left:50%;transform:translate(-50%);min-width:152px;min-height:64px;padding:8px 16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;border:1px solid #375bd280;border-radius:16px;background:#111827;z-index:3}.wf-hub>span:first-child{display:flex;align-items:center;gap:8px;color:#93b4ff;font-size:13px;font-weight:600}.wf-hub>small{color:#94a3b8;font-size:10px}.wf-hub.is-active{border-color:#6385ed;box-shadow:0 0 0 3px #375bd215}.wf-nodes{position:absolute;top:224px;left:0;right:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));align-items:start}.wf-node{display:flex;flex-direction:column;align-items:center;justify-content:start;gap:8px;min-height:144px;padding:8px;width:100%;max-width:176px;margin:auto;background:transparent;border-radius:16px;position:relative;z-index:2}.wf-node-tile{display:grid;place-items:center;width:80px;height:80px;flex-shrink:0;color:#cbd5e1;background:#111827;border:1px solid #64748b;border-radius:16px}.wf-node-copy{display:flex;flex-direction:column;align-items:center;gap:4px}.wf-node-caption{display:block;font-size:10px;color:#94a3b8;white-space:nowrap}.wf-node strong{font-size:12px;font-weight:500}.wf-node>svg{color:#94a3b8}.wf-node>small{color:#94a3b8;font-size:10px}.wf-node.is-active .wf-node-tile{border-color:#cbd5e1;box-shadow:0 0 0 2px #cbd5e115}.wf-node.is-outage .wf-node-tile{color:#fbbf24;border-color:#fbbf2480}.wf-call-count{position:absolute;bottom:24px;left:50%;transform:translate(-50%);font-size:11px;color:#cbd5e1;background:#111827;padding:4px 16px;border-radius:32px;white-space:nowrap}.wf-ghost .wf-call-count{left:24px;transform:none}.wf-diagram-hash{position:absolute;top:184px;left:16px;font-size:10px;color:#cbd5e1}.wf-gauge-wrap{width:100%;max-width:112px;min-width:0}.wf-gauge{display:flex;width:100%;height:4px;background:#334155;border-radius:4px;overflow:hidden}.wf-gauge>span{height:100%;background:#e2e8f0}.wf-gauge>.wf-refund-bar{background:#64748b}.wf-gauge-wrap>small{display:block;font-size:9px;color:#94a3b8;margin-top:4px;overflow-wrap:anywhere}.wf-idle-action{position:absolute;bottom:16px;left:50%;transform:translate(-50%);z-index:10;width:-moz-max-content;width:max-content;max-width:calc(100% - 32px)}.wf-idle-action>button{white-space:normal}.wf-trust{display:flex;flex-wrap:wrap;justify-content:center;gap:8px 16px;padding:16px;border-top:1px solid #ffffff12}.wf-trust>a{display:inline-flex;gap:4px;align-items:center;color:#94a3b8;font-size:10px;min-height:24px}.wf-trust>a:hover{color:#f1f5f9}.wf-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;border-radius:32px;font-size:10px;font-weight:500;white-space:nowrap;line-height:1.6}.wf-allow{background:#10b98115;color:#6ee7b7}.wf-deny{background:#ef444418;color:#fca5a5}.wf-warn{background:#f59e0b15;color:#fcd34d}.wf-neutral{color:#cbd5e1}.wf-playback{display:flex;justify-content:space-between;align-items:center;padding:8px 0;min-height:48px}.wf-playback>div{display:flex;gap:8px}.wf-playback-label{color:#94a3b8;font-size:11px}.wf-summary{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;margin-bottom:16px;font-size:11px;color:#cbd5e1;font-variant-numeric:tabular-nums;min-height:24px}.wf-scope{display:inline-flex;font-size:10px;color:#94a3b8;min-height:32px;align-items:center;margin-top:8px}.wf-error{padding:8px 0 16px;color:#fca5a5;font-size:12px;overflow-wrap:anywhere}.wf-timeline-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:16px;border-bottom:1px solid #ffffff12}.wf-timeline-heading h2{font-size:12px;font-weight:500}.wf-timeline-heading label{display:flex;gap:8px;align-items:center;font-size:10px;color:#94a3b8}.wf-timeline-feed{max-height:280px;overflow:auto;scroll-behavior:auto;overscroll-behavior:contain}.wf-empty{padding:24px 16px;color:#94a3b8;font-size:12px}.wf-event{border-bottom:1px solid #ffffff0d}.wf-event:last-child{border-bottom:0}.wf-event>summary{display:flex;align-items:center;gap:8px;cursor:pointer;padding:16px;min-height:48px;list-style:none;color:#cbd5e1}.wf-event>summary::-webkit-details-marker{display:none}.wf-event:hover>summary,.wf-event:focus-within>summary{background:#ffffff04}.wf-step-number{font-family:ui-monospace,monospace;font-size:10px;color:#94a3b8;min-width:16px}.wf-event>summary>svg{flex-shrink:0}.wf-event-title{font-size:12px;min-width:0}.wf-event-metric{margin-left:auto;font-size:10px;color:#94a3b8;text-align:right;overflow-wrap:anywhere}.wf-chevron{color:#64748b}.wf-event[open]>summary .wf-chevron{transform:rotate(180deg)}.wf-event-detail{padding:0 16px 16px;font-size:11px;color:#cbd5e1;overflow-wrap:anywhere}.wf-detail-meta{color:#94a3b8;margin-bottom:16px;font-size:10px}.wf-event-detail dl{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin:16px 0}.wf-event-detail dt{font-size:10px;color:#94a3b8}.wf-event-detail dd{margin-top:4px}.wf-command{display:flex;align-items:flex-start;gap:8px;padding:8px 0;font-size:11px}.wf-command code{white-space:pre-wrap;overflow-wrap:anywhere;min-width:0;flex:1}.wf-artifact-links{display:flex;gap:16px;flex-wrap:wrap;margin-top:8px}.wf-artifact-links a{min-height:32px;display:inline-flex;align-items:center}.wf-raw{margin-top:8px}.wf-raw>summary{min-height:32px;cursor:pointer}.wf-event-detail pre{max-width:100%;overflow:auto;font-size:10px;line-height:1.6;margin-top:8px;max-height:240px}.wf-packet{fill:#cbd5e1;animation:wf-packet .6s ease-out both}.wf-packet-approval{animation-name:wf-approval}.wf-packet-close{animation-direction:reverse}.wf-mobile-stepper{display:none}@keyframes wf-input-flash{0%{color:#93b4ff;border-color:#6385ed}to{color:#cbd5e1;border-color:#ffffff26}}@keyframes wf-packet{0%{transform:translate(0);opacity:1}to{transform:translate(200px);opacity:0}}@keyframes wf-approval{0%{opacity:1;r:4}to{opacity:0;r:10}}@media (max-width: 1023px){.wf-grid{grid-template-columns:1fr}.wf-controls{position:static}.wf-controls .wf-policy-used dl{grid-template-columns:repeat(4,minmax(0,1fr))}.wf-controls .wf-run-button{max-width:320px}}@media (max-width: 767px){.app-header-inner{flex-wrap:wrap;gap:0 24px;padding:8px 16px}.app-header nav{margin-left:auto;gap:16px}.app-network{flex-basis:100%;justify-content:flex-end;margin-top:8px}.app-main{padding-top:24px}.workflow-title{align-items:flex-start;gap:8px;flex-direction:column}.workflow-title h1{max-width:340px;font-size:23px}.workflow-title p{font-size:12px}.workflow-title>a{min-height:32px;font-size:11px}.wf-controls{padding:24px}.wf-controls .wf-policy-used dl{grid-template-columns:repeat(2,minmax(0,1fr))}.wf-controls .wf-run-button{max-width:none}.wf-canvas{height:auto;min-height:496px;padding-top:112px}.wf-ghost{padding-bottom:80px}.wf-inputs{grid-template-columns:repeat(2,minmax(0,1fr));top:16px;gap:8px 16px}.wf-desktop-diagram{display:none}.wf-mobile-stepper{display:block;padding:0 24px 24px}.wf-mobile-stepper .wf-hub{position:relative;top:auto;left:auto;transform:none;width:100%}.wf-mobile-stepper ol{margin-top:16px}.wf-mobile-stepper li{position:relative}.wf-mobile-edge{padding:0 0 8px 88px;font-size:11px;text-align:left;color:#cbd5e1}.wf-mobile-stepper li+li:before{content:"";position:absolute;left:36px;top:-16px;height:16px;border-left:1px dashed #64748b}.wf-mobile-stepper .wf-node{display:grid;grid-template-columns:72px minmax(0,1fr);align-items:center;gap:8px 16px;margin:0;width:100%;max-width:none;min-height:112px;background:transparent;padding:8px 0}.wf-mobile-stepper .wf-node-tile{width:72px;height:72px;grid-row:span 2}.wf-mobile-stepper .wf-node-copy{align-items:flex-start;text-align:left}.wf-mobile-stepper .wf-node-caption{white-space:normal}.wf-mobile-stepper .wf-node>svg{flex-shrink:0}.wf-mobile-stepper .wf-node strong{min-width:64px}.wf-mobile-stepper .wf-node .wf-badge{justify-self:start}.wf-mobile-stepper .wf-node>small{grid-column:2;text-align:left}.wf-mobile-stepper .wf-gauge-wrap{grid-column:2;max-width:144px;text-align:left}.wf-mobile-calls{display:block;text-align:center;font-size:12px;color:#cbd5e1;margin-top:16px}.wf-mobile-stepper>p{font-size:10px;text-align:center;color:#94a3b8;margin-top:8px}.wf-idle-action{bottom:16px}.wf-trust{justify-content:flex-start;padding:16px 24px;gap:8px}.wf-trust a{flex-basis:100%;min-height:24px}.wf-icon{width:40px;height:40px}.wf-scenarios>button{min-height:40px}.wf-event>summary{flex-wrap:wrap;padding:16px;gap:8px}.wf-event-title{font-size:11px}.wf-event-metric{flex-basis:100%;text-align:left;padding-left:40px}.wf-event>summary .wf-chevron{display:none}.wf-timeline-feed{max-height:400px}}@media (prefers-reduced-motion: reduce){.wf-input-pulse,.wf-packet{animation:none}.wf-packet{display:none}}.app-footer{padding-bottom:32px}.wf-local-chip{border:1px solid #ffffff1a;border-radius:32px;padding:2px 6px}.wf-trust>a{border:1px solid #ffffff1a;border-radius:32px;padding:4px 8px}.wf-recorded-scenarios{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.wf-recorded-scenarios>button{white-space:nowrap;padding-inline:8px}.wf-history{display:block;margin-top:12px;color:#cbd5e1;font-size:11px}.wf-history select{display:block;width:100%;min-width:0;margin-top:6px;min-height:38px;padding:6px 28px 6px 8px;background-color:#111827;border:1px solid #64748b;border-radius:8px;color:#e2e8f0;font-size:11px}.wf-authorization{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;border-top:1px solid #ffffff12;padding:12px 16px;list-style:none}.wf-authorization li{display:flex;gap:8px;align-items:flex-start;min-width:0}.wf-authorization li>span{display:grid;place-items:center;flex-shrink:0;width:20px;height:20px;border:1px solid #64748b;border-radius:100%;font-size:10px;color:#cbd5e1}.wf-authorization strong{display:block;color:#e2e8f0;font-size:11px;font-weight:500}.wf-authorization small{display:block;margin-top:4px;color:#94a3b8;font-size:10px;line-height:1.5}.wf-run-status{margin:0 0 12px;padding:12px 16px;border:1px solid #64748b;border-radius:10px;background:#111827;color:#cbd5e1;font-size:12px;line-height:1.5}.wf-run-status strong{color:#e2e8f0;font-weight:600}.wf-run-status p{margin:4px 0 0}.wf-run-status a{display:inline-block;margin-top:8px;color:#bfdbfe;text-decoration:underline;text-underline-offset:3px;overflow-wrap:anywhere}.wf-status-allow{border-color:#34d39966}.wf-status-allow strong{color:#6ee7b7}.wf-status-warn{border-color:#fbbf2466}.wf-status-warn strong{color:#fcd34d}@media (max-width: 600px){.wf-authorization{grid-template-columns:minmax(0,1fr);gap:12px;padding:16px 24px}}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-white\/60:hover{color:#fff9}@media (min-width: 640px){.sm\:flex-row{flex-direction:row}.sm\:p-5{padding:1.25rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width: 768px){.md\:h-16{height:4rem}.md\:w-16{width:4rem}.md\:p-8{padding:2rem}.md\:py-16{padding-top:4rem;padding-bottom:4rem}}@media (min-width: 1024px){.lg\:sticky{position:sticky}.lg\:top-28{top:7rem}.lg\:flex{display:flex}.lg\:grid-cols-\[210px_minmax\(0\,1fr\)\]{grid-template-columns:210px minmax(0,1fr)}.lg\:flex-col{flex-direction:column}.lg\:gap-12{gap:3rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}}.near-page{max-width:1240px;margin:0 auto;padding:38px 0 50px;color:#e8edf6}.near-kicker{font-size:10px;font-weight:700;letter-spacing:.16em;color:#8d9aa9}.near-heading{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;margin-bottom:34px}.near-heading h1{font-size:clamp(30px,3.5vw,48px);line-height:1.12;letter-spacing:-.045em;font-weight:600;margin:14px 0 16px}.near-heading h1 span{color:#8e9aa9}.near-heading p{max-width:590px;color:#9ca8b7;line-height:1.65;font-size:14px}.near-doc-link{display:flex;align-items:center;gap:10px;font-size:12px;color:#aab7c6;white-space:nowrap;padding-bottom:5px}.near-toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px;gap:15px}.near-tabs{display:flex;padding:4px;border:1px solid #27303d;border-radius:8px;background:#111722}.near-tabs button{font-size:12px;padding:9px 15px;border-radius:5px;color:#8794a5}.near-tabs button[aria-pressed=true]{background:#27313e;color:#eef3f9;box-shadow:0 1px 4px #0004}.near-tabs button:disabled{opacity:.4;cursor:not-allowed}.near-network{display:flex;gap:8px;align-items:center;font-size:11px;color:#b7c6ce}.near-network i,.near-status i{height:6px;width:6px;background:#9fedb2;border-radius:50%}.near-network>span{font-size:10px;color:#86919f;border:1px solid #313b47;border-radius:4px;padding:3px 6px;margin-left:8px}.near-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px}.near-panel{background:#111823;border:1px solid #29313e;border-radius:12px;overflow:hidden}.near-panel-top{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:25px 26px}.near-panel h2{font-size:19px;letter-spacing:-.025em;font-weight:500;margin-top:7px}.near-status{display:flex;align-items:center;gap:7px;border:1px solid #33463d;background:#182a22;color:#afe8bf;font-size:10px;padding:6px 9px;border-radius:30px;white-space:nowrap}.near-status.running{background:#202939;border-color:#3b4a65;color:#bfd2fb}.near-stages{display:flex;margin:20px 22px 34px;justify-content:space-between}.near-stage-wrap{display:flex;align-items:center;flex:1;min-width:0}.near-stage-wrap:last-child{flex:.8}.near-stage{display:flex;align-items:center;flex-direction:column;min-width:0;width:100%;text-align:center}.near-stage-icon{border:1px solid #35404e;background:#1d2733;display:grid;place-items:center;width:60px;height:60px;border-radius:15px;color:#7d8b9c;margin-bottom:14px}.near-stage.active .near-stage-icon{border-color:#466e59;background:#1b342a;color:#b0f0c3}.near-stage strong{font-size:12px;font-weight:500}.near-stage>span{font-size:10px;color:#8593a4;margin-top:5px;line-height:1.5;max-width:104px}.near-stage-arrow{color:#465264;flex:none;margin:0 8px 35px}.near-reuse{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin:0 25px 22px;border:1px solid #2b3543;border-radius:8px;background:#2b3543;overflow:hidden}.near-reuse>div{display:flex;flex-direction:column;align-items:center;padding:15px 8px;background:#151e2a}.near-big-number{font-size:31px;font-weight:500;letter-spacing:-.05em;color:#d6f5df}.near-reuse div>span:last-child{font-size:11px;color:#93a2b2;margin-top:3px}.near-controls{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 25px;border-top:1px solid #29313e;background:#0f151f;min-height:77px}.near-controls label{font-size:10px;color:#8c9cad;display:flex;gap:7px;flex-direction:column}.near-controls select{font-size:12px;background:#192330;color:#d6e0eb;border:1px solid #344252;border-radius:5px;padding:6px;max-width:250px}.near-controls p{font-size:10px;color:#8896a7;line-height:1.6}.near-run{display:flex;align-items:center;justify-content:center;gap:9px;background:#b0f2c2;color:#143320;border-radius:6px;font-size:12px;padding:12px 18px;font-weight:600;white-space:nowrap}.near-run:disabled{opacity:.45;cursor:not-allowed}.near-caption{padding:14px 25px;font-size:10px;color:#7f8e9e;line-height:1.65;border-top:1px solid #29313e}.near-recorded-label{font-size:10px;color:#a4b4c4;white-space:nowrap}.near-vault{padding:25px}.near-vault h2{font-size:18px}.near-vault-total{padding:30px 0 24px;display:flex;flex-direction:column;gap:4px}.near-vault-total>span{font-size:32px;font-weight:500;letter-spacing:-.04em}.near-vault-total small{font-size:11px;color:#8e9dad}.near-limits{border-top:1px solid #2a3441}.near-limits>div{display:flex;justify-content:space-between;gap:8px;font-size:10px;padding:13px 0;border-bottom:1px solid #27303c}.near-limits dt{color:#8493a4}.near-limits dd{white-space:nowrap;font-variant-numeric:tabular-nums}.near-guard{display:flex;gap:11px;align-items:center;padding:18px 0 0;color:#b4e9c2;font-size:11px}.near-guard small{display:block;font-size:9px;color:#839c8e;margin-top:4px}.near-details{font-size:11px;margin-top:18px;color:#97a8b9}.near-details summary{cursor:pointer;min-height:30px}.near-details dl{font-size:10px;line-height:1.8;padding:8px 0}.near-details dd{overflow-wrap:anywhere;color:#c0cedd;margin-bottom:9px}.near-details dt{color:#75889c}.near-results{display:grid;grid-template-columns:repeat(4,1fr);margin:18px 0;border:1px solid #29313e;border-radius:10px;background:#111823}.near-results>div{padding:20px 25px;border-right:1px solid #29313e;display:flex;flex-direction:column;gap:10px}.near-results>div:last-child{border:0}.near-results span{font-size:10px;color:#8b9aad}.near-results strong{font-size:24px;letter-spacing:-.03em;font-weight:500}.near-results small{font-size:10px;letter-spacing:0;color:#8193a8}.near-results .near-denied{color:#e3b88b;font-size:20px}.near-activity .near-panel-top>span{font-size:10px;color:#8a9aae}.near-activity ol{padding:0 26px 10px;max-height:470px;overflow:auto}.near-activity li{display:flex;gap:16px;align-items:flex-start;padding:14px 0;border-top:1px solid #27313e}.near-event-seq{width:24px;flex:none;font-size:10px;color:#6b8197;padding-top:3px}.near-activity li>div{min-width:0;flex:1}.near-activity strong{font-size:11px;font-weight:500;color:#c7d6e4}.near-activity li p{font-size:10px;color:#8c9fb1;margin-top:5px;overflow-wrap:anywhere;line-height:1.6}.near-activity time{font-size:9px;color:#647b92;padding-top:3px;white-space:nowrap}.near-activity .denied strong{color:#e3b88b}.near-activity>.near-details{margin:0;border-top:1px solid #29313e;padding:18px 26px}.near-receipts>div{display:flex;flex-direction:column;gap:7px;margin:16px 0}.near-receipts a{display:flex;gap:8px;overflow-wrap:anywhere}.near-receipts code{overflow-wrap:anywhere;color:#b1c5d8}.near-receipts small{color:#6f859a}.near-empty{padding:20px 26px 32px;color:#8b9aac;font-size:12px}.near-notice{padding:13px 18px;border:1px solid #65502f;background:#292316;border-radius:8px;color:#e2c897;font-size:12px;margin-bottom:18px}.near-spin{animation:near-spin 1s linear infinite}@keyframes near-spin{to{transform:rotate(360deg)}}.near-docs{max-width:820px}.near-docs h1{font-size:40px;line-height:1.15;font-weight:500;letter-spacing:-.04em;margin:15px 0 25px}.near-docs h2{font-size:22px;font-weight:500;margin:35px 0 15px}.near-docs p,.near-docs li{font-size:14px;line-height:1.8;color:#a3b2c3;margin:12px 0}.near-docs ol{list-style:decimal;padding-left:23px}.near-docs pre{background:#111823;border:1px solid #2b3644;border-radius:9px;padding:18px;color:#bbdfc7;font-size:12px;line-height:1.9;overflow:auto}.near-docs a{color:#b4eec4}.near-docs code{font-size:.9em}.near-page button:focus-visible,.near-page a:focus-visible,.near-page select:focus-visible,.near-page summary:focus-visible{outline:2px solid #b0f2c2;outline-offset:4px}@media (max-width: 960px){.near-grid{grid-template-columns:1fr}.near-vault{display:grid;grid-template-columns:1fr 1fr;gap:0 30px}.near-vault>.near-kicker,.near-vault>h2{grid-column:1}.near-vault-total{grid-column:1;grid-row:3}.near-limits{grid-column:2;grid-row:1/5}.near-guard{grid-column:1}.near-details{grid-column:1/-1}.near-heading{align-items:flex-start}.near-heading h1{font-size:36px}.near-heading p{max-width:550px}.near-doc-link{margin-top:30px}}@media (max-width: 600px){.near-page{padding-top:20px}.near-heading{display:block;margin-bottom:25px}.near-heading h1{font-size:32px}.near-heading p{font-size:12px}.near-doc-link{margin-top:18px}.near-toolbar{align-items:flex-start}.near-network{flex-wrap:wrap;justify-content:flex-end;max-width:140px;font-size:9px}.near-network>span{display:none}.near-tabs button{font-size:10px;padding:8px 10px}.near-panel-top{padding:20px}.near-panel h2{font-size:17px}.near-stages{margin:16px 8px 25px}.near-stage-icon{width:43px;height:43px;border-radius:11px}.near-stage strong{font-size:10px}.near-stage>span{font-size:8px;max-width:73px}.near-stage-arrow{width:12px;margin:0 2px 35px}.near-reuse{margin:0 16px 18px}.near-reuse div>span:last-child{font-size:9px}.near-controls{padding:16px;flex-wrap:wrap}.near-controls select{max-width:210px;font-size:10px}.near-recorded-label{display:none}.near-vault{display:block}.near-vault-total{padding:22px 0}.near-results{grid-template-columns:1fr 1fr}.near-results>div{padding:17px}.near-results>div:nth-child(2){border-right:0}.near-results>div:nth-child(-n+2){border-bottom:1px solid #29313e}.near-results strong{font-size:22px}.near-activity ol{padding:0 18px 10px}.near-activity time{display:none}.near-docs h1{font-size:32px}.near-docs p,.near-docs li{font-size:13px}}@media (prefers-reduced-motion: reduce){.near-spin{animation:none}}.ap-dashboard{--ap-border: #29343e;--ap-muted: #96a6b4;--ap-green: #b2edc7;--ap-surface: #111a23;--ap-bg: #0d141c;padding:28px 0 20px;color:#e8edf0;font-size:13px}.ap-dashboard button,.ap-drawer button{font:inherit;cursor:pointer}.ap-dashboard button:disabled{cursor:not-allowed;opacity:.42}.ap-eyebrow{display:flex;align-items:center;gap:7px;color:#97aaa5;font-size:10px;font-weight:650;letter-spacing:.13em}.ap-live-dot{width:5px;height:5px;border-radius:50%;background:#b2edc7}.ap-heading{display:flex;justify-content:space-between;align-items:center;gap:24px;margin-bottom:30px}.ap-heading h1{margin:13px 0 10px;font-size:clamp(28px,3vw,39px);line-height:1.2;letter-spacing:-.045em;font-weight:550}.ap-heading h1 span{color:#a1afa9}.ap-heading p{color:var(--ap-muted);font-size:13px;line-height:1.7}.ap-doc-link{display:flex;gap:7px;align-items:center;color:#d6dfdf;white-space:nowrap;font-size:12px;border-bottom:1px solid #5a6968;padding:7px 0}.ap-source-bar{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-bottom:20px}.ap-source-tabs{display:flex;gap:4px;background:#111a23;border:1px solid var(--ap-border);padding:4px;border-radius:8px}.ap-source-tabs button{display:flex;gap:7px;align-items:center;padding:8px 12px;border-radius:5px;font-size:11px;color:#93a3b2;min-height:35px}.ap-source-tabs button[aria-pressed=true]{background:#2a363e;color:#edf3f0;box-shadow:0 1px 3px #0003}.ap-source-info{display:flex;align-items:center;gap:13px;color:#8a9eaa;font-size:10px;text-align:right}.ap-network-label{color:#d1ddd7;padding:5px 8px;border:1px solid #3d4e49;border-radius:5px;white-space:nowrap}.ap-money{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border:1px solid var(--ap-border);border-radius:10px;background:var(--ap-surface);overflow:hidden}.ap-money-card{padding:20px 22px;min-width:0;border-right:1px solid var(--ap-border)}.ap-money-card:last-child{border:0}.ap-money-card>div{display:flex;justify-content:space-between;gap:8px;color:#a8b5bf;font-size:11px;align-items:center}.ap-money-card>div svg{color:#768f85;flex:none}.ap-money-card>strong{display:block;font-size:clamp(24px,2.6vw,34px);line-height:1.2;letter-spacing:-.045em;font-weight:500;font-variant-numeric:tabular-nums;margin:17px 0 2px;color:#ecf4ee}.ap-money-card>small{font-size:10px;color:#92a59a}.ap-money-card>p{font-size:10px;color:#a1afa8;margin:13px 0 0;line-height:1.5;overflow-wrap:anywhere}.ap-scope-note{font-size:10px;color:#8a9b9f;margin:10px 0 23px}.ap-workspace-grid{display:grid;grid-template-columns:minmax(0,1fr) 310px;gap:18px;align-items:start}.ap-panel{border:1px solid var(--ap-border);border-radius:10px;background:var(--ap-surface);min-width:0;overflow:hidden}.ap-panel-heading{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:24px}.ap-panel-heading h2{font-size:20px;font-weight:500;letter-spacing:-.035em;margin:7px 0 0;line-height:1.3}.ap-owner .ap-panel-heading{padding-bottom:12px}.ap-owner .ap-panel-heading h2{font-size:18px}.ap-owner .ap-panel-heading>svg{color:#9ab2a4;flex:none}.ap-badge{display:inline-flex;align-items:center;justify-content:center;gap:5px;width:-moz-fit-content;width:fit-content;font-size:9px;font-weight:550;letter-spacing:.035em;padding:5px 8px;border-radius:5px;border:1px solid #3d4d59;background:#1c2935;color:#bac9d7;white-space:nowrap;line-height:1.3}.ap-badge svg{flex:none}.ap-badge.ap-success{border-color:#38584b;color:#b7e7c8;background:#1c3029}.ap-badge.ap-warn{border-color:#6a5231;color:#f0c18c;background:#30291f}.ap-badge.ap-error{border-color:#774547;color:#f3b0b0;background:#342126}.ap-flow-canvas{background-image:radial-gradient(#93af9c22 .7px,transparent .7px);background-size:16px 16px;padding:30px 12px 19px;position:relative;border-block:1px solid #28343c;background-color:#0d161d}.ap-workflow-nodes{display:flex;position:relative;justify-content:space-between}.ap-node-wrap{display:flex;align-items:center;flex:1;min-width:0}.ap-node-wrap:last-child{flex:.84}.ap-node{width:100%;min-width:0;display:flex;align-items:center;flex-direction:column;text-align:center;border-radius:9px;padding:8px 2px}.ap-node:hover:not(:disabled){background:#b3e9c709}.ap-node-symbol{position:relative;display:grid;place-items:center;width:59px;height:59px;border:1px solid #3e4c55;background:#17242c;border-radius:13px;margin-bottom:14px;color:#8a9aa8;box-shadow:0 6px 20px #0002}.ap-node-observed .ap-node-symbol{color:#b2edc7;border-color:#4b6b5b;background:#1d322a}.ap-node-symbol>span{position:absolute;top:-7px;right:-6px;font-size:9px;background:#1c2c24;color:#b4d7c1;border:1px solid #476250;border-radius:4px;padding:2px 4px}.ap-node>strong{font-size:12px;font-weight:550;letter-spacing:-.01em}.ap-node-subtitle{font-size:10px;margin-top:4px;color:#94a7b3;line-height:1.5}.ap-node-tag{font-size:9px;color:#b4c5bc;margin-top:15px;line-height:1.5;min-height:28px;max-width:120px}.ap-flow-arrow{flex:none;color:#5a7869;margin:0 4px 72px}.ap-flow-legends{display:flex;justify-content:center;gap:22px;font-size:9px;color:#899f99;margin-top:17px}.ap-flow-legends>span{display:flex;align-items:center;gap:6px}.ap-flow-legends i{border:1px solid #84a092;border-radius:50%;width:7px;height:7px}.ap-reuse-strip{display:flex;gap:20px;align-items:center;padding:21px 24px;border-bottom:1px solid var(--ap-border)}.ap-reuse-strip>div{display:flex;flex-direction:column;gap:5px}.ap-reuse-strip strong{color:#c8edcf;font-size:26px;font-weight:500;letter-spacing:-.04em;font-variant-numeric:tabular-nums}.ap-reuse-strip div>span{font-size:10px;color:#96a9b2}.ap-reuse-divider{height:35px;border-left:1px solid #35443f}.ap-reuse-strip>button{display:flex;gap:6px;align-items:center;white-space:nowrap;margin-left:auto;font-size:10px;color:#c3d4ca}.ap-run-controls{min-height:84px;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 24px;background:#0e171e}.ap-run-mode{font-size:11px;color:#d4dfdb}.ap-run-controls p{font-size:10px;color:#8c9d9f;line-height:1.6;margin-top:5px}.ap-run-controls label{display:flex;flex-direction:column;gap:6px;font-size:10px;color:#a2b3ae}.ap-run-controls select{max-width:245px;background:#1b2931;border:1px solid #4e625c;color:#d6e4dc;font-size:11px;padding:7px 28px 7px 9px;border-radius:5px;min-height:34px}.ap-primary,.ap-secondary{display:inline-flex;align-items:center;justify-content:center;gap:8px;white-space:nowrap;border-radius:5px;min-height:38px;padding:9px 13px;font-size:11px}.ap-primary{color:#173323;background:#b2edc7;font-weight:650}.ap-secondary{color:#c3d3cd;border:1px solid #3b4c46}.ap-secondary:hover{background:#263c30}.ap-footnote{font-size:10px;color:#8b9da3;line-height:1.7;padding:13px 24px;border-top:1px solid var(--ap-border)}.ap-limit-list{padding:0 24px}.ap-field{min-width:0}.ap-limit-list .ap-field{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:14px 0;border-bottom:1px solid #2a383c;font-size:10px}.ap-limit-list dt{color:#a1b1b8}.ap-limit-list dd{color:#dce8df;white-space:nowrap;font-variant-numeric:tabular-nums}.ap-limit-list small{font-size:9px;color:#90a49b}.ap-owner-note{font-size:10px;line-height:1.7;color:#9cacaa;padding:13px 24px 17px}.ap-authority{margin:0 17px 17px;background:#182720;border:1px solid #354a3f;border-radius:7px;padding:13px}.ap-authority>div{display:flex;gap:8px;align-items:center;color:#bddfc8}.ap-authority strong{font-size:11px;font-weight:500}.ap-authority>p{display:flex;gap:6px;flex-wrap:wrap;margin:11px 0}.ap-authority code{font-size:9px;color:#c7dfcf;border:1px solid #3d5145;padding:3px 5px;border-radius:4px}.ap-authority small{font-size:9px;color:#9fb6a7;line-height:1.7;display:block}.ap-authority-details{border-top:1px solid var(--ap-border);padding:15px 24px;font-size:10px}.ap-authority-details summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;color:#bacdc2;min-height:22px}.ap-authority-details[open] summary>svg{transform:rotate(90deg)}.ap-authority-details>p{font-size:10px;line-height:1.7;color:#a9b9af;margin-top:10px}.ap-operational{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));background:#111a23;border:1px solid var(--ap-border);border-radius:8px;margin:18px 0}.ap-operational>div{display:flex;flex-direction:column;gap:6px;padding:16px 22px;border-right:1px solid var(--ap-border)}.ap-operational>div:last-child{border:0}.ap-operational span{font-size:10px;color:#92a6ad}.ap-operational strong{font-size:12px;font-weight:500;color:#c8d7d0}.ap-operational strong.ap-text-warn{color:#e5b985}.ap-operational small{font-size:9px;color:#91a39d}.ap-denial{width:100%;display:flex;gap:13px;align-items:center;padding:16px 20px;border:1px solid #5f513b;background:#221f1b;border-radius:8px;text-align:left;margin:0 0 25px;color:#e8cda7}.ap-denial:hover{background:#30291e}.ap-denial-icon{display:grid;place-items:center;width:32px;height:32px;border:1px solid #67563b;background:#31291d;border-radius:6px;flex:none}.ap-denial strong{display:flex;gap:12px;align-items:center;font-size:12px;font-weight:550}.ap-denial strong>span{font-size:9px;font-weight:400;color:#c4ab88}.ap-denial p{font-size:10px;line-height:1.65;margin-top:5px;color:#bda88c}.ap-denial-action{margin-left:auto;display:flex;align-items:center;gap:6px;font-size:10px;white-space:nowrap}.ap-history{margin-top:24px}.ap-event-count{font-size:10px;color:#90a7af}.ap-history-toolbar{display:flex;justify-content:space-between;gap:15px;padding:0 24px 18px;flex-wrap:wrap}.ap-history-tabs{display:flex;gap:5px}.ap-history-tabs>button{font-size:11px;color:#a4b4bb;display:flex;gap:8px;align-items:center;padding:7px 10px;border-radius:5px;min-height:33px}.ap-history-tabs>button[aria-pressed=true]{color:#d2e7d9;background:#23372c}.ap-history-tabs button>span{font-size:9px;background:#ffffff0b;border:1px solid #ffffff13;border-radius:4px;padding:1px 4px;color:#9eb3a5}.ap-history-search{display:flex;align-items:center;gap:8px;border:1px solid #364b45;border-radius:5px;background:#0f181e;min-height:34px;min-width:215px;padding:0 10px;color:#91a59b}.ap-history-search input{border:0;background:transparent;color:#d3e2da;outline:none;font-size:10px;width:100%;min-width:0}.ap-history-search:focus-within{outline:2px solid #b2edc7;outline-offset:3px}.ap-history-search input::-moz-placeholder{color:#91a39c}.ap-history-search input::placeholder{color:#91a39c}.ap-history-columns,.ap-history-row{display:grid;grid-template-columns:minmax(0,1fr) 115px 158px 103px 14px;align-items:center;gap:20px}.ap-history-columns{font-size:8px;letter-spacing:.08em;color:#8da29e;padding:12px 24px;background:#142029;border-block:1px solid #2b3b40}.ap-history-list{max-height:445px;overflow:auto;scrollbar-color:#4f6a5b #141e25;list-style:none}.ap-history-row{width:100%;padding:14px 24px;text-align:left;border-bottom:1px solid #2b393d;min-height:69px;transition:background .12s;color:#cbd8d2}.ap-history-row:hover,.ap-row-selected{background:#20322a}.ap-history-row:focus-visible{outline-offset:-3px!important}.ap-row-event{display:flex;gap:13px;align-items:flex-start;min-width:0}.ap-event-number{font-family:ui-monospace,monospace;font-size:9px;color:#7f9b8b;padding-top:2px;min-width:16px}.ap-row-event>span:last-child{min-width:0}.ap-row-event strong{font-size:11px;font-weight:500;display:block;color:#dce7e1}.ap-row-event small{font-size:10px;line-height:1.6;margin-top:4px;display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#91a5ad}.ap-row-session{font-size:9px;color:#91a6a0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.ap-history-row time{font-size:9px;font-variant-numeric:tabular-nums;color:#9cb1a6}.ap-row-arrow{color:#6c8c7c}.ap-history-footer{padding:13px 24px;display:flex;justify-content:space-between;gap:10px;font-size:9px;color:#8fa39b;border-top:1px solid #2b393d}.ap-dashboard-footer{display:flex;justify-content:space-between;gap:20px;font-size:10px;color:#8a9c99;padding:22px 2px;line-height:1.7}.ap-dashboard-footer a{display:flex;gap:6px;align-items:center;color:#bdcec3}.ap-notice{display:flex;align-items:flex-start;gap:12px;border:1px solid #6d5632;background:#282218;color:#e6c99a;padding:15px 18px;margin-bottom:18px;border-radius:7px}.ap-notice>svg{flex:none;margin-top:2px}.ap-notice strong{font-size:12px;font-weight:550}.ap-notice p{font-size:11px;line-height:1.7;margin-top:5px}.ap-notice>button{margin-left:auto;text-decoration:underline;font-size:11px;min-height:30px}.ap-empty{padding:45px 24px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;color:#91a99c}.ap-empty strong{font-size:14px;color:#c9dcd1;font-weight:500}.ap-empty p{font-size:12px;line-height:1.6;max-width:400px}.ap-empty button{color:#c1eccd;font-size:12px;text-decoration:underline;padding:8px}.ap-drawer{position:fixed;inset:0 0 0 auto;margin:0;width:min(510px,100%);max-width:100vw;height:100dvh;max-height:100dvh;background:#111b23;color:#dbe5df;border:0;border-left:1px solid #42554a;padding:0;box-shadow:-18px 0 80px #0005;font-size:12px}.ap-drawer::backdrop{background:#030b10aa;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.ap-drawer-inner{height:100%;display:flex;flex-direction:column}.ap-drawer-header{padding:26px;display:flex;align-items:flex-start;justify-content:space-between;gap:18px;border-bottom:1px solid #33443c;background:#14221c}.ap-drawer-header h2{font-size:23px;font-weight:500;letter-spacing:-.035em;line-height:1.3;margin-top:10px}.ap-icon-button{padding:6px;border:1px solid #4f6658;border-radius:5px;color:#c8dbcf;min-width:34px;min-height:34px;display:grid;place-items:center}.ap-icon-button:hover{background:#294534}.ap-drawer-body{overflow:auto;padding:25px;flex:1}.ap-drawer .ap-badge{font-size:10px}.ap-evidence-description{font-size:15px;line-height:1.65;color:#c4d6ca;margin:17px 0 24px;overflow-wrap:anywhere}.ap-metadata{display:flex;flex-direction:column;gap:16px;margin:17px 0}.ap-metadata dt{font-size:10px;color:#91aa9d;margin-bottom:5px}.ap-metadata dd{font-size:11px;color:#d2e2d7;line-height:1.65;overflow-wrap:anywhere}.ap-metadata code{font-size:10px;overflow-wrap:anywhere}.ap-metadata a{display:inline;line-height:1.8;color:#bee9cd;overflow-wrap:anywhere}.ap-metadata a svg{display:inline;margin-left:5px}.ap-evidence-section{border-top:1px solid #34443b;padding-top:23px;margin-top:24px}.ap-evidence-section h3{font-size:13px;font-weight:550;color:#e1ece4;margin:0 0 10px}.ap-evidence-section>p{font-size:11px;color:#a2b7ab;line-height:1.8;margin:8px 0}.ap-evidence-section>a{color:#bee9cd;display:flex;align-items:center;gap:8px;font-size:11px;line-height:1.6;margin-top:10px}.ap-comparisons{margin:18px 0;border:1px solid #3b5143;border-radius:6px;overflow:hidden}.ap-comparison{display:grid;grid-template-columns:70px 1fr 1fr;gap:10px;padding:12px 10px;background:#182920;border-top:1px solid #364a3d;font-size:10px;font-variant-numeric:tabular-nums;line-height:1.7}.ap-comparison-heading{border:0;color:#9eb4a5;background:#203228;font-size:9px}.ap-comparison strong{font-weight:500}.ap-comparison-failed{background:#342a1d;color:#ebc99e}.ap-evidence-section>p.ap-explanation{border-left:2px solid #58745f;padding-left:12px;margin:16px 0}.ap-drawer pre{overflow:auto;max-height:420px;background:#0b1419;border:1px solid #33453b;border-radius:5px;padding:14px;font-size:10px;line-height:1.8;color:#c5d9cd;-moz-tab-size:2;-o-tab-size:2;tab-size:2}.ap-raw{margin-top:24px;border-top:1px solid #34483b;padding-top:18px}.ap-raw summary{display:flex;gap:7px;align-items:center;cursor:pointer;color:#c6dbce;font-size:11px;min-height:30px;list-style:revert}.ap-raw pre{margin-top:12px}.ap-journal-hash{display:flex;flex-direction:column;gap:9px;font-size:10px;color:#9bb1a2;margin-top:25px}.ap-journal-hash code{overflow-wrap:anywhere;color:#c1d8c7;line-height:1.8;font-size:9px}.ap-journal-hash small{font-size:9px;line-height:1.8;color:#8fa698}.ap-evidence-section>p.ap-model-text{white-space:pre-wrap}.ap-drawer :is(button,a,summary):focus-visible{outline:2px solid #b2edc7;outline-offset:4px}@media (min-width: 1500px){.ap-dashboard{padding-top:40px}.ap-flow-canvas{padding-top:38px;padding-bottom:24px}.ap-node-symbol{width:65px;height:65px}}@media (max-width: 1050px){.ap-workspace-grid{grid-template-columns:minmax(0,1fr) 280px;gap:14px}.ap-panel-heading{padding:20px}.ap-panel-heading h2{font-size:18px}.ap-node-subtitle{font-size:9px}.ap-node-tag{font-size:8px}.ap-node-symbol{width:50px;height:50px}.ap-reuse-strip{padding:20px;gap:15px}.ap-reuse-strip>button{font-size:9px}.ap-history-columns,.ap-history-row{grid-template-columns:minmax(0,1fr) 105px 130px 86px 12px;gap:15px}.ap-source-info{flex-direction:column;gap:6px;align-items:flex-end}.ap-money-card{padding:19px}.ap-run-controls{padding:16px 20px;flex-wrap:wrap}.ap-footnote{padding:13px 20px}}@media (max-width: 850px){.ap-workspace-grid{grid-template-columns:1fr}.ap-owner .ap-panel-heading{padding-bottom:6px}.ap-limit-list{display:grid;grid-template-columns:1fr 1fr;gap:0 28px}.ap-owner .ap-owner-note{padding-bottom:14px}.ap-authority{margin:0 24px 20px}.ap-source-info{flex-direction:row;align-items:center}.ap-money-card{padding:18px 15px}.ap-money-card>div{font-size:10px}.ap-money-card>strong{font-size:26px}.ap-history-columns,.ap-history-row{grid-template-columns:minmax(0,1fr) 105px 105px 80px 12px;gap:12px}.ap-row-session{font-size:8px}}@media (max-width: 620px){.ap-dashboard{padding-top:16px}.ap-heading{align-items:flex-start;gap:12px;margin-bottom:24px}.ap-heading h1{font-size:30px;max-width:300px}.ap-heading h1 span{display:block}.ap-heading p{font-size:12px;max-width:290px}.ap-eyebrow{font-size:8px}.ap-doc-link{font-size:10px;margin-top:27px;gap:4px}.ap-source-bar{align-items:flex-start;gap:12px}.ap-source-tabs{flex:none;padding:3px}.ap-source-tabs button{font-size:10px;padding:7px 8px;gap:5px;min-height:34px}.ap-source-info{flex-direction:column;align-items:flex-end;gap:7px;font-size:8px;line-height:1.5}.ap-network-label{font-size:8px}.ap-money{grid-template-columns:1fr 1fr}.ap-money-card{padding:17px}.ap-money-card:nth-child(2){border-right:0}.ap-money-card:nth-child(-n+2){border-bottom:1px solid var(--ap-border)}.ap-money-card>strong{font-size:29px;margin-top:14px}.ap-money-card>p{font-size:9px;margin-top:10px}.ap-scope-note{font-size:9px;line-height:1.7;margin-bottom:18px}.ap-panel-heading{padding:20px 16px}.ap-panel-heading h2{font-size:18px}.ap-panel-heading .ap-badge{font-size:8px;padding:5px 6px}.ap-node-symbol{width:44px;height:44px;border-radius:10px}.ap-node-symbol>svg{width:21px}.ap-node-symbol>span{font-size:7px}.ap-node>strong{font-size:10px}.ap-node-subtitle{font-size:8px;max-width:69px;min-height:24px}.ap-node-tag{max-width:77px;min-height:30px;margin-top:11px;font-size:8px}.ap-flow-canvas{padding:21px 6px 17px}.ap-flow-arrow{width:12px;margin:0 1px 78px}.ap-flow-legends{gap:12px;font-size:8px;margin-top:10px;flex-wrap:wrap}.ap-reuse-strip{padding:17px 16px;gap:17px;flex-wrap:wrap}.ap-reuse-strip strong{font-size:25px}.ap-reuse-strip div>span{font-size:9px}.ap-reuse-strip>button{margin-left:0;width:100%;justify-content:flex-end;min-height:20px}.ap-reuse-strip>div{flex:1}.ap-reuse-divider{height:34px}.ap-run-controls{padding:16px;gap:14px}.ap-run-controls>div{min-width:0}.ap-run-controls p{font-size:9px;max-width:200px}.ap-secondary{padding:9px;font-size:9px}.ap-run-controls select{max-width:190px;font-size:10px}.ap-primary{padding:9px 12px;font-size:10px}.ap-footnote{padding:12px 16px;font-size:9px}.ap-limit-list{padding:0 18px;gap:0 18px}.ap-limit-list .ap-field{flex-direction:column;gap:7px;align-items:flex-start;font-size:10px}.ap-owner-note{padding:13px 18px}.ap-authority{margin:0 18px 16px}.ap-authority-details{padding:14px 18px}.ap-operational{grid-template-columns:1fr;margin:14px 0}.ap-operational>div{display:grid;grid-template-columns:1fr 1fr;padding:13px 16px;border-right:0;border-bottom:1px solid var(--ap-border);gap:5px 10px}.ap-operational strong{font-size:10px;text-align:right}.ap-operational span{font-size:9px}.ap-operational small{font-size:8px;grid-column:1/-1}.ap-denial{padding:14px;gap:10px;flex-wrap:wrap}.ap-denial strong{font-size:11px;flex-wrap:wrap;gap:5px}.ap-denial>div{flex:1}.ap-denial p{font-size:9px}.ap-denial-action{font-size:9px;width:100%;justify-content:flex-end;margin-top:2px}.ap-history{margin-top:18px}.ap-event-count{font-size:9px;max-width:90px;text-align:right;line-height:1.6}.ap-history-toolbar{padding:0 16px 15px;gap:14px}.ap-history-tabs{width:100%;gap:3px}.ap-history-tabs>button{font-size:10px;padding:8px 9px;gap:7px}.ap-history-search{width:100%;min-height:37px}.ap-history-columns{grid-template-columns:minmax(0,1fr) 99px;gap:8px;padding:12px 16px;font-size:8px}.ap-history-columns>span:nth-child(n+3){display:none}.ap-history-row{grid-template-columns:minmax(0,1fr) 99px;gap:6px 8px;padding:14px 16px;min-height:80px}.ap-row-event{gap:10px}.ap-row-event strong{font-size:10px}.ap-row-event small{font-size:9px}.ap-history-row>.ap-badge{justify-self:end;font-size:8px;padding:5px}.ap-row-session,.ap-row-arrow{display:none}.ap-history-row>time{grid-column:2;font-size:8px;text-align:right}.ap-history-list{max-height:425px}.ap-history-footer{padding:13px 16px;font-size:8px;line-height:1.6}.ap-dashboard-footer{font-size:9px;flex-wrap:wrap;gap:9px;padding:20px 0}.ap-drawer-header{padding:22px 20px}.ap-drawer-header h2{font-size:23px}.ap-drawer-body{padding:22px 20px}.ap-comparison{grid-template-columns:58px 1fr 1fr;font-size:9px;gap:7px;padding:11px 8px}.ap-evidence-description{font-size:14px}.ap-notice{padding:14px;font-size:10px}}@media (prefers-reduced-motion: reduce){.ap-history-row{transition:none}}
|