@vincemakes/kiso-web 0.53.0 → 0.54.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/dist/main/agent.js +6 -3
- package/dist/main/approvals.js +15 -3
- package/dist/main/artifacts.js +3 -0
- package/dist/main/desk-api.js +59 -4
- package/dist/main/environment.js +102 -0
- package/dist/main/folder-info.js +18 -1
- package/dist/main/fs-routes.js +22 -5
- package/dist/main/git.js +1 -1
- package/dist/main/history.js +0 -13
- package/dist/main/host.js +19 -2
- package/dist/main/pick-folder.js +41 -0
- package/dist/main/prs.js +37 -0
- package/dist/main/settings.js +14 -7
- package/dist/main/space.js +66 -15
- package/dist/main/times.js +19 -0
- package/dist/main/usage.js +15 -4
- package/dist/main/work-folders.js +28 -0
- package/dist/main/works.js +1 -1
- package/out/renderer/assets/index-CSaqocLC.css +1 -0
- package/out/renderer/assets/index-Dt9YIp7q.js +46 -0
- package/out/renderer/icon.png +0 -0
- package/out/renderer/index.html +2 -2
- package/package.json +10 -10
- package/out/renderer/assets/index-C3fCoBdq.css +0 -1
- package/out/renderer/assets/index-DiDTmq9b.js +0 -45
package/dist/main/space.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { realpathSync } from "node:fs";
|
|
2
|
-
import { SessionStore } from "@vincemakes/kiso-runtime";
|
|
2
|
+
import { isEnvironmentNote, SessionStore } from "@vincemakes/kiso-runtime";
|
|
3
3
|
import { named, titleIfUnnamed } from "./names.js";
|
|
4
4
|
import { createSessionService, toWireEvent } from "@vincemakes/kiso-server";
|
|
5
5
|
import { createHttpHandler } from "@vincemakes/kiso-server/http";
|
|
@@ -7,7 +7,7 @@ import { createWebAgent, routeOf } from "./agent.js";
|
|
|
7
7
|
import { createTaskHub, rowsOf } from "./tasks.js";
|
|
8
8
|
import { runRate, runTotals, usageFrameAt } from "./usage.js";
|
|
9
9
|
import { webSanitize } from "./sanitize.js";
|
|
10
|
-
import { TimeIndex } from "./times.js";
|
|
10
|
+
import { StampCache, TimeIndex } from "./times.js";
|
|
11
11
|
import { artifactsOf, LogImages } from "./artifacts.js";
|
|
12
12
|
const HEAD_LINES = 12;
|
|
13
13
|
const DELTAS = new Set(["thinking", "text_delta"]);
|
|
@@ -30,6 +30,31 @@ export function createSpace(options) {
|
|
|
30
30
|
// own name wins, before or after, and a failure leaves the first request's title. A first message sent in the last
|
|
31
31
|
// minute, not "a run is live": a quick run can end before its first event is seen here, and a replayed old one is old
|
|
32
32
|
const titled = new Set();
|
|
33
|
+
// What is decided from the log and the name file, not from memory: a Work with no name and a first request is asked for a title whenever
|
|
34
|
+
// a run of it settles (no page needs to be watching), and when it is opened (a host that restarted since the first ask). A host life
|
|
35
|
+
// asks at most twice for a Work: the first time, and once more after a failure (a provider timeout, a refusal), so a Work whose only
|
|
36
|
+
// ask failed is not left with its first request as its name for good.
|
|
37
|
+
const tries = new Map();
|
|
38
|
+
const firstText = (sessionId) => {
|
|
39
|
+
const first = store.load(sessionId).map((r) => r.event).find((e) => e.type === "user_input");
|
|
40
|
+
if (first === undefined || first.type !== "user_input")
|
|
41
|
+
return "";
|
|
42
|
+
const parts = typeof first.content === "string" ? [first.content] : first.content.map((b) => (b.type === "text" ? b.text : ""));
|
|
43
|
+
return parts.filter((p) => !isEnvironmentNote(p) && !p.startsWith("This session was forked from the session ")).join(" ").trim(); // the one note filter is the runtime's
|
|
44
|
+
};
|
|
45
|
+
const ensureTitle = (sessionId) => {
|
|
46
|
+
const text = options.titles === true && (tries.get(sessionId) ?? 0) < 2 && !named(options.dir, sessionId) && !service.isRunning(sessionId) ? firstText(sessionId) : "";
|
|
47
|
+
if (text !== "")
|
|
48
|
+
ask(sessionId, text);
|
|
49
|
+
};
|
|
50
|
+
const ask = (sessionId, text) => {
|
|
51
|
+
const session = sessions.get(sessionId);
|
|
52
|
+
if (session === undefined)
|
|
53
|
+
return;
|
|
54
|
+
tries.set(sessionId, (tries.get(sessionId) ?? 0) + 1);
|
|
55
|
+
const failed = () => ensureTitle(sessionId);
|
|
56
|
+
void session.title(text, { signal: AbortSignal.timeout(15_000) }).then((name) => (name === "" ? failed() : titleIfUnnamed(options.dir, sessionId, name)), failed);
|
|
57
|
+
};
|
|
33
58
|
const title = (sessionId, event) => {
|
|
34
59
|
const session = sessions.get(sessionId);
|
|
35
60
|
if (options.titles !== true || session === undefined || titled.has(sessionId) || Date.now() - times.at(sessionId, event.seq) > 60_000)
|
|
@@ -37,21 +62,34 @@ export function createSpace(options) {
|
|
|
37
62
|
if (service.events(sessionId).some((e) => e.type === "user_input" && e.seq < event.seq) || named(options.dir, sessionId))
|
|
38
63
|
return;
|
|
39
64
|
titled.add(sessionId);
|
|
40
|
-
const text = typeof event.content === "string" ? event.content : event.content.map((b) => (b.type === "text" ? b.text : "")).join(" ");
|
|
41
|
-
|
|
65
|
+
const text = typeof event.content === "string" ? event.content : event.content.map((b) => (b.type === "text" && !isEnvironmentNote(b.text) ? b.text : "")).join(" ").trim();
|
|
66
|
+
ask(sessionId, text);
|
|
42
67
|
};
|
|
43
68
|
const followUp = (sessionId, seq) => {
|
|
44
69
|
const session = sessions.get(sessionId);
|
|
45
70
|
const end = [...service.events(sessionId)].reverse().find((e) => e.type === "terminal");
|
|
46
71
|
if (options.followUps !== true || session === undefined || service.isRunning(sessionId) || end?.seq !== seq || end.outcome.kind !== "completed")
|
|
47
72
|
return Promise.resolve("");
|
|
73
|
+
// work still going in the background: the run is not the end of it, so no "next message" is guessed
|
|
74
|
+
if (tasks.managerFor(sessionId).list().some((t) => t.endedAt === undefined))
|
|
75
|
+
return Promise.resolve("");
|
|
48
76
|
const at = `${sessionId}:${seq}`;
|
|
49
|
-
if (!followUps.has(at))
|
|
50
|
-
|
|
77
|
+
if (!followUps.has(at)) {
|
|
78
|
+
// as the terminal does: a slow suggestion is no suggestion; and only the latest ones are kept
|
|
79
|
+
followUps.set(at, session.followUp({ maxTokens: 200, signal: AbortSignal.timeout(15_000) }).catch(() => ""));
|
|
80
|
+
for (const old of [...followUps.keys()].slice(0, -200))
|
|
81
|
+
followUps.delete(old);
|
|
82
|
+
}
|
|
51
83
|
return followUps.get(at);
|
|
52
84
|
};
|
|
53
85
|
const service = createSessionService({
|
|
54
86
|
store,
|
|
87
|
+
hooks: {
|
|
88
|
+
onSettled: (s) => {
|
|
89
|
+
options.onSettled?.(s.sessionId, s.runId, store);
|
|
90
|
+
setTimeout(() => ensureTitle(s.sessionId), 0); // after the run has let go of the Work
|
|
91
|
+
},
|
|
92
|
+
},
|
|
55
93
|
open: async (sessionId) => {
|
|
56
94
|
opened.add(sessionId);
|
|
57
95
|
return createWebAgent({
|
|
@@ -66,6 +104,7 @@ export function createSpace(options) {
|
|
|
66
104
|
...(options.toolLimits !== undefined ? { toolLimits: options.toolLimits } : {}),
|
|
67
105
|
onSession: (sessionId, session) => {
|
|
68
106
|
sessions.set(sessionId, session);
|
|
107
|
+
setTimeout(() => ensureTitle(sessionId), 0); // a Work opened again after a restart, still unnamed
|
|
69
108
|
// the model hears how a task ended; nothing wakes an idle session
|
|
70
109
|
session.useTasks(tasks.managerFor(sessionId), { wake: false });
|
|
71
110
|
},
|
|
@@ -83,6 +122,7 @@ export function createSpace(options) {
|
|
|
83
122
|
}
|
|
84
123
|
};
|
|
85
124
|
const times = new TimeIndex(store);
|
|
125
|
+
const stamps = new StampCache(store);
|
|
86
126
|
const augment = (event, sessionId) => {
|
|
87
127
|
const frames = [];
|
|
88
128
|
// when it happened: for every wire event but the two delta types, which are too many
|
|
@@ -96,16 +136,25 @@ export function createSpace(options) {
|
|
|
96
136
|
return frames;
|
|
97
137
|
};
|
|
98
138
|
/** The tool, input and execution start of the call a result answers, from the log before it. */
|
|
139
|
+
// an index of each Work's calls, extended as its log grows (a replay asked once per result, from seq 0, before)
|
|
140
|
+
const calls = new Map();
|
|
99
141
|
const callOf = (sessionId, callId) => {
|
|
100
|
-
|
|
101
|
-
let
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
142
|
+
const events = service.events(sessionId);
|
|
143
|
+
let held = calls.get(sessionId);
|
|
144
|
+
if (held === undefined || held.upTo > events.length)
|
|
145
|
+
calls.set(sessionId, (held = { upTo: 0, byId: new Map() }));
|
|
146
|
+
for (; held.upTo < events.length; held.upTo++) {
|
|
147
|
+
const e = events[held.upTo];
|
|
148
|
+
if (e.type === "tool_call_end")
|
|
149
|
+
held.byId.set(e.callId, { name: e.name, input: (e.input ?? {}), started: held.byId.get(e.callId)?.started ?? null });
|
|
150
|
+
else if (e.type === "tool_execution_started") {
|
|
151
|
+
const c = held.byId.get(e.callId);
|
|
152
|
+
if (c !== undefined)
|
|
153
|
+
c.started = e.seq;
|
|
154
|
+
}
|
|
107
155
|
}
|
|
108
|
-
|
|
156
|
+
const c = held.byId.get(callId);
|
|
157
|
+
return c === undefined ? null : { name: c.name, input: c.input, startedAt: c.started === null ? null : times.at(sessionId, c.started) };
|
|
109
158
|
};
|
|
110
159
|
const realWorkspace = () => {
|
|
111
160
|
try {
|
|
@@ -123,7 +172,9 @@ export function createSpace(options) {
|
|
|
123
172
|
if (event.type === "terminal") {
|
|
124
173
|
const events = service.events(sessionId);
|
|
125
174
|
const totals = runTotals(events, event.seq, route(sessionId));
|
|
126
|
-
|
|
175
|
+
// the rate reads the durable stamps, not the arrival clock: `usage` and the deltas are sent with no time, and one first asked for here would read as now
|
|
176
|
+
const stamp = stamps.upTo(sessionId, event.seq);
|
|
177
|
+
return totals === null ? [] : [{ event: "run_usage", data: { seq: event.seq, ...totals, tokPerSec: runRate(events, event.seq, totals.output, (seq) => stamp.get(seq) ?? times.at(sessionId, seq)) } }];
|
|
127
178
|
}
|
|
128
179
|
if (event.type === "tool_result") {
|
|
129
180
|
const artifacts = artifactsOf(event, sessionId, callOf(sessionId, event.callId), realWorkspace(), options.dir);
|
package/dist/main/times.js
CHANGED
|
@@ -26,3 +26,22 @@ export class TimeIndex {
|
|
|
26
26
|
return ts;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
/** The durable time of every event of a Work, read once and kept while the log has not grown past what was asked for: a replay sends a
|
|
30
|
+
* terminal event per run, and each one reading the whole log again would cost a Work with many runs seconds to open. */
|
|
31
|
+
export class StampCache {
|
|
32
|
+
#store;
|
|
33
|
+
#held = new Map();
|
|
34
|
+
constructor(store) {
|
|
35
|
+
this.#store = store;
|
|
36
|
+
}
|
|
37
|
+
/** The times of the log up to at least `seq` (the log is read again only when it has grown past what is held). */
|
|
38
|
+
upTo(sessionId, seq) {
|
|
39
|
+
let held = this.#held.get(sessionId);
|
|
40
|
+
if (held === undefined || held.seq < seq) {
|
|
41
|
+
const records = this.#store.load(sessionId);
|
|
42
|
+
held = { seq: records.at(-1)?.event.seq ?? -1, ts: new Map(records.map((r) => [r.event.seq, r.ts])) };
|
|
43
|
+
this.#held.set(sessionId, held);
|
|
44
|
+
}
|
|
45
|
+
return held.ts;
|
|
46
|
+
}
|
|
47
|
+
}
|
package/dist/main/usage.js
CHANGED
|
@@ -24,12 +24,21 @@ export function callNumbers(route, ev) {
|
|
|
24
24
|
const c = canonicalizeUsage(route, ev);
|
|
25
25
|
return { fresh: c.input, output: c.output, cacheRead: ev.cacheRead === null ? null : c.cacheRead, costUsd: c.costUsd, known: ev.known };
|
|
26
26
|
}
|
|
27
|
+
/** Where the run holding `seq` starts: just after the terminal before it, found by walking back (a run, not the log: the
|
|
28
|
+
* frames of a long Work were read from seq 0 for every usage report). The log's seq is its index. */
|
|
29
|
+
function runStartBefore(events, seq) {
|
|
30
|
+
for (let i = Math.min(seq, events.length) - 1; i >= 0; i--)
|
|
31
|
+
if (events[i].type === "terminal")
|
|
32
|
+
return i + 1;
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
27
35
|
/** The frame for the usage event at `seq`: the call, and the run so far. */
|
|
28
36
|
export function usageFrameAt(events, seq, route) {
|
|
29
37
|
let settled = null;
|
|
30
38
|
let inFlight = null;
|
|
31
39
|
let calls = 0;
|
|
32
|
-
for (
|
|
40
|
+
for (let i = runStartBefore(events, seq); i < events.length; i++) {
|
|
41
|
+
const ev = events[i];
|
|
33
42
|
if (ev.seq > seq)
|
|
34
43
|
break;
|
|
35
44
|
if (ev.type === "terminal") {
|
|
@@ -58,7 +67,8 @@ export function runTotals(events, terminalSeq, route) {
|
|
|
58
67
|
let settled = null;
|
|
59
68
|
let inFlight = null;
|
|
60
69
|
let calls = 0;
|
|
61
|
-
for (
|
|
70
|
+
for (let i = runStartBefore(events, terminalSeq); i < events.length; i++) {
|
|
71
|
+
const ev = events[i];
|
|
62
72
|
if (ev.seq > terminalSeq)
|
|
63
73
|
break;
|
|
64
74
|
if (ev.type === "terminal") {
|
|
@@ -85,9 +95,10 @@ const CALL_OUTPUT = new Set(["thinking", "text_start", "text_delta", "tool_call_
|
|
|
85
95
|
/** The run's decode rate as the terminal times one call (TPS-1), summed: each call from its first output event to its last usage
|
|
86
96
|
* report (tool time falls between calls), output over the summed time; null under 0.5 s or with no output ("0 tok/s" is no measurement). */
|
|
87
97
|
export function runRate(events, terminalSeq, output, at) {
|
|
88
|
-
const start = events
|
|
98
|
+
const start = runStartBefore(events, terminalSeq) - 1;
|
|
89
99
|
let [ms, first, last] = [0, -1, -1];
|
|
90
|
-
for (
|
|
100
|
+
for (let i = start + 1; i < events.length; i++) {
|
|
101
|
+
const ev = events[i];
|
|
91
102
|
if (ev.seq <= start || ev.seq > terminalSeq)
|
|
92
103
|
continue;
|
|
93
104
|
if (CALL_OUTPUT.has(ev.type) && first < 0)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { addFolder, EnvironmentRefusedError, kisoHome, readEnvironment, removeFolder } from "@vincemakes/kiso-runtime";
|
|
4
|
+
import { fileStopRoots } from "@vincemakes/kiso-code/policy";
|
|
5
|
+
import { Refusal } from "./files.js";
|
|
6
|
+
/** The places no added folder may be, and no listing of an added folder may name (the file tools refuse them there). */
|
|
7
|
+
export const stopRoots = () => fileStopRoots(homedir(), kisoHome());
|
|
8
|
+
/** A Work's added folders for the page: each with whether it still exists, and whether the list could be read at all. */
|
|
9
|
+
export function foldersOf(space, session) {
|
|
10
|
+
const { added, damaged } = readEnvironment(space.dir, session);
|
|
11
|
+
return { added: added.map((path) => ({ path, missing: !existsSync(path) })), damaged };
|
|
12
|
+
}
|
|
13
|
+
/** Add or remove, at any time: the file tools read the list on every call, so nothing has to be rebuilt. */
|
|
14
|
+
export async function changeFolders(space, session, add, remove) {
|
|
15
|
+
try {
|
|
16
|
+
if (add !== undefined)
|
|
17
|
+
await addFolder(space.dir, session, { primary: space.workspace, folder: add, stops: stopRoots() });
|
|
18
|
+
else if (remove !== undefined)
|
|
19
|
+
await removeFolder(space.dir, session, remove);
|
|
20
|
+
else
|
|
21
|
+
throw new Refusal(400, "add or remove a folder");
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err instanceof EnvironmentRefusedError)
|
|
25
|
+
throw new Refusal(409, err.message);
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/dist/main/works.js
CHANGED
|
@@ -15,7 +15,7 @@ export function workAct(space, settings, session, act) {
|
|
|
15
15
|
// closed first: the store refuses any later write to it, so nothing brings the files back
|
|
16
16
|
space.store.close(session);
|
|
17
17
|
space.tasks.forget(session);
|
|
18
|
-
for (const path of [`${session}.jsonl`, `${session}.meta.json`, `${session}.tasks`, `${session}.files`])
|
|
18
|
+
for (const path of [`${session}.jsonl`, `${session}.meta.json`, `${session}.environment.json`, `${session}.environment.json.lock`, `${session}.tasks`, `${session}.files`])
|
|
19
19
|
rmSync(join(space.dir, path), { recursive: true, force: true });
|
|
20
20
|
settings.forget(session);
|
|
21
21
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--ink:#1c1c1e;--mute:#8a8a8e;--faint:#b4b4ba;--line:#ececee;--blue:#2f6bff;--green:#1f9d57;--red:#d94a4a;--amber:#d98a1a;--sunk:#f6f6f8;--ease:cubic-bezier(.22, .9, .24, 1);--spring:cubic-bezier(.34, 1.4, .5, 1);--mono:ui-monospace, SFMono-Regular, Menlo, monospace;--sans:-apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Hiragino Sans GB", "Helvetica Neue", sans-serif}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font:14px/1.6 var(--sans);color:var(--ink);background:#fff;overflow:hidden}button{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0;padding:0}textarea{font:inherit;color:inherit}svg{display:block}.ico{fill:none;stroke:currentColor;stroke-width:1.8px;stroke-linecap:round;stroke-linejoin:round;width:15px;height:15px}.i16{fill:none;stroke:currentColor;stroke-width:1.75px;stroke-linecap:round;stroke-linejoin:round;flex:none;width:16px;height:16px}.scroll{inset:54px 0 calc(var(--comp-h,88px) + 20px) 0;overflow-anchor:none;scrollbar-width:thin;scrollbar-color:#c4c4c8 transparent;scrollbar-gutter:stable both-edges;padding:24px 0 20px;position:absolute;overflow-y:auto;mask-image:linear-gradient(#0000,#000 14px)}.col{flex-direction:column;gap:14px;width:680px;max-width:calc(100% - 40px);margin:0 auto;display:flex}.empty{text-align:center;color:var(--mute);margin:22vh auto 0;font-size:15px}.empty b{color:var(--ink);letter-spacing:-.01em;margin-bottom:6px;font-size:22px;font-weight:600;display:block}.me{white-space:pre-wrap;overflow-wrap:break-word;background:#f3f3f5;border-radius:18px;align-self:flex-end;max-width:82%;padding:9px 14px;font-size:14.5px;line-height:1.55}@keyframes in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}@keyframes fade{0%{opacity:0}}.turn.fresh :is(.me,.proc,.think,.say,.step,.bgtag,.note,.ans,.acts,.run-end){animation:.15s ease-out both fade}.comp{width:min(680px,100% - 40px);position:absolute;bottom:20px;left:50%;transform:translate(-50%)}.box{background:#fff;border-radius:22px;grid-template-columns:auto 1fr auto;grid-template-areas:"plus text send";align-items:center;column-gap:4px;padding:6px 8px;transition:box-shadow .15s;display:grid;position:relative;box-shadow:0 8px 30px #00000012,0 0 0 1px #0000000a}.box.grown{grid-template-columns:1fr auto;grid-template-areas:"atts atts""text text""plus send";row-gap:2px;padding:10px 10px 8px 16px}.box>.atts{grid-area:atts}.box>.cm{grid-area:plus;justify-self:start}.box>.sendb{grid-area:send;justify-self:end}.box textarea{resize:none;background:0 0;border:0;outline:0;grid-area:text;width:100%;min-width:0;max-height:160px;padding:6px 4px 5px;font-size:14.5px;line-height:1.5}.box.grown textarea{padding:4px 6px 6px 0}.comp.inline .box textarea{min-height:56px}.box textarea::placeholder{color:#a5a5a8}.sendb{color:#b5b5b9;background:0 0;border-radius:50%;flex:none;place-items:center;width:32px;height:32px;transition:all .2s;display:grid;box-shadow:inset 0 0 0 1.5px #cfcfd2}.sendb.ready,.sendb.run{background:var(--ink);box-shadow:none;color:#fff}.sendb i{background:#fff;border-radius:2px;width:10px;height:10px;display:block}.proc{flex-direction:column;gap:10px;display:flex}.ph{text-align:left;width:100%;color:var(--mute);align-items:center;gap:8px;padding:4px 0;font-size:13.5px;display:flex}.chev{color:var(--faint);flex:none;transition:transform .15s,opacity .12s}.ph .chev,.th-h .chev{opacity:0}.ph:hover .chev,.th-h:hover .chev,.ph:focus-visible .chev,.th-h:focus-visible .chev,.grp:not(.folded)>.ph .chev,.think.open .th-h .chev{opacity:1}.grp:not(.folded)>.ph .chev,.think.open .th-h .chev{transform:rotate(90deg)}.ph .lab{color:#555;font-weight:500}.ph .clk{font-variant-numeric:tabular-nums}.delta{font-variant-numeric:tabular-nums;gap:4px;font-size:12.5px;display:inline-flex}.delta .plus{color:var(--green);font-style:normal}.delta .minus{color:var(--red);font-style:normal}.delta.mod{color:var(--faint)}.pw{transition:grid-template-rows .2s var(--ease);grid-template-rows:1fr;grid-template-columns:minmax(0,1fr);display:grid}.grp.folded>.pw{grid-template-rows:0fr}.pb{min-width:0;min-height:0;overflow:clip}.pb-in{flex-direction:column;gap:12px;padding:6px 0 4px;display:flex}.th-h{color:var(--mute);text-align:left;align-items:center;gap:8px;width:100%;font-size:13.5px;display:flex}.ph .lab.shimmer,.th-h .lab.shimmer{background:linear-gradient(90deg,#8a8a8e 20%,#1c1c1e 50%,#8a8a8e 80%) 0 0/200% 100%;color:#0000;background-clip:text;animation:1.8s linear infinite sh}@keyframes sh{to{background-position:-200% 0}}.th-h .t{font-variant-numeric:tabular-nums;color:var(--faint)}.th-full{transition:grid-template-rows .2s var(--ease);grid-template-rows:0fr;grid-template-columns:minmax(0,1fr);display:grid}.think.open .th-full{grid-template-rows:1fr}.th-full>div{min-width:0;min-height:0;overflow:clip}.th-text{border-left:2px solid var(--line);color:var(--mute);white-space:pre-wrap;margin:6px 0 2px;padding:2px 0 2px 12px;font-size:13px;line-height:1.75}.say{color:var(--ink);overflow-wrap:break-word;font-size:14.5px;line-height:1.65}.say p{margin-bottom:0}.say>*+*{margin-top:10px}.say>:first-child{margin-top:0}.say blockquote>*+*{margin-top:10px}.say blockquote>:first-child{margin-top:0}.say :is(h1,h2,h3,h4){margin-bottom:0;font-size:14.5px;font-weight:600;line-height:1.6}.say :is(blockquote,hr){margin-bottom:0;margin-inline:0}.say code{font:13px var(--mono);background:#f3f3f5;border-radius:5px;padding:1px 5px}.say ul,.say ol{margin-bottom:0;padding-left:20px}.caret>:last-child:not(ul,ol,pre,hr,.tbl):after,.caret>:is(ul,ol):last-child>li:last-child:after{content:"";background:var(--ink);vertical-align:-2px;width:6px;height:14px;margin-left:2px;animation:.9s step-end infinite bl;display:inline-block}@keyframes bl{50%{opacity:0}}.steer{background:#f3f3f5;border-radius:14px;align-self:flex-end;padding:5px 12px;font-size:13px}.s-row{align-items:center;gap:9px;min-height:26px;display:flex}.s-ic{color:#777;flex:none;place-items:center;width:16px;height:16px;display:grid}.s-ic .sp{border:2px solid #dcdce0;border-top-color:var(--blue);border-radius:50%;width:12px;height:12px;animation:1s linear infinite spn}@keyframes spn{to{transform:rotate(360deg)}}.s-verb{font-size:12.5px;font-weight:600}.s-obj{font:12px var(--mono);color:#555;white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.s-sp{flex:1}.s-time{font:11px var(--mono);color:var(--mute);font-variant-numeric:tabular-nums;flex:none}.step.failed .s-verb,.step.denied .s-verb{color:var(--red)}.bgtag{color:var(--blue);background:#eef3ff;border-radius:8px;flex:none;padding:1px 8px;font-size:11px}.s-out{background:var(--sunk);font:11.5px/1.6 var(--mono);color:#4a4a52;border-radius:8px;margin:4px 0 0;padding:7px 11px}.s-lines{white-space:pre;overflow:hidden}.s-lines[data-wide=true]{mask-image:linear-gradient(90deg,#000 calc(100% - 36px),#0000)}.s-out .more{color:var(--blue);font:11px var(--sans);margin-top:3px}.s-out .a{color:#176b3a}.s-out .d{color:#a33636}.s-req{font:11px var(--mono);color:var(--mute);font-variant-numeric:tabular-nums;margin:3px 0 0}.link{color:var(--mute);justify-content:center;align-items:center;gap:4px;margin-bottom:8px;font-size:13px;display:flex}.link button{color:var(--ink);text-decoration:underline}.link .sp,.s-req .sp{vertical-align:-1px;border:2px solid #dcdce0;border-top-color:var(--blue);border-radius:50%;width:10px;height:10px;margin-right:6px;animation:1s linear infinite spn;display:inline-block}.s-err{color:var(--red);margin:3px 0 0;font-size:12px}.ask{animation:in .45s var(--ease) both, pl 1.6s ease-in-out .5s infinite;background:#fff;border-radius:16px;padding:13px 15px;box-shadow:0 0 0 1px #f0d9a8,0 8px 30px #d98a1a1f}@keyframes pl{50%{box-shadow:0 0 0 1px #e8c47a,0 8px 36px #d98a1a47}}.ask .h{align-items:center;gap:8px;font-weight:600;display:flex}.ask .h svg{color:var(--amber)}.ask pre{font:12.5px var(--mono);white-space:pre-wrap;overflow-wrap:anywhere;background:#f5f5f6;border-radius:10px;max-height:220px;margin:9px 0;padding:8px 12px;overflow:auto}.ask pre .a{color:#176b3a}.ask pre .d{color:#a33636}.btn{background:#f1f1f3;border-radius:9px;height:30px;margin-right:6px;padding:0 13px;transition:all .2s}.btn.pri{background:var(--ink);color:#fff}.btn:disabled{opacity:.5;cursor:default}.note{color:var(--mute);align-items:center;gap:8px;font-size:12.5px;display:flex}.note .ok{background:var(--green);border-radius:50%;flex:none;width:14px;height:14px;position:relative}.note .ok:after{content:"";border:1.6px solid #fff;border-width:0 1.6px 1.6px 0;width:3px;height:6px;position:absolute;top:2px;left:4.5px;transform:rotate(45deg)}.note .no{background:var(--red);border-radius:50%;flex:none;width:14px;height:14px}.note[data-kind=notice]{color:var(--ink);gap:6px;font-size:14px;line-height:1.5}.note[data-kind=notice].fail{color:var(--red)}.note[data-kind=notice].stop{color:var(--mute)}.note[data-kind=notice] small{color:var(--mute);font-size:13px}.ans{color:var(--ink);overflow-wrap:break-word;font-size:14.5px;line-height:1.65}.ans>:first-child{margin-top:0}.ans>:last-child{margin-bottom:0}.ans h1{margin:24px 0 6px;font-size:15.5px;font-weight:600;line-height:1.5}.ans h2{margin:22px 0 6px;font-size:14.5px;font-weight:600;line-height:1.6}.ans h3,.ans h4{margin:18px 0 4px;font-size:14.5px;font-weight:600;line-height:1.6}.ans p{margin:0 0 14px}.ans ul,.ans ol{margin:0 0 14px;padding-left:22px}.ans li{margin:2px 0}.ans li::marker{color:var(--mute)}:is(.ans,.say) li>:is(ul,ol){margin:2px 0 0}:is(.ans,.say) li>:is(p,pre,blockquote,.tbl){margin:6px 0 0}:is(.ans,.say) li.tk{margin-left:-20px;list-style:none}:is(.ans,.say) li.tk input{vertical-align:-1px;margin:0 7px 0 0}.ans code{font:13px var(--mono);background:#f3f3f5;border-radius:5px;padding:1px 5px}.ans pre{background:var(--sunk);font:12.5px/1.6 var(--mono);border-radius:10px;padding:10px 14px;overflow:auto}.ans pre code{background:0 0;padding:0}.lk{color:var(--blue);cursor:pointer;border-bottom:1px dashed #0000;text-decoration:none;display:inline;position:relative}.lk:hover{border-bottom-color:var(--blue)}.lk.plain{cursor:default;color:inherit;text-decoration:underline;-webkit-text-decoration-color:var(--line);text-decoration-color:var(--line);border-bottom:0}.fic{vertical-align:-.15em;width:14px;height:14px;margin-right:4px;display:inline}.hov{z-index:5;border:1px solid var(--line);min-width:240px;color:var(--mute);white-space:nowrap;background:#fff;border-radius:12px;align-items:center;gap:10px;padding:8px 12px;font-size:13px;display:none;position:absolute;top:calc(100% + 4px);left:0;box-shadow:0 8px 28px #0000001a}.lk:hover .hov,.lk:focus-visible .hov{display:flex}.hov .o{color:var(--ink);margin-left:auto}.fchip{overflow-wrap:anywhere;vertical-align:baseline;max-width:100%;color:var(--ink);cursor:pointer;background:#f3f4f6;border-radius:6px;padding:1px 6px;display:inline-block}.fchip:hover{background:#e9ebef}.ans .tbl{margin:10px 0}:is(.ans,.say) .tbl{max-width:100%;overflow-x:auto}:is(.ans,.say) table{border-collapse:collapse;font-size:13.5px;line-height:1.5}:is(.ans,.say) th,:is(.ans,.say) td{border:1px solid var(--line);vertical-align:top;padding:5px 10px}:is(.ans,.say) th{white-space:nowrap;text-align:left;background:#f7f7f8;font-weight:600}:is(.ans,.say) blockquote{border-left:3px solid var(--line);color:#555;padding:2px 0 2px 14px}.ans blockquote{margin:8px 0}:is(.ans,.say) hr{border:0;border-top:1px solid var(--line)}.ans hr{margin:14px 0}.acts{color:var(--faint);font-variant-numeric:tabular-nums;font-size:12px}.run-end{color:#8a5300;overflow-wrap:anywhere;background:#fff7e6;border-radius:10px;margin:6px 0 10px;padding:8px 12px;font-size:13px;line-height:1.5}.run-end.bad{color:#b42318;background:#fef3f2}.racts{color:var(--mute);opacity:0;align-items:center;gap:2px;margin:2px 0 10px -6px;font-size:12px;transition:opacity .15s;display:flex}.racts.me-acts{justify-content:flex-end;margin:-2px 0 0}.turn{display:contents}.turn:hover>.racts:not(.me-acts),.me:hover~.me-acts,.me-more:hover~.me-acts,.racts:hover,.racts:focus-within{opacity:1}.racts .ab{width:26px;height:26px;color:var(--mute);border-radius:7px;place-items:center;display:grid}.racts .ab:hover{color:var(--ink);background:#0000000d}.racts .ago{color:var(--mute);margin-left:6px;font-size:11.5px}.forknote{color:var(--mute);background:#f6f6f4;border-radius:10px;margin:0 0 14px;padding:8px 12px;font-size:12.5px;line-height:1.5}.forknote.err{color:#b42318;background:#fef3f2}.forknote .flink{color:var(--ink);text-underline-offset:2px;text-decoration:underline}.ask.resume .btn,.verdict{margin-top:8px}.verdict pre{margin:0 0 8px}.toast{left:50%;bottom:calc(var(--comp-h,88px) + 28px);color:#fff;animation:in .3s var(--ease) both;background:#1c1c1ee6;border-radius:14px;padding:6px 14px;font-size:12.5px;position:absolute;transform:translate(-50%)}.latest{left:50%;bottom:calc(var(--comp-h,88px) + 32px);color:var(--ink);box-shadow:0 0 0 1px var(--line), 0 6px 18px #0000001a;animation:in .25s var(--ease) both;background:#fff;border-radius:15px;padding:5px 13px;font-size:12.5px;position:absolute;transform:translate(-50%)}.loading{animation:in .3s var(--ease) .3s both;flex-direction:column;gap:12px;padding-top:8px;display:flex}.loading i{background:linear-gradient(90deg,#f1f1f3 30%,#e7e7ea 50%,#f1f1f3 70%) 0 0/200% 100%;border-radius:6px;height:12px;animation:1.4s linear infinite sheen;display:block}.loading .me-sk{border-radius:18px;align-self:flex-end;width:42%;height:38px;margin-bottom:12px}.loading i:nth-child(3){width:85%}.loading i:nth-child(4){width:55%}@keyframes sheen{to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.ph .lab.shimmer,.th-h .lab.shimmer{color:var(--mute);background:0 0;animation:none}.ask{animation:none!important}.turn.fresh :is(.me,.proc,.think,.say,.step,.bgtag,.note,.ans,.acts,.run-end){animation:none}.pw,.th-full,.chev{transition:none}}.tns{flex:none;align-items:center;gap:6px;margin-left:auto;display:inline-flex}.tn{width:66px;height:42px;box-shadow:0 0 0 1px var(--line), 0 1px 4px #00000014;cursor:zoom-in;background:#fff;border-radius:7px;flex:none;place-items:center;display:inline-grid;overflow:hidden}.tn .fic{width:18px;height:18px;margin:0}.tn-img{object-fit:cover;width:100%;height:100%;display:block}.tn-img.gone,.ip-img.gone{color:var(--faint);text-align:center;place-items:center;font-size:10.5px;line-height:1.2;display:grid}.tpage{color:var(--mute);text-align:center;flex-direction:column;align-items:center;gap:2px;padding:0 4px;font-size:10px;line-height:1.2;display:flex;overflow:hidden}.tpage>span{white-space:nowrap;text-overflow:ellipsis;max-width:58px;overflow:hidden}.tn-more{color:var(--mute);font-size:12px}.s-row.click{cursor:pointer}.step.shown .s-row .chev{transform:rotate(90deg)}.inplace{flex-direction:column;gap:8px;margin:6px 0 2px;display:flex}.ip-img{width:100%;box-shadow:0 0 0 1px var(--line);cursor:zoom-in;border-radius:10px;display:block}.made{flex-wrap:wrap;gap:6px;margin:10px 0 2px;display:flex}.made-c{border:1px solid var(--line);max-width:260px;height:32px;color:var(--ink);background:#fff;border-radius:10px;align-items:center;gap:8px;padding:0 12px 0 10px;font-size:13px;display:inline-flex}.made-c:hover{background:var(--sunk)}.made-c .i16{color:var(--mute)}.made-c span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.lightbox{z-index:200;animation:in .15s var(--ease) both;background:#111113d6;flex-direction:column;justify-content:center;align-items:center;gap:12px;padding:56px 24px 24px;display:flex;position:fixed;inset:0}.lb-img{object-fit:contain;background:#fff;border-radius:10px;max-width:min(1200px,100%);max-height:calc(100vh - 120px);box-shadow:0 20px 60px #00000073}.lb-cap{color:#d9d9dc;font-size:12.5px}.lb-acts{gap:6px;display:flex;position:absolute;top:14px;right:14px}.lb-b{color:#fff;background:#ffffff1f;border-radius:9px;place-items:center;width:34px;height:34px;display:grid}.lb-b:hover{background:#ffffff38}.box.drag{box-shadow:0 0 0 2px var(--blue), 0 8px 30px #2f6bff26}.cm{display:inline-flex;position:relative}.cpill{height:30px;color:var(--mute);white-space:nowrap;border-radius:999px;align-items:center;gap:4px;padding:0 10px;font-size:13px;display:inline-flex}.sline{align-items:center;gap:2px;padding:6px 0 0 6px;display:flex}.sline .hint{color:var(--faint);margin-left:auto;padding-right:6px;font-size:12px}.sline .chip{height:30px;color:var(--mute);background:0 0;border-radius:999px;gap:5px;padding:0 10px}.sline .chip:hover{background:var(--sunk)}.sline .chip .ico{width:14px;height:14px}.sline>:is(.cm,.trayfold)+.cm:before{content:"·";color:var(--faint);align-self:center;padding:0 1px}.sline.busy .cpill{opacity:.55}.box .cpill.round{color:#3a3a3e}.cpill:hover:not(:disabled){background:var(--sunk)}.cpill:disabled{opacity:.55;cursor:default}.cpill.round{justify-content:center;width:30px;padding:0}.cpill .sub{color:var(--faint)}.cpill [data-field=model-pill]{text-overflow:ellipsis;max-width:180px;overflow:hidden}.cmenu{z-index:90;min-width:260px;max-width:340px;box-shadow:0 14px 50px #00000029, 0 0 0 1px var(--line);animation:in .15s var(--ease) both;background:#fff;border-radius:14px;padding:6px;position:absolute;bottom:calc(100% + 8px);left:0}.cm-h{color:var(--mute);padding:6px 10px 4px;font-size:12px}.cm-i{text-align:left;width:100%;color:var(--ink);border-radius:9px;align-items:flex-start;gap:10px;padding:8px 10px;display:flex}.cm-i:hover:not(:disabled),.cm-i.on{background:var(--sunk)}.cm-i:disabled{opacity:.5;cursor:default}.cm-i>.i16{color:var(--mute);margin-top:2px}.cm-i>.i16:last-child{color:var(--blue);margin-left:auto}.cm-t{flex-direction:column;min-width:0;display:flex}.cm-t b{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;overflow:hidden}.cm-t small{color:var(--mute);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;overflow:hidden}.cm-at{text-align:center;width:16px;color:var(--mute);font-weight:600}.cm-tag{border:1px solid var(--line);color:var(--mute);border-radius:6px;margin-left:6px;padding:0 5px;font-size:11px;font-weight:400}.cm-seg{gap:4px;padding:2px 8px 8px;display:flex}.cm-seg button{background:var(--sunk);color:var(--mute);border-radius:7px;flex:1;padding:4px 0;font-size:12.5px}.cm-seg button.on{background:var(--ink);color:#fff}.cmenu[data-menu=model]{width:340px;max-width:calc(100vw - 32px)}.cm-list{scrollbar-width:thin;max-height:264px;overflow-y:auto}.cm-i.one{align-items:center;gap:8px;padding:6px 10px}.cm-i.one>b{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:14px;font-weight:450;overflow:hidden}.cm-i.one>small{max-width:42%;color:var(--faint);text-align:right;text-overflow:ellipsis;white-space:nowrap;flex:0 auto;font-size:12.5px;overflow:hidden}.cm-i.one>.i16,.cm-nock{flex:none;width:16px;margin:0}.cm-i.one>.i16:last-child{color:var(--blue)}.cmenu .sep{background:var(--line);height:1px;margin:5px 4px}.cm-fly{position:relative}.cm-row>.cm-v{color:var(--mute);text-transform:capitalize}.cm-i.one.cm-row>.i16:last-child{color:var(--mute);transform:rotate(-90deg)}.cm .cmenu.cm-sub[data-menu]{width:220px;min-width:200px;bottom:-6px;left:calc(100% + 12px);right:auto}.cm-sub .cm-i.one>b{text-transform:capitalize}.cm-err{color:#9a3412;background:#fff4ec;border-radius:8px;margin:4px 8px 6px;padding:6px 8px;font-size:12.5px}.atp{bottom:calc(100% - 4px);left:8px}.atts{flex-wrap:wrap;gap:8px;padding:4px 0 2px;display:flex}.att{border:1px solid var(--line);background:var(--sunk);border-radius:10px;align-items:center;gap:8px;height:56px;display:inline-flex;position:relative;overflow:hidden}.att.image{width:56px}.att.image img{object-fit:cover;width:100%;height:100%}.att.file{max-width:220px;padding:0 30px 0 10px;font-size:12.5px}.att.file span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.att-x{color:#fff;background:#0000008c;border-radius:50%;place-items:center;width:18px;height:18px;display:grid;position:absolute;top:3px;right:3px}.att-x .i16{stroke-width:2.2px;width:11px;height:11px}.cwarn{color:#92400e;background:#fffbeb;border-radius:10px;align-items:center;gap:8px;margin:0 0 6px;padding:7px 10px;font-size:12.5px;display:flex}.cnote{color:var(--red);padding:0 2px 6px;font-size:12.5px}.vnote{color:var(--mute);margin:2px 0 8px;font-size:12.5px}.cquiet{color:var(--mute);padding:0 2px 6px;font-size:12.5px}.me-pics{--att:64px;flex-wrap:wrap;justify-content:flex-end;align-items:stretch;gap:6px;margin:18px 0 -12px;display:flex}.me-pic{width:var(--att);height:var(--att);border:1px solid var(--line);border-radius:12px;overflow:hidden}.me-img{object-fit:cover;width:100%;height:100%;display:block}.me-file{height:var(--att);box-sizing:border-box;border:1px solid var(--line);text-align:left;background:#fff;border-radius:12px;align-items:center;gap:10px;max-width:260px;padding:0 14px 0 11px;display:flex}.me-file:hover{background:#fafafb}.me-ft{background:var(--sunk);width:36px;height:42px;font:600 10px var(--mono);color:#6b6b70;border-radius:7px;flex:none;place-items:center;display:grid}.me-fn{flex-direction:column;min-width:0;display:flex}.me-fn b{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}.me-fn small{color:var(--mute);font-size:12px}.fviewer{z-index:200;animation:in .15s var(--ease) both;background:#11111352;place-items:center;padding:24px;display:grid;position:fixed;inset:0}.fv-box{background:#fff;border-radius:14px;flex-direction:column;width:min(760px,100%);max-height:min(80vh,900px);display:flex;overflow:hidden;box-shadow:0 18px 60px #0000002e}.fv-h{border-bottom:1px solid var(--line);align-items:center;gap:10px;padding:10px 12px 10px 16px;font-size:13px;display:flex}.fv-h b{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.fv-h span{color:var(--mute);margin-left:auto}.fv-text{font:12.5px/1.6 var(--mono);color:#333;white-space:pre;margin:0;padding:12px 16px;overflow:auto}.me.clamp{max-height:calc(9.6em + 18px);position:relative;overflow:hidden}.me.folded:after{content:"";pointer-events:none;background:linear-gradient(#f3f3f500,#f3f3f5);height:3.2em;position:absolute;bottom:0;left:0;right:0}.me-more{color:#3a3a3e;align-self:flex-end;margin:-2px 12px 0 0;font-size:13px}.me-more:hover{color:var(--ink);text-decoration:underline}:root{--sw:264px;--side:#fff}.win{background:#fff;display:flex;position:fixed;inset:0;overflow:clip}@media (display-mode:standalone){.win:before{content:"";background:var(--line);z-index:200;pointer-events:none;height:1px;position:absolute;top:0;left:0;right:0}}.sidetoggle{z-index:70;width:34px;height:34px;color:var(--mute);transition:left .2s var(--ease);border-radius:10px;place-items:center;display:grid;position:absolute;top:10px;left:12px}.win[data-side="1"] .sidetoggle{left:calc(var(--sw) - 46px)}.brand{z-index:70;height:34px;color:var(--ink);pointer-events:none;align-items:center;gap:8px;display:flex;position:absolute;top:10px;left:22px}.brand .mark{flex:none}.brand .word{letter-spacing:-.02em;font-size:17px;font-weight:600;line-height:1}.sidetoggle:hover{color:var(--ink);background:#0000000f}.main{flex:1 1 0;min-width:0;display:flex;position:relative;container-type:inline-size}.side{background:var(--side);width:0;transition:width .2s var(--ease);flex:none;overflow:hidden}.win[data-side="1"] .side{width:var(--sw)}.side-in{width:var(--sw);border-right:1px solid var(--line);flex-direction:column;height:100%;padding:54px 10px 10px;display:flex}.newbtn{background:#fff;border-radius:11px;align-items:center;gap:8px;width:100%;height:38px;margin-bottom:8px;padding:0 12px;transition:box-shadow .15s;display:flex;box-shadow:0 0 0 1px #00000012}.newbtn:hover{box-shadow:0 0 0 1px #0000001f}.hlist{scrollbar-width:thin;scrollbar-color:#cfcfcb transparent;flex:1;margin:0 -6px;padding:0 6px;overflow-y:auto}.side .grp{color:var(--mute);padding:12px 10px 4px;font-size:12.5px;font-weight:500}.hlist section+section{margin-top:10px}.side .grp.gh{text-align:left;align-items:center;gap:5px;width:100%;display:flex}.side .grp.gh:hover{color:var(--ink)}.side .grp.gh .chev{color:inherit;opacity:0;transform:rotate(90deg)}.side .grp.gh:hover .chev,.side .grp.gh:focus-visible .chev,.side .shut>.grp.gh .chev{opacity:1}.side .shut>.grp.gh .chev{transform:none}.item{text-align:left;width:100%;min-height:36px;color:var(--ink);border-radius:8px;align-items:center;gap:8px;padding:0 10px;font-size:14.5px;transition:background .15s;display:flex}.item.child{color:#3a3a3e;padding-left:30px;font-size:14px;position:relative}.item.child:before{content:"";border-bottom:1.5px solid #d6d6d2;border-left:1.5px solid #d6d6d2;border-bottom-left-radius:6px;width:8px;height:12px;position:absolute;top:3px;left:16px}.item.child.more:after{content:"";border-left:1.5px solid #d6d6d2;position:absolute;top:3px;bottom:-4px;left:16px}.item:hover{background:#0000000b}.item.on{background:#0001}.item .tt{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.dot{border-radius:50%;flex:none;width:8px;height:8px}.dot.amber{background:var(--amber)}.dot.blue{background:var(--blue)}.item .pr-ico{width:18px;height:18px;color:var(--mute);border-radius:5px;flex:none;place-items:center;display:grid}.item .pr-ico:hover{background:#0000000f}.item .pr-ico[data-pr-state=open]{color:#1f883d}.item .pr-ico[data-pr-state=merged]{color:#8250df}.item .pr-ico[data-pr-state=closed]{color:#cf222e}.item .kid-fold{width:20px;height:20px;color:var(--mute);border-radius:5px;flex:none;place-items:center;margin-left:-4px;display:grid}.row:hover .item .kid-fold,.row.menu-open .item .kid-fold{margin-right:26px}.item .kid-fold:hover{color:var(--ink);background:#0000000f}.item .kid-fold .chev{color:inherit;opacity:0;transform:rotate(90deg)}.item:hover .kid-fold .chev,.item .kid-fold:focus-visible .chev,.item .kid-fold.shut .chev{opacity:1}.item .kid-fold.shut .chev{transform:none}.kids-line{text-align:left;width:100%;color:var(--mute);border-radius:8px;padding:8px 10px 8px 30px;font-size:12.5px;line-height:20px;display:block;position:relative}.kids-line:before{content:"";border-bottom:1.5px solid #d6d6d2;border-left:1.5px solid #d6d6d2;border-bottom-left-radius:6px;width:8px;height:12px;position:absolute;top:3px;left:16px}.kids-line:hover{color:var(--ink)}.kids-line em{color:var(--blue);font-style:normal}.item .sp{border:2px solid #d8d8d5;border-top-color:var(--blue);border-radius:50%;flex:none;width:12px;height:12px;animation:1s linear infinite sp}@keyframes sp{to{transform:rotate(360deg)}}.fn{border-top:1px solid #0000000f;margin:8px -4px 0;padding-top:6px}.fn-h{width:100%;color:var(--mute);border-radius:10px;align-items:center;gap:8px;padding:7px 10px;font-size:14px;display:flex}.fn-h:hover,.fn-h.on{color:var(--ink);background:#0000000a}.row{position:relative}.row .dots{color:#555;border-radius:7px;place-items:center;width:26px;height:24px;display:none;position:absolute;top:50%;right:6px;transform:translateY(-50%)}.row:hover .dots,.row.menu-open .dots{display:grid}.row:hover .item :is(.sp,.dot),.row.menu-open .item :is(.sp,.dot){visibility:hidden}.row .dots:hover{background:#00000012}.row-in{min-width:0;font:inherit;color:var(--ink);background:0 0;border:0;outline:0;flex:1;padding:0}.row-in::selection{background:#cfe0ff}.menu.smenu{z-index:140;min-width:200px;position:fixed;right:auto}.menu .sep{background:var(--line);height:1px;margin:5px 4px}.menu button.danger{color:#c0392b}.menu.smenu kbd{font:inherit;color:var(--mute);margin-left:auto;font-size:12px}.side-err{color:#b42318;background:#fef3f2;border-radius:9px;margin:6px 4px;padding:7px 10px;font-size:12.5px;line-height:1.45}.archived-h{text-align:left;width:100%;display:block}.archived-h:hover{color:var(--ink)}.frow{width:100%;min-height:36px;color:var(--ink);text-align:left;border-radius:8px;align-items:center;gap:8px;padding:0 10px;font-size:14.5px;transition:background .15s;display:flex}.frow:hover{background:#0000000b}.frow .i16{color:var(--mute)}.frow .tt{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.fin .item{padding-left:34px}.fin .item.child,.fin .kids-line{padding-left:54px}.fin .item.child:before,.fin .item.child.more:after,.fin .kids-line:before{left:40px}.more-line{text-align:left;width:100%;color:var(--mute);border-radius:8px;padding:6px 10px 6px 34px;font-size:12.5px;display:block}.hlist>section>.more-line{padding-left:10px}.more-line:hover{color:var(--ink)}.ghead{position:relative}.ghead .gmenu{color:#555;border-radius:7px;place-items:center;width:26px;height:24px;display:none;position:absolute;bottom:0;right:6px}.ghead:hover .gmenu,.ghead .gmenu.on{display:grid}.ghead .gmenu:hover{background:#00000012}.menu .mh{color:var(--mute);padding:6px 10px 2px;font-size:12px}.menu .ck{width:16px;margin-left:auto;display:grid}.menu .ck .ico{color:var(--ink)}@media (width<=863px){.side,.rail{z-index:80;position:absolute;top:0;bottom:0}.win[data-side="1"] .side,.win[data-rail="1"] .rail{box-shadow:0 0 40px #0000002e}.side{left:0}.rail{right:0}.win[data-side="1"] .side{width:min(var(--sw), 82vw)}.win[data-rail="1"] .rail{width:min(280px,82vw)}.win[data-side="1"]:after,.win[data-rail="1"]:after{content:"";z-index:75;background:#14141847;position:absolute;inset:0}.sidetoggle,.brand{z-index:90}.chat{min-width:0}}.settings{padding:72px 0 40px;position:absolute;inset:0;overflow-y:auto}.settings>*{width:560px;max-width:calc(100% - 40px);margin-left:auto;margin-right:auto}.settings h1{letter-spacing:-.01em;margin-top:0;margin-bottom:20px;font-size:22px;font-weight:600}.srow{border-top:1px solid var(--line);align-items:center;gap:16px;padding:14px 0;display:flex}.slabel{flex:1;min-width:45%}.slabel small{color:var(--mute);font-size:12px;display:block}.sfield .cpill{border:1px solid var(--line);background:#fff;max-width:280px}.sfield{text-align:right;max-width:55%}.sfield .cpill>span{text-overflow:ellipsis;overflow:hidden}.sfield [data-field=effort],.sfield [data-effort] b{text-transform:capitalize}.sfield .cmenu.down{text-align:left;width:340px;max-height:min(420px,60vh);inset:calc(100% + 6px) 0 auto auto;overflow-y:auto}.muted{color:var(--mute)}.okline{color:var(--green)}.warnline{color:var(--amber)}.folders{border:0;border-radius:16px;flex-direction:column;gap:10px;width:min(560px,100vw - 32px);max-height:min(620px,100vh - 48px);padding:18px;display:flex;box-shadow:0 18px 60px #0000002e}.folders:not([open]){display:none}.folders::backdrop{background:#0000002e}.folders h2{margin:0;font-size:16px;font-weight:600}.folders .frow{align-items:center;gap:8px;display:flex}.folders .frow input{border:1px solid var(--line,#e5e5e2);min-width:0;height:32px;font:inherit;border-radius:9px;flex:1;padding:0 10px}.folders .frow.end{justify-content:flex-end}.folders .full{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;font-size:12px;overflow:hidden}.folders .chip.on{background:#00000012}.folders .chip.primary{background:var(--ink);color:#fff}.folders .chip.primary:disabled{opacity:.4}.folders .crumbs{color:var(--mute);flex-wrap:wrap;gap:2px;font-size:13px;display:flex}.folders .crumbs button+button:before{content:"/";color:#c4c4c0;margin-right:4px}.folders .dirs{border-top:1px solid #0000000f;border-bottom:1px solid #0000000f;flex-direction:column;flex:1;min-height:160px;padding:4px 0;display:flex;overflow-y:auto}.folders .dir{text-align:left;border-radius:8px;padding:6px 8px}.folders button.dir:hover{background:#0000000b}.folders .dir.off{color:var(--mute)}.signedout{color:var(--mute);text-align:center;background:#fff;place-items:center;padding:16px;font-size:14px;display:grid;position:fixed;inset:0}.railtoggle{width:34px;height:34px;color:var(--mute);border-radius:10px;flex:none;place-items:center;display:grid;position:relative}.railtoggle:hover{color:var(--ink);background:#0000000f}.railtoggle.on{color:var(--ink);background:#efeff1}.rail{width:0;transition:width .2s var(--ease);background:#fff;flex:none;overflow:hidden}.win[data-rail="1"] .rail{width:280px}.rail-in{border-left:1px solid var(--line);flex-direction:column;width:280px;min-width:0;height:100%;display:flex}.rail-h{border-bottom:1px solid var(--line);height:54px;color:var(--ink);flex:none;align-items:center;padding:0 20px;font-size:14.5px;font-weight:600;display:flex}.rail-b{scrollbar-width:thin;flex:1;overflow-y:auto}.grow{flex:1}.mono{color:var(--mute);font:11.5px ui-monospace,Menlo,monospace}.r-sec{padding:4px 0 10px;position:relative}.r-sec:after{content:"";background:var(--line);height:1px;position:absolute;bottom:0;left:20px;right:20px}.r-sec.closed{padding-bottom:4px}.r-sh{text-align:left;width:100%;height:38px;color:var(--ink);align-items:center;gap:6px;padding:0 20px;font-size:14.5px;display:flex}.r-sh b{font-weight:500}.r-cnt{color:var(--mute);font-variant-numeric:tabular-nums;font-size:13.5px}.r-ic{width:18px;height:18px;color:var(--mute);flex:none;place-items:center;display:grid}.rail .i16{width:18px;height:18px}.r-chev{color:var(--mute);opacity:0;transition:transform .15s var(--ease), opacity .12s;flex:none;place-items:center;display:grid}.r-sh:hover .r-chev,.r-sh:focus-visible .r-chev,.closed>.r-sh .r-chev,.r-row .r-chev{opacity:1}.closed>.r-sh .r-chev,.r-chev.turned{transform:rotate(-90deg)}.r-row{width:calc(100% - 16px);height:34px;color:var(--ink);text-align:left;cursor:pointer;border-radius:8px;align-items:center;gap:10px;margin:0 8px;padding:0 12px;font-size:14.5px;display:flex}.r-row:hover{background:#0000000d}.r-row.dim{color:var(--mute)}.r-row.r-br,.r-row.r-st{cursor:default}.r-row.r-br:hover,.r-row.r-st:hover{background:0 0}.r-grp{margin-top:6px}.r-gh{color:var(--mute);margin:4px 20px 2px;font-size:12px}.r-more{color:var(--mute);margin:0 20px;padding:4px 12px;font-size:12.5px;display:block}.r-more:hover{color:var(--ink)}.r-note{color:var(--mute);margin:4px 20px;font-size:12.5px}.r-note.err{color:#9a3412}.r-nm{white-space:nowrap;text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.r-nm.mono{color:inherit;font-size:13px}.r-sub{color:var(--mute)}.r-mt{color:var(--mute);font-variant-numeric:tabular-nums;flex:none;font-size:13px}.r-mt .add,.r-sh .add{color:var(--green)}.r-mt .del,.r-sh .del{color:var(--red)}.r-stop{opacity:.7;border-radius:6px;flex:none;place-items:center;width:20px;height:20px;display:grid}.r-stop:hover{opacity:1;background:#e5e5ea}.r-stop i{background:var(--ink);border-radius:2px;width:8px;height:8px}.r-ctxv{font-variant-numeric:tabular-nums;color:var(--mute);white-space:nowrap;font-size:13px}.r-ctxv b{color:var(--ink);font-weight:600}.r-meter{background:#ebebef;border-radius:999px;height:6px;margin:0 20px 6px;display:flex;position:relative}.r-meter b{background:var(--blue);height:100%;transition:width .8s var(--ease);flex:none;display:block}.r-meter b:first-of-type{border-radius:999px 0 0 999px}.r-meter b:last-of-type{border-radius:0 999px 999px 0}.r-meter b:only-of-type{border-radius:999px}.seg-conversation{background:var(--blue)!important}.seg-system{background:#8b5cf6!important}.seg-instructions{background:#14b8a6!important}.seg-tools{background:#f97316!important}.seg-free{background:#ebebef;box-shadow:inset 0 0 0 1px #dcdce1}.r-parts{flex-direction:column;grid-column:1/-1;gap:2px;margin-bottom:8px;display:flex}.r-part{height:24px;color:var(--ink);grid-template-columns:10px 1fr auto 48px;align-items:center;gap:8px;display:grid}.r-part .sw{border-radius:2px;width:9px;height:9px}.r-part span{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.r-part b{color:var(--mute);text-align:right;font-variant-numeric:tabular-nums;font-weight:500}.r-part em{color:var(--ink);text-align:right;font-variant-numeric:tabular-nums;font-style:normal}.r-parts small{color:var(--mute);margin-top:2px;font-size:12.5px}.r-act{color:var(--ink);white-space:nowrap;background:#fff;border:1px solid #d5d5da;border-radius:7px;flex:none;margin-left:4px;padding:2px 9px;font-size:12px}.r-act:hover{background:var(--sunk)}.r-pr{text-decoration:none}.r-ci{font-variant-numeric:tabular-nums;color:var(--green);flex:none;font-size:13px}.r-ci.run{color:var(--amber)}.r-ci.bad{color:var(--red)}.dlg-veil{z-index:210;background:#14141852;place-items:center;padding:16px;display:grid;position:fixed;inset:0}.dlg{width:min(520px,100%);max-height:calc(100vh - 32px);animation:in .15s var(--ease) both;background:#fff;border-radius:14px;padding:18px 20px;overflow:auto;box-shadow:0 24px 70px #00000040}.dlg h3{margin:0 0 4px;font-size:15px}.dlg-sub{margin-bottom:10px}.dlg-l{color:var(--mute);margin:10px 0 4px;font-size:12px;display:block}.dlg-in{width:100%;font:inherit;resize:vertical;border:1px solid #dfdfe4;border-radius:9px;padding:8px 10px;font-size:13px}.dlg-files{flex-direction:column;gap:2px;max-height:200px;padding:4px 0;display:flex;overflow:auto}.dlg-file{align-items:center;gap:8px;font-size:12.5px;display:flex}.dlg-file small{color:var(--mute)}.dlg-err{color:#9a3412;background:#fff4ec;border-radius:8px;margin-top:10px;padding:7px 10px;font-size:12.5px}.dlg-btns{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.dlg-btns button{background:#fff;border:1px solid #d5d5da;border-radius:9px;padding:6px 14px;font-size:13px}.dlg-btns .go{background:var(--ink);border-color:var(--ink);color:#fff}.dlg-btns button:disabled{opacity:.6}.r-kv{color:var(--ink);grid-template-columns:1fr auto;gap:4px 10px;margin:4px 20px 6px;font-size:13.5px;display:grid}.r-kv b{color:var(--ink);font-variant-numeric:tabular-nums;text-align:right;font-weight:500}.r-kv small{color:var(--mute);grid-column:1/-1;margin-top:4px;font-size:12.5px}.tip{z-index:150;width:236px;box-shadow:0 14px 50px #0000002e, 0 0 0 1px var(--line);color:#444;pointer-events:none;animation:in .18s var(--ease) both;background:#fff;border-radius:14px;padding:12px 14px;font-size:12.5px;position:fixed;right:290px}.tip h6{color:var(--mute);letter-spacing:.04em;word-break:break-all;margin:0 0 8px;font-size:12px;font-weight:500}.tip .kv{justify-content:space-between;gap:12px;padding:3px 0;display:flex}.tip .kv b{color:var(--ink);font-variant-numeric:tabular-nums;text-align:right;word-break:break-all;font-weight:600}.tip .lg{color:#d9d9dc;white-space:pre-wrap;word-break:break-all;background:#161618;border-radius:8px;margin-top:6px;padding:8px 10px;font:11.5px/1.6 ui-monospace,Menlo,monospace}.tip .tnote{color:var(--mute);margin-top:6px}.dlg-p{color:#444;margin:4px 0 6px;font-size:13px;line-height:1.55}.dlg-btns .go.danger{background:#c0392b;border-color:#c0392b}.work{flex:1 1 0;min-width:0;display:flex;position:relative}.chat{flex:320px;min-width:320px;position:relative}.panel{border-left:1px solid var(--line);min-width:320px;animation:in .2s var(--ease) both;background:#fff;flex-direction:column;flex:0 50%;display:flex;position:relative;overflow:hidden}.panel.full{flex:100%}.work.paneled:has(.panel.full) .chat{flex:0 0 0;min-width:0;overflow:hidden}@container (width<=639px){.work.paneled .chat{flex:0 0 0;min-width:0;overflow:hidden}.work.paneled .panel{flex:auto;min-width:0}}.panel.full.clear .pv-h{padding-left:132px}.pv-h{border-bottom:1px solid var(--line);flex:none;align-items:center;gap:2px;height:54px;padding:0 12px;display:flex}.pv-h .name{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:7px;min-width:0;margin-right:auto;font-weight:600;display:inline-flex;overflow:hidden}.sbtn{width:34px;height:34px;color:var(--mute);border-radius:10px;place-items:center;display:grid}.sbtn:hover{color:var(--ink);background:#0000000f}.pv-b{flex:1;padding:12px;overflow:auto}.pv-b.flush{flex-direction:column;padding:0;display:flex}.pnote{color:var(--mute);padding:6px 2px;font-size:12px}.pnote.warn{color:var(--amber);padding:6px 10px}.pv-b .empty{color:var(--mute);text-align:left;margin:0;padding:4px 0;font-size:13.5px}.pad{padding:20px 16px!important}.morebtn{width:34px;height:34px;color:var(--mute);border-radius:10px;flex:none;place-items:center;display:grid;position:relative}.morebtn:hover{color:var(--ink);background:#0000000f}.menu{z-index:120;min-width:210px;box-shadow:0 12px 44px #00000029, 0 0 0 1px var(--line);animation:in .2s var(--ease) both;background:#fff;border-radius:14px;padding:6px;position:absolute;top:50px;right:12px}.menu button{text-align:left;border-radius:9px;align-items:center;gap:10px;width:100%;padding:8px 10px;font-size:14px;display:flex}.menu button:hover{background:#f4f4f6}.menu .ico{color:#777}.diff{border:1px solid var(--line);background:#fafaf9;border-radius:10px;margin-bottom:10px;font:12.5px/1.7 ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.diff div{white-space:pre-wrap;word-break:break-all;padding:0 12px}.diff .a{color:#176b3a;background:#e8f6ec}.diff .d{color:#a33636;background:#fbe9e9}.diff .h{color:var(--mute);background:#f1f1ef;padding:4px 12px}.log{color:#d9d9dc;white-space:pre-wrap;word-break:break-all;background:#161618;border-radius:12px;min-height:120px;padding:14px;font:12.5px/1.7 ui-monospace,Menlo,monospace}.log.txt{color:#333;border:1px solid var(--line);background:#fafaf9}.tmeta{padding:4px 0 8px}.tmeta b{font-weight:600}.tdet{grid-template-columns:auto 1fr;gap:2px 12px;margin:0 0 10px;font-size:12.5px;display:grid}.tdet dt{color:var(--mute)}.tdet dd{word-break:break-all;margin:0}.cmd{margin-bottom:12px}.crumbs{color:var(--mute);flex-wrap:wrap;gap:2px;margin-bottom:8px;font-size:12.5px;display:flex}.crumbs button:hover,.crumb:hover{color:var(--ink)}.crumb{color:var(--mute);margin-bottom:10px;font-size:12.5px}.tree{font-size:13.5px}.tree button{text-align:left;border-radius:8px;justify-content:space-between;gap:10px;width:100%;padding:7px 8px;display:flex}.tree button:hover{background:#f4f4f2}.tree button:disabled{opacity:.6;cursor:default}.tree span{color:var(--mute);flex:none}.tree span.plus{color:var(--green)}.imgprev{max-width:100%;box-shadow:0 0 0 1px var(--line);border-radius:10px}[data-panel-body=open] .imgprev{cursor:zoom-in}[data-panel-body=open] .imgprev.actual{cursor:zoom-out;max-width:none}.modes{gap:4px;padding:0 0 10px;display:flex}.modes button{color:var(--mute);border-radius:7px;padding:3px 10px;font-size:12.5px}.modes button:hover,.modes button.on{color:var(--ink);background:#f3f3f5}.mdprev{padding:4px 6px}.browser{flex-direction:column;height:100%;display:flex}.urlbar{border-bottom:1px solid var(--line);background:#f7f7f8;align-items:center;gap:8px;padding:8px 10px;display:flex}.urlbar .u{color:#555;font:inherit;box-shadow:0 0 0 1px var(--line);background:#fff;border:0;border-radius:8px;outline:0;flex:1;padding:4px 10px;font-size:13px}.chips{flex-wrap:wrap;gap:6px;padding:6px 10px;display:flex}.chips button{background:#f3f3f5;border-radius:10px;padding:2px 10px;font-size:12px}.browser iframe{background:#fff;border:0;flex:1;width:100%}.click{cursor:pointer}.homebox{flex-direction:column;justify-content:center;align-items:center;gap:28px;padding:0 20px 60px;display:flex;position:absolute;inset:0}.homebox h1{letter-spacing:-.02em;text-align:center;margin:0;font-size:40px;font-weight:300}.comp.inline{width:min(680px,100%);position:static;transform:none}.trayfold{position:relative}.chip{color:#444;background:#f3f3f5;border:0;border-radius:15px;align-items:center;gap:6px;height:30px;padding:0 12px;font-size:13px;display:inline-flex}.chip:hover{background:#ebebee}select.chip{appearance:none;cursor:pointer;font:inherit;padding-right:14px;font-size:13px}.fmenu{min-width:220px;inset:auto auto 36px 0}.mlabel{color:var(--mute);padding:6px 10px 2px;font-size:11.5px}.guide{text-align:left;background:#fff;border-radius:18px;flex-direction:column;gap:10px;width:min(560px,100%);padding:22px 24px;display:flex;box-shadow:0 8px 30px #00000012,0 0 0 1px #0000000a}.guide h2{margin:0;font-size:18px;font-weight:600}.guide p{color:#555;margin:0 0 6px}.guide label{color:var(--mute);font-size:12.5px}.guide input{font:inherit;border:1px solid var(--line);border-radius:10px;outline:0;width:100%;padding:8px 12px}.gprofile{text-align:left;background:#f6f6f8;border-radius:10px;align-items:baseline;gap:8px;padding:9px 12px;display:flex}.gprofile:hover{background:#ededf1}.gprofile span{color:var(--mute);font-size:12.5px}.gprofile small{color:var(--amber);margin-left:auto}.gdemo{color:var(--blue);align-self:flex-start;margin-top:4px}.grow-row{gap:8px;display:flex}[data-panel-body=open].served{flex-direction:column;height:100%;display:flex}.pageview{width:100%;min-height:60vh;box-shadow:0 0 0 1px var(--line);background:#fff;border:0;border-radius:8px;flex:1}.mediaview{width:100%}.hdr{z-index:60;border-bottom:1px solid var(--line);background:#fff;align-items:center;gap:4px;min-width:0;height:54px;padding:0 10px 0 14px;display:flex;position:absolute;top:0;left:0;right:0}.win[data-side="0"] .hdr{padding-left:54px}.hdr-title{min-width:0;max-width:55%;color:var(--ink);white-space:nowrap;text-overflow:ellipsis;text-align:left;border-radius:8px;padding:5px 8px;font-size:14px;font-weight:600;overflow:hidden}.hdr-title:hover{background:var(--sunk)}input.hdr-title.edit{width:min(440px,55%);max-width:none;font:inherit;background:0 0;border:0;outline:0;font-size:14px;font-weight:600}input.hdr-title.edit:hover{background:0 0}.hdr-title.edit::selection{background:#cfe0ff}.ptabs{flex:1;align-items:center;gap:2px;min-width:0;margin-right:auto;display:flex;overflow:hidden}.ptab{color:#555;cursor:pointer;white-space:nowrap;border-radius:9px;flex:0 auto;align-items:center;gap:6px;min-width:0;max-width:200px;height:32px;padding:0 6px 0 10px;font-size:13px;display:inline-flex}.ptab>span{text-overflow:ellipsis;min-width:0;overflow:hidden}.ptab:hover{background:var(--sunk)}.ptab.on{color:var(--ink);box-shadow:0 0 0 1px var(--line);background:#fff}.ptab .i16{color:var(--mute)}.ptab-x{width:18px;height:18px;color:var(--faint);border-radius:5px;flex:none;place-items:center;display:grid}.ptab-x:hover{color:var(--ink);background:#e7e7ea}.ptab-x .i16{width:12px;height:12px}.tabpane{flex-direction:column;flex:1;min-height:0}.urlbar a,.urlbar button{color:#555;border-radius:7px;place-items:center;width:28px;height:28px;display:grid}.urlbar a:hover,.urlbar button:hover{background:#ececef}
|