Before this, only MAGPIE_ADDR could move the gateway, and the app on a Mac or one started from the Start menu has no easy way to set an env var. The setting: - Settings has a Gateway port field. Any port from 1024 to 65535 can be typed, then applied with Apply or Enter. - The port is saved in settings.json and kept on this computer (KeepOwn), so a backup or WebDAV doesn't carry it across. - MAGPIE_ADDR, where it is set, still comes first. The field is then off and says so. - A port out of range is refused in the page. - A port another program listens on is refused: "port N is in use by another program: pick another one". The gateway stays where it was. - With another magpie serving the gateway, the field says to set the port there. On a change: - The listener moves live (Relisten listens on the new port before closing the old one). - When the old port had been taken by another program and nothing served, the gateway starts on the new one. - Every agent connected to magpie has its config rewritten with the new URL (agent.OnGateway before the move, agent.Rewire after): - each one whose wiring is now "unwired" is set again; - Codex signed in with ChatGPT is joined again and keeps its own model; - Cursor Private Inference's variables and dsh's routes follow. - What each agent had before magpie (the stash) is kept through this. Before, setting an agent again on the old URL would have written magpie's old URL and token over it. - The page says how many agents moved. What follows the saved port (through gateway.Addr()/URL() and settings.GatewayAddr): - the CLI and healthcheck; - Running(); - LAN sharing (Port); - the drift check for the installed magpie, from beside a MAGPIE_ADDR one; - importapps' "is this entry magpie's own" check. zh, ja and de strings. Tests, all failing on the old code: - TestPortMovesEveryAgent: every agent with a config file is connected at 3591 and moved to 3592. No file keeps 3591, and none is off afterwards. - TestPortMovesJoinedCodex. - TestPortLeavesAnUnwiredAgent. - TestPortKeepsWhatAnAgentHadBefore: the relay URL and own token come back on disconnect. - TestDriftInstalledMagpieOnItsPort. - TestSetPortMovesTheGateway, through the API: taken, out of range, moved, the old port silent, POST /api/settings keeps it, MAGPIE_ADDR refused. - TestSetPortServesWhenTheOldOneWasTaken. - TestGatewayURLOnSettingsPort. - gateway-port.test.cjs on WebKit, en and zh: - out of range, taken (translated), applied by Enter, the agents counted, the new URL shown; - the MAGPIE_ADDR state; - no select, no left border, and the page never scrolls (the row is swapped whole, or WebKit laid the list out empty and the view jumped). Sandbox run (own HOME, settings port 3591, magpie web on 3593): - Claude Code (over a relay with its own token) and Codex were connected at 3591. - POST /api/settings/port: - 3594, held by another program: refused, in use; - 80: refused; - 3592: moved [Claude Code, Codex]. - Both configs then say 3592. The gateway answers on 3592 and not on 3591, and `magpie healthcheck` exits 0. - `magpie claude default` gave back https://relay.example and own-token. lan-docker, settings-sections, settings-groups, click-scroll, gateway-caller-keys, gui-ja, gui-de and webdav-settings-refresh pass on WebKit. go vet, the builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass.
2941 lines
232 KiB
CSS
2941 lines
232 KiB
CSS
/* magpie — one quiet surface, real logos, controls that read as pop-up buttons. */
|
||
:root {
|
||
--bg: #f4f4f6;
|
||
--card: #ffffff;
|
||
--card-2: #f9f9fb; /* expanded editor */
|
||
--pill: #f1f1f4;
|
||
--pill-hover: #e9e9ee;
|
||
/* the header's view switch: its track and the thumb on the view shown, the
|
||
track a shade deeper than a pill so the white thumb stands off it (#477) */
|
||
--seg-track: #e6e6eb;
|
||
--seg-thumb: var(--card);
|
||
--seg-edge: 0 1px 2px rgba(0, 0, 0, .14), 0 0 0 .5px rgba(0, 0, 0, .08);
|
||
/* a control's quiet text (the switch's other views, a text button): darker
|
||
than --muted, so it reads at 4.5:1 or better on every surface it sits on */
|
||
--ctl-fg: #63636b;
|
||
--line: #e3e3e8;
|
||
--line-2: #ececf0;
|
||
--fg: #1c1c21;
|
||
--fg-2: #4b4b53;
|
||
--muted: #85858d;
|
||
--faint: #b9b9c2;
|
||
--accent: #4f46e5;
|
||
--accent-soft: #eeedfd;
|
||
--accent-fg: #ffffff;
|
||
--sel: #ecebfb;
|
||
--green: #189a58;
|
||
--green-soft: #e4f6ec;
|
||
--red: #d64545;
|
||
--red-soft: #fbe9e9;
|
||
--amber: #b45309;
|
||
--amber-soft: #fbf0df;
|
||
/* an agent magpie set up that no longer goes through it */
|
||
--drift: #ce2c31;
|
||
--drift-soft: #feebec;
|
||
--pop-bg: rgba(255, 255, 255, .94);
|
||
--shadow: 0 16px 44px rgba(20, 22, 30, .16), 0 2px 8px rgba(20, 22, 30, .06), 0 0 0 .5px rgba(20, 22, 30, .1);
|
||
--font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
|
||
--code: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||
--logo-invert: 0;
|
||
--tk-s: #1a7f45; --tk-k: #7c3aed; --tk-f: #1d4ed8; --tk-n: #b45309; --tk-v: #0e7490; --tk-o: #a21caf; --tk-c: #85858d;
|
||
/* what a chart tells apart: providers, agents, models */
|
||
--c1: #4f46e5; --c2: #0ea5e9; --c3: #10b981; --c4: #f59e0b; --c5: #ec4899; --c6: #8b5cf6; --c7: #64748b;
|
||
}
|
||
@media (prefers-color-scheme: dark) {
|
||
:root:not([data-theme="light"]) {
|
||
--bg: #1a1a1e;
|
||
--card: #232327;
|
||
--card-2: #1f1f23;
|
||
--pill: #2d2d33;
|
||
--pill-hover: #36363d;
|
||
--seg-track: rgba(255, 255, 255, .035);
|
||
--seg-thumb: rgba(255, 255, 255, .15);
|
||
--seg-edge: inset 0 .5px 0 rgba(255, 255, 255, .08), 0 1px 2px rgba(0, 0, 0, .3);
|
||
--line: #333339;
|
||
--line-2: #2c2c32;
|
||
--fg: #ededf1;
|
||
--fg-2: #b9b9c1;
|
||
--muted: #8b8b94;
|
||
--faint: #56565f;
|
||
--ctl-fg: #a1a1aa;
|
||
--accent: #a5b4fc;
|
||
--accent-soft: #2b2c47;
|
||
--accent-fg: #14142a;
|
||
--sel: #33345a;
|
||
--green: #6fd99b;
|
||
--green-soft: #1e3a2b;
|
||
--red: #f28b82;
|
||
--red-soft: #45272a;
|
||
--amber: #f2b544;
|
||
--amber-soft: #3f3220;
|
||
--drift: #ff9592;
|
||
--drift-soft: #3b1219;
|
||
--pop-bg: rgba(38, 38, 43, .96);
|
||
--shadow: 0 16px 44px rgba(0, 0, 0, .55), 0 2px 8px rgba(0, 0, 0, .3), 0 0 0 .5px rgba(255, 255, 255, .1);
|
||
--logo-invert: 1;
|
||
--tk-s: #98d8a4; --tk-k: #c4b5fd; --tk-f: #93c5fd; --tk-n: #f2b544; --tk-v: #67e8f9; --tk-o: #f0abfc; --tk-c: #8b8b94;
|
||
--c1: #a5b4fc; --c2: #7dd3fc; --c3: #6ee7b7; --c4: #fcd34d; --c5: #f9a8d4; --c6: #c4b5fd; --c7: #94a3b8;
|
||
}
|
||
}
|
||
:root[data-theme="dark"] {
|
||
--bg: #1a1a1e; --card: #232327; --card-2: #1f1f23; --pill: #2d2d33; --pill-hover: #36363d;
|
||
--seg-track: rgba(255, 255, 255, .035); --seg-thumb: rgba(255, 255, 255, .15); --seg-edge: inset 0 .5px 0 rgba(255, 255, 255, .08), 0 1px 2px rgba(0, 0, 0, .3);
|
||
--line: #333339; --line-2: #2c2c32; --fg: #ededf1; --fg-2: #b9b9c1; --muted: #8b8b94; --faint: #56565f; --ctl-fg: #a1a1aa;
|
||
--accent: #a5b4fc; --accent-soft: #2b2c47; --accent-fg: #14142a; --sel: #33345a;
|
||
--green: #6fd99b; --green-soft: #1e3a2b; --red: #f28b82; --red-soft: #45272a; --amber: #f2b544; --amber-soft: #3f3220;
|
||
--drift: #ff9592; --drift-soft: #3b1219;
|
||
--pop-bg: rgba(38, 38, 43, .96);
|
||
--shadow: 0 16px 44px rgba(0, 0, 0, .55), 0 2px 8px rgba(0, 0, 0, .3), 0 0 0 .5px rgba(255, 255, 255, .1);
|
||
--logo-invert: 1;
|
||
--tk-s: #98d8a4; --tk-k: #c4b5fd; --tk-f: #93c5fd; --tk-n: #f2b544; --tk-v: #67e8f9; --tk-o: #f0abfc; --tk-c: #8b8b94;
|
||
--c1: #a5b4fc; --c2: #7dd3fc; --c3: #6ee7b7; --c4: #fcd34d; --c5: #f9a8d4; --c6: #c4b5fd; --c7: #94a3b8;
|
||
}
|
||
/* Windows' own text faces, and Chinese in YaHei UI, its UI face for it, not
|
||
the webview's fallback; the Mac's and Linux's stack is the one above */
|
||
:root.win { --font: "Segoe UI Variable Text", "Segoe UI", "Microsoft YaHei UI", "Microsoft YaHei", system-ui, sans-serif; }
|
||
/* and its code faces, with YaHei UI for the Chinese in them: the generic
|
||
monospace is SimSun on a Chinese Windows, thin and unhinted at 11px (#690) */
|
||
:root.win { --code: "Cascadia Mono", Consolas, "Microsoft YaHei UI", "Microsoft YaHei", monospace; }
|
||
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html, body { height: 100%; }
|
||
body {
|
||
font: 13px/1.4 var(--font);
|
||
color: var(--fg);
|
||
background: var(--bg);
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
-webkit-font-smoothing: antialiased;
|
||
user-select: none;
|
||
-webkit-user-select: none;
|
||
cursor: default;
|
||
}
|
||
/* The tray panel sits on a frosted NSVisualEffectView, so its own paint is thin. */
|
||
body.panel { --panel-tint: color-mix(in srgb, var(--bg) 93%, transparent); background: var(--panel-tint); border-radius: 12px; }
|
||
/* on the Mac the panel's colour is painted under the page, where it keeps up
|
||
with the panel as it grows (see tintPanel) */
|
||
body.panel.tinted { background: transparent; }
|
||
.tint-probe { display: none; background: var(--panel-tint); }
|
||
/* on the frosted panel the surfaces are tints of the backdrop, not flat paint */
|
||
@media (prefers-color-scheme: dark) {
|
||
:root:not([data-theme="light"]) body.panel { --bg: #1b1c20; --card: #25262c; --card-2: #212227; --line: rgba(255, 255, 255, .07); --line-2: rgba(255, 255, 255, .06); --pill: #2e2f36; --pill-hover: #383942; --pill-line: rgba(255, 255, 255, .11); --pill-shadow: 0 1px 2px rgba(0, 0, 0, .28); --muted: #9c9ca6; --faint: #7c7c87; --card-edge: inset 0 0 0 1px rgba(255, 255, 255, .06); }
|
||
}
|
||
:root[data-theme="dark"] body.panel { --bg: #1b1c20; --card: #25262c; --card-2: #212227; --line: rgba(255, 255, 255, .07); --line-2: rgba(255, 255, 255, .06); --pill: #2e2f36; --pill-hover: #383942; --pill-line: rgba(255, 255, 255, .11); --pill-shadow: 0 1px 2px rgba(0, 0, 0, .28); --muted: #9c9ca6; --faint: #7c7c87; --card-edge: inset 0 0 0 1px rgba(255, 255, 255, .06); }
|
||
@media (prefers-color-scheme: light) {
|
||
:root:not([data-theme="dark"]) body.panel { --bg: #f2f2f5; --card: #ffffff; --card-2: #f8f8fa; --line: rgba(0, 0, 0, .07); --line-2: rgba(0, 0, 0, .06); --pill: #ffffff; --pill-hover: #f4f4f7; --skel: #eeeef2; --skel-hi: #e2e2e8; --pill-line: rgba(0, 0, 0, .12); --pill-shadow: 0 1px 1px rgba(0, 0, 0, .06); --faint: #9a9aa3; --card-edge: 0 0 0 1px rgba(0, 0, 0, .05), 0 1px 2px rgba(0, 0, 0, .04); }
|
||
}
|
||
:root[data-theme="light"] body.panel { --bg: #f2f2f5; --card: #ffffff; --card-2: #f8f8fa; --line: rgba(0, 0, 0, .07); --line-2: rgba(0, 0, 0, .06); --pill: #ffffff; --pill-hover: #f4f4f7; --skel: #eeeef2; --skel-hi: #e2e2e8; --pill-line: rgba(0, 0, 0, .12); --pill-shadow: 0 1px 1px rgba(0, 0, 0, .06); --faint: #9a9aa3; --card-edge: 0 0 0 1px rgba(0, 0, 0, .05), 0 1px 2px rgba(0, 0, 0, .04); }
|
||
button { font: inherit; color: inherit; background: none; border: 0; cursor: default; appearance: none; -webkit-appearance: none; text-align: center; }
|
||
button:focus-visible, input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
||
input { font: inherit; color: var(--fg); }
|
||
.grow { flex: 1; }
|
||
[hidden] { display: none !important; }
|
||
code { font: 11.5px var(--code); }
|
||
|
||
/* ---- brand icons: colour ones are images, mono ones take the text colour --- */
|
||
/* a box of its own by default: a mask icon has no size to fall back on, and
|
||
one placed where nothing sizes it would otherwise not show at all */
|
||
.ic { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 16px; height: 16px; }
|
||
.ic img { width: 100%; height: 100%; object-fit: contain; display: block; }
|
||
.ic .mask { width: 100%; height: 100%; background: currentColor; -webkit-mask: var(--i) center / contain no-repeat; mask: var(--i) center / contain no-repeat; }
|
||
.ic.generic { color: var(--muted); }
|
||
/* a routing group's providers, overlapping discs with the first on top */
|
||
.ic-stack { display: inline-flex; flex: none; align-items: center; }
|
||
.ic-stack .disc { position: relative; width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--card); box-shadow: 0 0 0 1px var(--line); }
|
||
.ic-stack .disc + .disc { margin-left: -4px; }
|
||
.ic-stack .disc:nth-child(1) { z-index: 3; }
|
||
.ic-stack .disc:nth-child(2) { z-index: 2; }
|
||
.ic-stack .disc:nth-child(3) { z-index: 1; }
|
||
/* the stack sizes its own icons, whatever sizes the icons around it */
|
||
.ic-stack .disc > .ic { width: 13px !important; height: 13px !important; }
|
||
.ic-stack .more { font-size: 8.5px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.row .field .ic-stack .disc { width: 17px; height: 17px; }
|
||
.row .field .ic-stack .disc > .ic { width: 11px !important; height: 11px !important; }
|
||
.row .field .ic-stack .disc + .disc { margin-left: -4px; }
|
||
.ic.generic svg { width: 100%; height: 100%; }
|
||
|
||
/* ---- header --------------------------------------------------------------- */
|
||
.top { display: flex; align-items: center; gap: 8px; padding: 0 10px 0 14px; height: 46px; flex: none; position: relative; }
|
||
/* the traffic lights centre 25.75pt from the top, not 25; they are the window's, drawn in points, so at a larger text size (--zoom, the page's zoom) the header is that many fewer CSS pixels, still level with them */
|
||
body.window.mac .top { padding-left: calc(96px / var(--zoom, 1)); height: calc(50px / var(--zoom, 1)); padding-top: calc(2px / var(--zoom, 1)); }
|
||
body.window.mac .seg { top: calc(50% + 1px / var(--zoom, 1)); } /* 50% centres in the padding box; the 2px top padding puts the flex row a pixel lower */
|
||
.brand { display: flex; align-items: center; gap: 6px; font-weight: 600; letter-spacing: .01em; }
|
||
body.window:not(.mac):not(.linux):not(.web) .brand { display: none; } /* Windows' title bar above already shows the icon and the name; a browser tab has no title bar of the app's */
|
||
/* Linux: the header is the title bar, so it closes the window too — round,
|
||
as GNOME draws its close button, and set a little apart from the icons */
|
||
.icon.winclose { align-self: center; width: 22px; height: 22px; margin-left: 8px; border-radius: 50%; background: var(--pill); color: var(--fg-2); }
|
||
.icon.winclose:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); }
|
||
/* the magpie flaps, flicks its tail and bobs when the window opens and on
|
||
hover. It moves in pieces cut from the logo, and is drawn whole at rest, so
|
||
the cuts never show. */
|
||
.logo svg { display: block; overflow: visible; }
|
||
.logo .parts, .logo.wag .whole { display: none; }
|
||
.logo.wag .parts { display: inline; }
|
||
.logo .tail { transform-box: view-box; transform-origin: 14px 22px; }
|
||
.logo .wing { transform-box: view-box; transform-origin: 30px 19.8px; }
|
||
.logo .bird { transform-box: view-box; transform-origin: 26px 38px; }
|
||
.logo.wag .tail { animation: tail-flick .9s cubic-bezier(.3, 0, .3, 1); }
|
||
.logo.wag .wing { animation: wing-flap .9s cubic-bezier(.3, 0, .3, 1); }
|
||
.logo.wag .bird { animation: bird-bob .9s cubic-bezier(.3, 0, .3, 1); }
|
||
@keyframes wing-flap {
|
||
0%, 100% { transform: none; }
|
||
12% { transform: rotate(10deg); }
|
||
26% { transform: rotate(-3deg); }
|
||
40% { transform: rotate(8deg); }
|
||
56% { transform: rotate(-2deg); }
|
||
72% { transform: rotate(3deg); }
|
||
}
|
||
@keyframes tail-flick {
|
||
0%, 100% { transform: none; }
|
||
18% { transform: rotate(16deg); }
|
||
36% { transform: rotate(-7deg); }
|
||
54% { transform: rotate(9deg); }
|
||
72% { transform: rotate(-3deg); }
|
||
86% { transform: rotate(2deg); }
|
||
}
|
||
@keyframes bird-bob {
|
||
0%, 100% { transform: none; }
|
||
18% { transform: rotate(-4deg); }
|
||
40% { transform: rotate(2deg); }
|
||
62% { transform: rotate(-1deg); }
|
||
}
|
||
.logo { color: var(--fg); display: inline-flex; } /* ink, like the wordmark; the accent blue fought the text in light mode */
|
||
.seg {
|
||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
||
display: inline-flex; padding: 2px; border-radius: 8px;
|
||
/* no grey track behind the tabs: only the open one's thumb */
|
||
}
|
||
.seg > .thumb { border-radius: 6px; background: var(--seg-thumb); box-shadow: var(--seg-edge); }
|
||
body.panel .seg { display: none; }
|
||
.seg button { position: relative; z-index: 1; white-space: nowrap; height: 24px; padding: 0 12px; border-radius: 6px; font-size: 12.5px; color: var(--ctl-fg); transition: color .18s var(--ease), transform .14s var(--ease); }
|
||
.seg button.on { color: var(--fg); }
|
||
/* a plugin update waiting for the reader: a dot on Plugins */
|
||
.seg button.has-dot::after { content: ""; position: absolute; top: 4px; right: 4px; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
|
||
.seg button:hover:not(.on) { color: var(--fg-2); }
|
||
.actions { margin-left: auto; display: flex; gap: 2px; }
|
||
.icon {
|
||
width: 26px; height: 26px; border-radius: 7px;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
color: var(--muted);
|
||
transition: background .12s, color .12s;
|
||
}
|
||
.icon:hover, .icon.on { background: var(--pill); color: var(--fg); }
|
||
/* the icon turns on a layer of its own — painted in place, WebKit leaves
|
||
ghosts of each frame behind (#16) — and always finishes its turn */
|
||
.icon svg { transform-origin: 50% 50%; backface-visibility: hidden; }
|
||
.icon.spin svg { animation: spin .9s linear infinite; will-change: transform; }
|
||
/* a newer magpie is ready: a quiet pill before the header's icons */
|
||
.update {
|
||
align-self: center; display: inline-flex; align-items: center; gap: 4px;
|
||
height: 22px; margin-right: 6px; padding: 0 9px 0 7px; border-radius: 999px;
|
||
font-size: 11.5px; font-weight: 560; letter-spacing: .005em; white-space: nowrap;
|
||
color: var(--accent); background: var(--accent-soft);
|
||
box-shadow: inset 0 0 0 .5px color-mix(in srgb, var(--accent) 35%, transparent);
|
||
transition: background .15s, color .15s, transform .12s var(--ease), opacity .15s;
|
||
animation: update-in .45s var(--ease);
|
||
}
|
||
.update[hidden] { display: none; }
|
||
.update:hover { background: var(--accent); color: var(--accent-fg); }
|
||
.update:active { transform: scale(.96); }
|
||
.update.busy { pointer-events: none; opacity: .6; }
|
||
/* its × on the pill's corner, shown while the pointer is over it: hides
|
||
the pill until a newer version is out */
|
||
.update-wrap { position: relative; align-self: center; display: inline-flex; }
|
||
.update-hide {
|
||
position: absolute; top: -5px; right: 3px; width: 14px; height: 14px; border-radius: 50%;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
color: var(--muted); background: var(--card); box-shadow: 0 0 0 1px var(--line), 0 1px 2px rgba(0,0,0,.12);
|
||
opacity: 0; pointer-events: none; transition: opacity .12s, color .12s;
|
||
}
|
||
.update-wrap:hover .update-hide { opacity: 1; pointer-events: auto; }
|
||
.update-hide:focus-visible { opacity: 1; pointer-events: auto; } /* its own rule: Safari before 15.4 drops a list holding it */
|
||
.update-hide:hover { color: var(--fg); }
|
||
.update[hidden] + .update-hide, .update.busy + .update-hide { display: none; }
|
||
/* a narrow header (fitTop): the magpie without its name, Update as its arrow,
|
||
the tabs closer together, still in the middle of the window, and only when
|
||
they don't fit there, in the row rather than over it: halfway between what
|
||
is either side of them, not a third of the room their left and two thirds
|
||
their right (#442) */
|
||
.top.tight .brand > span:not(.logo), .top.tight .update span { display: none; }
|
||
.top.tight .update { width: 22px; padding: 0; justify-content: center; margin-right: 4px; }
|
||
body.window .top.inrow .seg { position: relative; left: auto; top: auto; transform: none; margin: 0 auto; } /* relative still: its thumb sits in it, not over the whole header */
|
||
body.window .top.inrow .actions { margin-left: 0; }
|
||
.top.cramped .seg button { padding: 0 8px; }
|
||
.top.crowded .seg button { padding: 0 6px; font-size: 12px; }
|
||
.top.crowded .brand { display: none; }
|
||
.top.packed .seg button { padding: 0 3px; font-size: 11.5px; }
|
||
/* and when even that doesn't fit, the tabs scroll sideways rather than push the page wider */
|
||
.top.packed .seg { min-width: 0; flex: 0 1 auto; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
|
||
.top.packed .seg::-webkit-scrollbar { display: none; }
|
||
/* magpie web on a phone, or a browser as narrow (phoneWeb): the magpie and
|
||
the icons in a row, the tabs at their size in a row of their own under
|
||
them, sliding sideways when they don't fit (they were squeezed into the
|
||
room between, too small to read or tap) */
|
||
@media (max-width: 760px), (pointer: coarse) and (max-width: 1024px) {
|
||
body.web .top {
|
||
height: auto; min-height: 48px; flex-wrap: wrap; gap: 4px 8px;
|
||
padding: calc(6px + env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 8px max(12px, env(safe-area-inset-left));
|
||
}
|
||
body.web .top .brand, body.web .top .actions { min-height: 40px; align-items: center; }
|
||
body.web .top #nav {
|
||
position: relative; left: auto; top: auto; transform: none;
|
||
order: 3; flex: 0 0 100%; min-width: 0; max-width: 100%;
|
||
overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none;
|
||
}
|
||
body.web .top #nav::-webkit-scrollbar { display: none; }
|
||
body.web .top #nav button { flex: none; height: 40px; padding: 0 14px; font-size: 14px; }
|
||
body.web .top .actions { gap: 4px; }
|
||
}
|
||
@keyframes update-in { from { opacity: 0; transform: translateY(-3px) scale(.94); } }
|
||
@keyframes spin { to { transform: rotate(360deg); } }
|
||
|
||
/* ---- lists ---------------------------------------------------------------- */
|
||
.view { flex: 1; min-height: 0; overflow-y: auto; padding: 0 12px 4px; display: flex; flex-direction: column; animation: view-in .24s var(--ease); }
|
||
@keyframes view-in { from { opacity: 0; transform: translateY(5px); } }
|
||
body.window .view { padding: 2px 16px 8px; }
|
||
.view > .view-room { flex: none; pointer-events: none; } /* see "where the reader is" */
|
||
.view::-webkit-scrollbar { width: 0; }
|
||
/* Windows and Linux draw a classic scrollbar, arrows and all; a thin rounded
|
||
thumb instead, like the overlay one macOS shows (left as it is there) */
|
||
:where(body:not(.mac)) ::-webkit-scrollbar { width: 10px; height: 10px; background: transparent; }
|
||
:where(body:not(.mac)) ::-webkit-scrollbar-thumb { background: var(--faint); border: 3px solid transparent; border-radius: 10px; background-clip: padding-box; }
|
||
:where(body:not(.mac)) ::-webkit-scrollbar-thumb:hover { background-color: var(--muted); }
|
||
:where(body:not(.mac)) ::-webkit-scrollbar-button, :where(body:not(.mac)) ::-webkit-scrollbar-corner { display: none; background: transparent; }
|
||
.list { background: var(--card); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; flex: none; }
|
||
body.panel .list { border: 0; border-radius: 10px; box-shadow: var(--card-edge); }
|
||
.row { display: flex; align-items: center; gap: 9px; min-height: 40px; padding: 5px 9px 5px 11px; }
|
||
body.window .row { min-height: 48px; padding: 7px 12px 7px 14px; gap: 12px; }
|
||
.row + .row, .editor + .row, .row + .editor { border-top: 1px solid var(--line-2); }
|
||
.row .ic { width: 18px; height: 18px; }
|
||
body.window .row .ic { width: 22px; height: 22px; }
|
||
.row .name { font-weight: 500; letter-spacing: -.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
|
||
.row .who { min-width: 0; flex: 1 1 auto; }
|
||
.row .sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
|
||
.empty-state { padding: 36px 20px; text-align: center; color: var(--muted); }
|
||
.empty-state b { display: block; color: var(--fg); font-weight: 500; margin-bottom: 4px; }
|
||
|
||
/* the last row of the list: the agents nothing is set on, folded away */
|
||
.agent-more { display: flex; align-items: center; justify-content: center; gap: 5px; width: 100%; border: 0; border-top: 1px solid var(--line-2); background: none; font: inherit; font-size: 12px; color: var(--muted); padding: 9px; cursor: pointer; transition: color .2s, background-color .2s; }
|
||
.agent-more:hover { color: var(--fg); background: var(--card-2); }
|
||
.agent-more span { display: inline-flex; }
|
||
.agent-more .chev { transition: transform .5s cubic-bezier(.22, 1, .36, 1); }
|
||
.agent-more[aria-expanded="true"] .chev { transform: rotate(180deg); }
|
||
/* the folded agents unroll like a scroll: the height opens on a long ease-out,
|
||
each row settles in a beat after the one above, and the unrolling edge is
|
||
soft while it moves. Rolling up is quicker, bottom row first. */
|
||
.agent-fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .42s cubic-bezier(.4, 0, .2, 1); }
|
||
.agent-fold.open { grid-template-rows: 1fr; transition-duration: .62s; transition-timing-function: cubic-bezier(.22, 1, .36, 1); }
|
||
.agent-fold-inner { min-height: 0; overflow: hidden; }
|
||
.agent-fold-inner > .row:first-child { border-top: 1px solid var(--line-2); }
|
||
.agent-fold.moving .agent-fold-inner { -webkit-mask-image: linear-gradient(#000 calc(100% - 32px), transparent); mask-image: linear-gradient(#000 calc(100% - 32px), transparent); }
|
||
.agent-fold .row { opacity: 0; transform: translateY(-10px) scale(.985); transform-origin: 50% 0; transition: opacity .22s ease, transform .32s cubic-bezier(.4, 0, .2, 1); transition-delay: calc((var(--n) - 1 - var(--i)) * 22ms); }
|
||
.agent-fold.open .row { opacity: 1; transform: none; transition: opacity .42s ease, transform .56s cubic-bezier(.22, 1, .36, 1); transition-delay: calc(70ms + var(--i) * 48ms); }
|
||
|
||
/* the logo is the row's handle: drag it to move the row, and a click opens
|
||
the row's menu (Move up, Move down, Hide). It stays the logo under the
|
||
pointer; the grip that says the row can be taken hold of is in its margin. */
|
||
.ag-handle { display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; margin: -3px; padding: 0; border: 0; border-radius: 6px; background: none; color: inherit; cursor: grab; touch-action: none; transition: background-color .15s; }
|
||
body.window .ag-handle { width: 28px; height: 28px; }
|
||
.ag-handle > .ic { grid-area: 1 / 1; transition: opacity .15s; }
|
||
.ag-handle:hover, .ag-handle.open { background: var(--pill); }
|
||
.ag-handle:focus-visible { background: var(--pill); outline: 1.5px solid var(--fg-2); outline-offset: 0; }
|
||
.agent-fold .ag-handle { cursor: default; }
|
||
/* a row in the list carries a grip in its left margin, drawn only while the
|
||
row is under the pointer, dragged, or its handle has the keyboard or its
|
||
menu open: always there it is clutter (the owner: 一直出现太丑了), as on
|
||
the Providers list. It is the handle's own, so a drag or a click on it does
|
||
what the logo does, and it takes no room from the row; the logo stays the
|
||
logo. Hide is in the handle's menu and the row's right-click menu. */
|
||
#agents > .row .ag-handle { position: relative; }
|
||
#agents > .row .ag-handle::before { content: ""; position: absolute; left: -7px; top: 50%; width: 6px; height: 11px; margin-top: -5.5px; background: radial-gradient(circle, var(--muted) .9px, transparent 1.2px) 0 0 / 3px 3.75px; opacity: 0; transition: opacity .15s; }
|
||
body.panel #agents > .row .ag-handle::before { left: -10px; }
|
||
#agents > .row:is(:hover, .dragging) .ag-handle::before, #agents > .row .ag-handle.open::before { opacity: 1; }
|
||
#agents > .row .ag-handle:focus-visible::before { opacity: 1; }
|
||
/* one hidden by hand reads as put away, with its way back beside its name */
|
||
.agent-fold .row.put-away .ag-handle > .ic, .agent-fold .row.put-away .name { opacity: .6; }
|
||
.agent-fold .row.put-away .who { display: flex; align-items: center; gap: 8px; }
|
||
/* at the end of the name's column, so it comes up in one place down the rows */
|
||
.agent-fold .row .ag-show { margin-left: auto; }
|
||
.ag-show { display: inline-flex; align-items: center; gap: 4px; flex: none; height: 22px; padding: 0 8px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--fg-2); font: inherit; font-size: 11.5px; cursor: pointer; transition: background-color .15s, color .15s, border-color .15s; }
|
||
.ag-show:hover { background: var(--pill); color: var(--fg); }
|
||
/* always there, not only under the pointer: it is the way back for a row
|
||
hidden by hand, and has to be seen to be found (#479) */
|
||
.ag-show:focus-visible { outline: 1.5px solid var(--fg-2); outline-offset: 1px; }
|
||
.ag-show svg { color: var(--muted); }
|
||
/* an agent whose config was rewritten since magpie set it: a line under
|
||
its name saying so, and the button that sets it again */
|
||
/* a drifted agent: a coral pill on its name's line — the row keeps its
|
||
height and the pickers their columns */
|
||
.row.drifted .who { display: flex; align-items: center; gap: 7px; }
|
||
.row.drifted .who .name { flex: 0 1 auto; }
|
||
.ag-fix { display: inline-flex; align-items: center; gap: 4px; flex: none; height: 20px; padding: 0 8px 0 6px; border: 0; border-radius: 999px; background: var(--drift-soft); color: var(--drift); font: inherit; font-size: 11.5px; font-weight: 500; line-height: 1; cursor: pointer; transition: background-color .15s, color .15s, transform .12s; }
|
||
.ag-fix:hover { background: color-mix(in srgb, var(--drift) 16%, var(--drift-soft)); }
|
||
.ag-fix:active { transform: scale(.96); }
|
||
.ag-fix:focus-visible { outline: 1.5px solid var(--drift); outline-offset: 1px; }
|
||
.ag-fix.busy { pointer-events: none; opacity: .7; }
|
||
.ag-fix.busy svg { animation: spin .8s linear infinite; }
|
||
/* the agent's CLI on its name's line (#202): its version faint, and a quiet
|
||
pill that updates it when a newer one is out — the row keeps its height */
|
||
body.window .row.agent .who { display: flex; align-items: center; gap: 7px; container-type: inline-size; }
|
||
/* the name is the last to give way: where the row is tight the update
|
||
pill keeps only its arrow, then the version goes, and only then is the
|
||
name cut (it was "C." beside a full pill at the window's first width) */
|
||
body.window .row.agent .who .name { flex: 0 0 auto; max-width: 100%; }
|
||
body.window .row.agent .who .ag-cli { flex: 0 1 auto; overflow: hidden; }
|
||
@container (max-width: 250px) {
|
||
body.window .row.agent .ag-up { padding: 0 6px; }
|
||
body.window .row.agent .ag-up > span { display: none; }
|
||
}
|
||
@container (max-width: 150px) { body.window .row.agent .ag-ver { display: none; } }
|
||
.ag-cli { display: inline-flex; align-items: center; gap: 6px; flex: none; min-width: 0; }
|
||
.ag-cli:empty { display: none; }
|
||
.ag-missing { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default; }
|
||
.ag-ver { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; cursor: default; }
|
||
.ag-up { display: inline-flex; align-items: center; gap: 4px; flex: none; height: 20px; padding: 0 8px 0 6px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--fg-2); font: inherit; font-size: 11.5px; font-weight: 500; line-height: 1; white-space: nowrap; cursor: pointer; transition: background-color .15s, color .15s, transform .12s; }
|
||
.ag-up:hover { background: var(--pill); color: var(--fg); }
|
||
.ag-up:active { transform: scale(.96); }
|
||
.ag-up:focus-visible { outline: 1.5px solid var(--fg-2); outline-offset: 1px; }
|
||
.ag-up svg { color: var(--muted); }
|
||
.ag-up.busy { pointer-events: none; color: var(--muted); }
|
||
.ag-up.busy svg { animation: spin .8s linear infinite; }
|
||
@media (prefers-reduced-motion: reduce) { .ag-up.busy svg { animation: none; } }
|
||
/* Update all (#727): a line above the list once two or more agents' CLIs
|
||
are behind, its pill like a row's */
|
||
.ag-updates { flex: none; display: flex; align-items: center; gap: 10px; margin: 0 2px 10px; min-height: 22px; font-size: 12.5px; color: var(--fg-2); }
|
||
.ag-updates-say { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.ag-updates.failed .ag-updates-say { color: var(--red); }
|
||
/* the agents not on this machine (#727), under the list: a heading that
|
||
opens their install commands, each to copy */
|
||
.ag-install { flex: none; margin-top: 12px; }
|
||
.ag-install-head { display: inline-flex; align-items: center; gap: 5px; border: 0; background: none; font: inherit; font-size: 12.5px; color: var(--muted); padding: 4px 2px; cursor: pointer; transition: color .2s; }
|
||
.ag-install-head:hover { color: var(--fg); }
|
||
.ag-install-head span { display: inline-flex; }
|
||
.ag-install-head .chev { transition: transform .3s cubic-bezier(.22, 1, .36, 1); }
|
||
.ag-install-head[aria-expanded="true"] .chev { transform: rotate(180deg); }
|
||
.ag-install-head:focus-visible { outline: 1.5px solid var(--fg-2); outline-offset: 1px; border-radius: 4px; }
|
||
.ag-install-note { margin: 4px 2px 8px; font-size: 12px; line-height: 1.5; color: var(--muted); }
|
||
.ag-install-row { display: flex; align-items: flex-start; gap: 12px; padding: 9px 12px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; margin-bottom: 6px; }
|
||
.ag-install-who { display: flex; align-items: center; gap: 8px; flex: 0 0 150px; min-width: 0; padding-top: 2px; }
|
||
.ag-install-who .ic { width: 18px; height: 18px; flex: none; }
|
||
.ag-install-name { display: flex; flex-direction: column; min-width: 0; }
|
||
.ag-install-missing { font-size: 11px; color: var(--muted); white-space: nowrap; }
|
||
.ag-install-who b { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.ag-install-cmds { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-width: 0; }
|
||
.ag-install-cmd { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||
.ag-install-via { flex: 0 0 84px; font-size: 11.5px; color: var(--muted); }
|
||
.ag-install-cmd code { flex: 1 1 auto; min-width: 0; overflow-x: auto; white-space: nowrap; font-size: 11.5px; padding: 2px 6px; border-radius: 5px; background: var(--pill); color: var(--fg-2); }
|
||
@media (max-width: 600px) {
|
||
.ag-install-row { flex-direction: column; gap: 6px; }
|
||
.ag-install-who { flex: none; }
|
||
}
|
||
/* the panel's name column has no room for it: there it is a badge on the
|
||
agent's logo, the name and the columns left as every other row's */
|
||
body.panel .row.drifted { position: relative; }
|
||
body.panel .ag-fix { position: absolute; left: 20px; top: calc(50% + 1px); width: 14px; height: 14px; padding: 0; justify-content: center; background: var(--drift); color: var(--card); box-shadow: 0 0 0 2px var(--card); }
|
||
body.panel .ag-fix:hover { background: var(--drift); filter: brightness(1.08); }
|
||
body.panel .ag-fix svg { width: 9px; height: 9px; }
|
||
body.panel .ag-fix span { display: none; }
|
||
.row.drifted .field[data-key="model"] { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--drift) 38%, transparent); }
|
||
|
||
/* the line over each kind of folded agent: hidden by hand, or nothing set */
|
||
.agent-fold-cap { padding: 8px 11px 2px; font-size: 11px; font-weight: 500; color: var(--muted); letter-spacing: .02em; border-top: 1px solid var(--line-2); }
|
||
body.window .agent-fold-cap { padding: 10px 14px 3px; }
|
||
.agent-fold-cap + .row { border-top: 0; }
|
||
.agent-fold .agent-fold-cap { opacity: 0; transition: opacity .22s ease; }
|
||
.agent-fold.open .agent-fold-cap { opacity: 1; transition: opacity .42s ease; transition-delay: calc(70ms + var(--i) * 48ms); }
|
||
/* while a row is dragged the others slide out of its way */
|
||
#agents.sorting { user-select: none; -webkit-user-select: none; }
|
||
#agents.sorting > .row { transition: transform .22s cubic-bezier(.22, 1, .36, 1); }
|
||
#agents.sorting .ag-handle { cursor: grabbing; }
|
||
#agents > .row.dragging { position: relative; z-index: 2; background: var(--card); box-shadow: 0 6px 18px rgba(20, 22, 30, .12), 0 0 0 1px var(--line); border-radius: 8px; }
|
||
#agents > .row.dragging { transition: none; }
|
||
/* a provider on is moved as an agent is (#499): its logo is the handle,
|
||
the grip in its margin drawn only with the pointer on the row */
|
||
#providers > .row .pv-handle { position: relative; }
|
||
#providers > .row .pv-handle::before { content: ""; position: absolute; left: -7px; top: 50%; width: 6px; height: 11px; margin-top: -5.5px; background: radial-gradient(circle, var(--muted) .9px, transparent 1.2px) 0 0 / 3px 3.75px; opacity: 0; transition: opacity .15s; }
|
||
#providers > .row:is(:hover, .dragging) .pv-handle::before { opacity: 1; }
|
||
/* apart: Safari before 15.4 drops a whole selector list with :focus-visible in it */
|
||
#providers > .row .pv-handle:focus-visible::before { opacity: 1; }
|
||
#providers.sorting { user-select: none; -webkit-user-select: none; }
|
||
#providers.sorting > .row { transition: transform .22s cubic-bezier(.22, 1, .36, 1); }
|
||
#providers.sorting .pv-handle { cursor: grabbing; }
|
||
#providers > .row.dragging { position: relative; z-index: 2; background: var(--card); box-shadow: 0 6px 18px rgba(20, 22, 30, .12), 0 0 0 1px var(--line); border-radius: 8px; transition: none; }
|
||
|
||
.pop.row-menu { width: auto; min-width: 176px; max-height: none; padding: 4px; border: 1px solid var(--line); display: grid; gap: 1px; }
|
||
.row-menu .rm-item { display: flex; align-items: center; gap: 8px; width: 100%; height: 28px; padding: 0 8px; border: 0; border-radius: 7px; background: none; color: var(--fg); font: inherit; font-size: 12.5px; text-align: left; cursor: default; outline: none; }
|
||
.row-menu .rm-item svg { flex: none; color: var(--muted); }
|
||
.row-menu .rm-item:not(:disabled):is(:hover, :focus) { background: var(--pill); }
|
||
.row-menu .rm-item:disabled, .row-menu .rm-item:disabled svg { color: var(--faint); }
|
||
.row-menu .rm-name { flex: 1; }
|
||
.row-menu .rm-key { margin-left: 14px; font-size: 11px; color: var(--faint); }
|
||
.row-menu .rm-item.has-why { height: auto; max-width: 280px; padding: 6px 8px; align-items: flex-start; }
|
||
.row-menu .rm-item.has-why svg { margin-top: 2px; }
|
||
.row-menu .rm-why { display: block; margin-top: 3px; font-size: 11.5px; line-height: 1.4; color: var(--muted); white-space: normal; }
|
||
.row-menu .rm-sep { height: 1px; margin: 3px 6px; background: var(--line-2); }
|
||
|
||
/* an agent row: logo, name, then one pop-up button per setting */
|
||
/* two columns: the model, then the smaller setting; single controls sit at the end.
|
||
Fixed widths keep every chevron on the same vertical line down the list. */
|
||
.agent .who { flex: 1 1 auto; }
|
||
/* Two fixed columns: the model (or large model) fills the left, the second
|
||
setting the right, so every chip and its chevron lines up down the list.
|
||
A single control keeps the left column, so the model always sits in the
|
||
same place. */
|
||
.fields { display: grid; grid-template-columns: minmax(0, 1fr) 124px; gap: 5px; width: 350px; flex: none; margin-left: auto; }
|
||
body.panel .fields { width: 272px; grid-template-columns: minmax(0, 1fr) 118px; }
|
||
.field {
|
||
display: inline-flex; align-items: center; gap: 5px;
|
||
max-width: 100%; min-width: 0;
|
||
height: 25px; padding: 0 5px 0 8px;
|
||
border-radius: 6px;
|
||
background: var(--pill);
|
||
font-size: 12.5px;
|
||
transition: background .12s, box-shadow .12s;
|
||
}
|
||
/* on the panel a control is a real pop-up button: hairline edge, a breath of shadow */
|
||
body.panel .field { height: 24px; font-size: 12px; box-shadow: inset 0 0 0 1px var(--pill-line), var(--pill-shadow); }
|
||
body.panel .field:hover { box-shadow: inset 0 0 0 1px var(--pill-line), var(--pill-shadow); }
|
||
body.panel .field.open { box-shadow: inset 0 0 0 1px var(--accent), var(--pill-shadow); }
|
||
/* the tray panel keeps control-sized pills: a solo control spans both columns
|
||
and hugs the right — an economy the narrow panel wants */
|
||
/* a field that follows the model unless set: a square in a third column */
|
||
#agents { --extras: 1; --extras-w: calc(var(--extras) * 29px - 5px); }
|
||
#agents.extras .fields { width: calc(355px + var(--extras-w)); grid-template-columns: minmax(0, 1fr) 124px var(--extras-w); }
|
||
/* the panel has no width to give: a second square is taken from the model's
|
||
column, as the names were left three letters when the row grew with it */
|
||
body.panel #agents.extras .fields { width: 301px; grid-template-columns: minmax(0, 1fr) 118px var(--extras-w); }
|
||
.extras-cell { grid-column: 3; display: flex; justify-content: flex-end; gap: 5px; }
|
||
#agents.extras .field.solo { grid-column: 1 / 3; }
|
||
body.window #agents.extras .field.solo { grid-column: 1 / 3; }
|
||
.field.extra { grid-column: 3; width: 24px; padding: 0; justify-content: center; position: relative; color: var(--faint); }
|
||
.field.extra:hover, .field.extra.open { color: var(--fg-2); }
|
||
.field.extra.set { color: var(--fg); }
|
||
.field.extra.set::after { content: ""; position: absolute; top: 3px; right: 3px; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
|
||
.field.main, .field.solo { justify-self: end; }
|
||
.field.solo { grid-column: 1 / -1; }
|
||
/* in the window the chips fill their column, so every chip and chevron lines
|
||
up down the list and the model always sits in the same place */
|
||
body.window .field.main, body.window .field.solo { justify-self: stretch; }
|
||
body.window .field.solo { grid-column: auto; }
|
||
/* When a window is narrow (or zoomed in), the fixed-width setting columns
|
||
leave too little room for the agent names. Put them on the next line. */
|
||
@media (max-width: 600px) {
|
||
body.window .row.agent { display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: 12px; row-gap: 3px; }
|
||
body.window .row.agent > .ag-handle { grid-column: 1; grid-row: 1; }
|
||
body.window .row.agent > .who { grid-column: 2; grid-row: 1; width: 100%; }
|
||
body.window .row.agent > .fields { grid-column: 2; grid-row: 2; width: 100%; min-width: 0; margin-left: 0; }
|
||
body.window #agents.extras .row.agent > .fields { grid-template-columns: minmax(0, 1fr) 124px var(--extras-w); }
|
||
body.window .row.agent > .ag-conn { grid-column: 2; grid-row: 1; justify-self: end; margin-left: 0; }
|
||
}
|
||
.field:hover, .field.open { background: var(--pill-hover); }
|
||
.field.open { box-shadow: inset 0 0 0 1px var(--accent); }
|
||
.row .field .ic, body.window .row .field .ic { width: 14px; height: 14px; }
|
||
.field .effort-ic { color: var(--fg); }
|
||
.field .effort-ic svg { width: 100%; height: 100%; }
|
||
.field .k { color: var(--faint); font-size: 11.5px; flex: none; }
|
||
.field .v { min-width: 0; flex: 0 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; font-weight: 500; }
|
||
.field .chev { color: var(--faint); display: inline-flex; margin-left: auto; padding-left: 1px; }
|
||
.field:hover .chev, .field.open .chev { color: var(--muted); }
|
||
.field.flash, .subscription-card.flash, .pq-card.flash { animation: flash 1.2s ease-out; }
|
||
@keyframes flash { 0%, 35% { box-shadow: inset 0 0 0 1px var(--green); background: var(--green-soft); } 100% {} }
|
||
|
||
/* ---- usage ---------------------------------------------------------------- */
|
||
.usage-head { display: flex; align-items: center; gap: 10px; height: 34px; margin: 4px 0 6px; flex: none; }
|
||
.subscription-usage { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 7px; margin-bottom: 8px; flex: none; }
|
||
.subscription-card { padding: 10px 12px 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); min-width: 0; }
|
||
.subscription-head { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; }
|
||
.subscription-head .ic { width: 17px; height: 17px; }
|
||
.subscription-head b { font-size: 12.5px; font-weight: 600; }
|
||
.subscription-account { display: flex; align-items: baseline; gap: 7px; margin: 0 0 6px; font-size: 11px; color: var(--fg-2); }
|
||
.subscription-card.several .quota-windows:not([hidden]) + .subscription-account,
|
||
.subscription-card.several .subscription-error:not([hidden]) + .subscription-account,
|
||
.subscription-card.several .quota-balance:not([hidden]) + .subscription-account,
|
||
.subscription-card.several .quota-read:not([hidden]) + .subscription-account,
|
||
.subscription-card.several .credit-days:not([hidden]) + .subscription-account,
|
||
.subscription-card.several .quota-curve:not([hidden]) + .subscription-account { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line); }
|
||
.subscription-account .user { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
/* an account of several in brief (ARNO): its windows' names, figures and
|
||
bars, closer to the next (its line where a full one's is, so a fold keeps it in place); its fold at the row's end */
|
||
.subscription-card.several .subscription-account.brief:not(:nth-child(2)) { padding-top: 7px; }
|
||
.subscription-account.brief { margin-bottom: 4px; }
|
||
.quota-acct-fold { align-self: center; display: inline-grid; place-items: center; flex: none; width: 18px; height: 18px; margin: -2px -5px -2px -3px; padding: 0; border-radius: 4px; color: var(--faint); transition: background .12s, color .12s; }
|
||
.subscription-account .user + .quota-acct-fold { margin-left: auto; }
|
||
.quota-acct-fold:hover { background: var(--pill); color: var(--fg-2); }
|
||
.quota-acct-fold svg { transform: rotate(180deg); transition: transform .15s ease-out; }
|
||
.quota-acct-fold[aria-expanded="false"] svg { transform: none; }
|
||
@media (prefers-reduced-motion: reduce) { .quota-acct-fold svg { transition: none; } }
|
||
.quota-windows.brief { row-gap: 5px; }
|
||
.quota-windows.brief .quota-reset { display: none; }
|
||
.quota-windows.brief .quota-labels { margin-bottom: 3px; }
|
||
.subscription-account .plan { margin-left: auto; flex: none; font-size: 10.5px; color: var(--muted); text-transform: capitalize; }
|
||
.subscription-head .plan { margin-left: auto; font-size: 10.5px; color: var(--muted); text-transform: capitalize; }
|
||
.quota-windows { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px 14px; }
|
||
/* each window takes two of the grid's rows, its names and its bar, so
|
||
when one's count wraps under its name the bars beside it still line up;
|
||
its one column is the window's width, which a long count would
|
||
otherwise stretch past the card's edge */
|
||
.quota-windows .quota { display: grid; grid-row: span 3; grid-template-rows: subgrid; grid-template-columns: minmax(0, 1fr); row-gap: 0; }
|
||
.quota-windows .quota-track { align-self: start; }
|
||
/* a narrow card puts the count under the window's name rather than
|
||
squeezing the name a character a line and the count past the edge;
|
||
side by side they are at either end, and a count on a line of its own
|
||
starts at the left, under the name */
|
||
.quota-labels { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 6px; margin-bottom: 4px; font-size: 10.5px; color: var(--muted); }
|
||
.quota-labels > span { white-space: nowrap; }
|
||
.quota-labels .quota-n { max-width: 100%; padding: 0; text-align: left; overflow: hidden; text-overflow: ellipsis; color: var(--fg-2); font-size: inherit; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.quota-labels .quota-n:hover { color: var(--fg); }
|
||
.quota-labels .quota-n > span { white-space: nowrap; }
|
||
/* stacked, a count too long for the window's width breaks at its ·; its
|
||
parts are laid out as flex items, as WebKit leaves the space between two
|
||
nowrap spans out when it checks a line fits and then cuts the line with
|
||
the ellipsis ("剩余 100…" for 100 / 100 积分 · 剩余 100%) */
|
||
.quota-windows.stacked .quota-n { flex-basis: 100%; display: flex; flex-wrap: wrap; column-gap: 4px; white-space: normal; }
|
||
.quota-windows.stacked .quota-n > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.quota-reset { display: flex; flex-wrap: wrap; column-gap: 4px; margin-top: 4px; font-size: 10px; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.quota-reset > span { white-space: nowrap; }
|
||
.quota-track { height: 4px; border-radius: 2px; background: var(--pill); overflow: hidden; }
|
||
.quota-track i { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
|
||
.subscription-error { font-size: 11px; color: var(--faint); }
|
||
/* WorkBuddy's credits a day (#568): the period's sum over a bar a day; a
|
||
day before counting began is an empty slot, not a zero */
|
||
.credit-days { margin-top: 10px; }
|
||
.credit-days .cd-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; font-size: 10.5px; color: var(--muted); }
|
||
.credit-days .cd-head b { color: var(--fg-2); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.credit-days .cd-bars { display: flex; align-items: flex-end; gap: 2px; height: 28px; margin-top: 5px; }
|
||
.credit-days .cd-day { flex: 1; height: 100%; display: flex; align-items: flex-end; border-radius: 2px; background: var(--pill); }
|
||
.credit-days .cd-day.unknown { background: none; outline: 1px dashed var(--line); outline-offset: -1px; }
|
||
.credit-days .cd-day i { display: block; width: 100%; border-radius: 2px; background: var(--accent); }
|
||
.credit-days .cd-note { margin-top: 4px; font-size: 10px; color: var(--faint); }
|
||
/* what was left over time (#651): a line a window, an even burn dashed, now
|
||
upright; the range (or Off) is picked once, in the allowances' head */
|
||
.quota-head .quota-trend { margin-right: 8px; }
|
||
.quota-curve { margin-top: 10px; }
|
||
.quota-curve .qc-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; font-size: 10.5px; color: var(--muted); }
|
||
.quota-curve .qc-range { font-size: 10px; color: var(--faint); }
|
||
.quota-curve .qc-plot { display: block; width: 100%; height: 52px; margin-top: 5px; overflow: hidden; }
|
||
.qc-grid { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
|
||
.qc-line { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
|
||
/* a window far shorter than the span drawn (a 5-hour one over a week) is a
|
||
comb of drops: faint, and without its upright even burn */
|
||
.qc-line.qc-short { stroke-width: 1; opacity: .45; }
|
||
.qc-even { stroke-width: 1; stroke-dasharray: 3 3; opacity: .45; vector-effect: non-scaling-stroke; }
|
||
.qc-now { stroke: var(--faint); stroke-width: 1; stroke-dasharray: 1 2; vector-effect: non-scaling-stroke; }
|
||
.quota-curve .qc-axis { display: flex; justify-content: space-between; gap: 8px; margin-top: 3px; font-size: 10px; color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.quota-curve .qc-legend { display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 5px; font-size: 10.5px; color: var(--muted); }
|
||
/* a key never breaks inside: a long name ends in … rather than its % on a line of its own */
|
||
.qc-key { display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 100%; white-space: nowrap; }
|
||
.qc-key > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.qc-key i { flex: none; width: 7px; height: 7px; border-radius: 50%; }
|
||
.qc-key b { color: var(--fg-2); font-weight: 600; font-variant-numeric: tabular-nums; }
|
||
.quota-resets { display: flex; align-items: center; gap: 8px; margin-top: 9px; font-size: 10.5px; font-variant-numeric: tabular-nums; }
|
||
.quota-resets .text { margin-left: auto; flex: none; font-size: 11px; padding: 2px 7px; }
|
||
.subscription-card.several .quota-resets:not([hidden]) + .subscription-account { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line); }
|
||
.reset-ask .reset-idle { color: var(--amber); }
|
||
/* a WorkBuddy account's daily check-in on its Usage card (#694) */
|
||
.wb-checkin { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.wb-checkin .ci-say { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
|
||
.wb-checkin .ci-say > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
/* a failed check-in's reason wraps under it rather than ending in "…" (#821) */
|
||
.wb-checkin[data-state="bad"] { flex-wrap: wrap; align-items: flex-start; }
|
||
.wb-checkin[data-state="bad"] .ci-say { flex: 1 1 180px; align-items: flex-start; }
|
||
.wb-checkin[data-state="bad"] .ci-say > span { white-space: normal; overflow-wrap: anywhere; }
|
||
.wb-checkin[data-state="bad"] .ci-dot { margin-top: 4px; }
|
||
.wb-checkin .ci-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
|
||
.wb-checkin .ci-dot.ok { background: var(--green); }
|
||
.wb-checkin .ci-dot.bad { background: var(--red); }
|
||
.wb-checkin .ci-dot.wait { background: var(--amber); }
|
||
.wb-checkin[data-state="ok"] .ci-say { color: var(--fg-2); }
|
||
.wb-checkin .text { flex: none; font-size: 11px; padding: 2px 7px; }
|
||
.wb-checkin .ci-auto { margin-left: auto; }
|
||
.subscription-card.several .wb-checkin { margin-bottom: 6px; }
|
||
.wb-checkin .ci-auto.on { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
|
||
.quota-balance { display: flex; align-items: baseline; gap: 6px; font-size: 10.5px; color: var(--muted); }
|
||
.quota-windows + .quota-balance { margin-top: 9px; }
|
||
/* "Every model" at the end of the account's line, above its families */
|
||
.text.quota-every { flex: none; margin: -2px -7px -2px 0; padding: 1px 7px; font-size: 10.5px; }
|
||
.subscription-account .plan + .quota-every, .subscription-head .plan + .quota-every { margin-left: 4px; }
|
||
.subscription-account .user + .quota-every, .subscription-head .quota-every { margin-left: auto; }
|
||
.quota-balance b { margin-left: auto; font-size: 15px; color: var(--fg); font-weight: 600; font-variant-numeric: tabular-nums; }
|
||
/* a balance field's several amounts (#420): a line each, the label quiet
|
||
at the left and the figure at the right, the first the larger; a
|
||
percent's meter under its line; when it was read under them all */
|
||
.quota-balance { flex-wrap: wrap; }
|
||
.quota-balance.parts { display: grid; gap: 7px; }
|
||
.bal-part { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 8px; }
|
||
.bal-part > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.bal-part b { font-size: 12.5px; color: var(--fg-2); }
|
||
.bal-part.lead b { font-size: 15px; color: var(--fg); }
|
||
.bal-part .quota-track, .pq-card.bal .quota-track { grid-column: 1 / -1; margin-top: 4px; }
|
||
.quota-track.full i { background: var(--amber); }
|
||
.quota-read { flex-basis: 100%; margin-top: 2px; font-size: 10px; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.quota-windows + .quota-read, .quota-balance + .quota-read { margin-top: 8px; }
|
||
.quota-read.stale { color: var(--amber); }
|
||
/* a card's own refresh, left of when it was read (or of why it couldn't
|
||
be), opening as the card is hovered: at rest the line starts where the
|
||
card's other lines do (#840) */
|
||
.quota-refresh { display: inline-flex; align-items: center; justify-content: center; width: 0; height: 14px; margin: 0; padding: 0; border: 0; border-radius: 4px; background: none; color: var(--faint); vertical-align: -3px; opacity: 0; overflow: hidden; cursor: pointer; transition: width .12s, margin .12s, opacity .12s; }
|
||
.quota-refresh svg { flex: none; }
|
||
.subscription-card:hover .quota-refresh, .quota-refresh:focus-visible, .quota-refresh.busy { width: 14px; margin: 0 3px 0 -2px; opacity: 1; }
|
||
.quota-refresh:hover { color: var(--fg); background: var(--pill-hover); }
|
||
.quota-refresh.busy { cursor: default; }
|
||
.quota-refresh.busy svg { animation: spin .8s linear infinite; }
|
||
@media (hover: none) { .quota-refresh { width: 14px; margin: 0 3px 0 -2px; opacity: 1; } }
|
||
@media (prefers-reduced-motion: reduce) { .quota-refresh { transition: none; } }
|
||
.skeleton { display: block; border-radius: 5px; background: linear-gradient(90deg, var(--skel, var(--pill)) 25%, var(--skel-hi, var(--pill-hover)) 45%, var(--skel, var(--pill)) 65%); background-size: 240% 100%; animation: skeleton-shift 1.4s ease-in-out infinite; }
|
||
@keyframes skeleton-shift { from { background-position: 100% 0; } to { background-position: -100% 0; } }
|
||
.sk-cost { width: 72px; height: 15px; }
|
||
.skeleton-card { min-height: 78px; display: flex; flex-direction: column; gap: 9px; justify-content: center; }
|
||
.sk-title { width: 38%; height: 12px; }
|
||
.sk-line { width: 100%; height: 5px; }
|
||
.sk-line.short { width: 64%; }
|
||
.loading-kpi { min-height: 67px; justify-content: center; gap: 7px; }
|
||
.loading-kpi .sk-number { width: 54%; height: 17px; }
|
||
.loading-kpi .sk-label { width: 36%; height: 8px; }
|
||
#view-usage.loading .opt { cursor: default; }
|
||
.usage-cost { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; overflow: hidden; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); font-size: 12px; }
|
||
.usage-cost b { font-size: 15px; font-weight: 600; color: var(--fg); }
|
||
/* a narrow window, three tabs and the periods beside it: the words after the
|
||
sum give way, never the page sideways */
|
||
.usage-cost span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
@media (max-width: 640px) {
|
||
.usage-head { gap: 7px; }
|
||
.usage-cost span:not(.skeleton) { display: none; }
|
||
.usage-cost b { font-size: 14px; }
|
||
/* and the refresh's picker is its figure alone; where the tabs, the periods and
|
||
these are more than a line, the sum goes on a line of its own, at the right */
|
||
.usage-head { flex-wrap: wrap; height: auto; min-height: 34px; row-gap: 2px; }
|
||
.usage-cost { margin-left: auto; }
|
||
.usage-refresh { margin-right: 0; }
|
||
.usage-refresh .icon { width: 22px; }
|
||
.usage-refresh .sess-pick { padding: 0 7px; }
|
||
.usage-refresh .sess-pick svg { display: none; }
|
||
}
|
||
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; flex: none; }
|
||
.stats.empty { display: block; background: var(--card); }
|
||
.stats .none { padding: 18px 16px; color: var(--muted); text-align: center; line-height: 1.5; }
|
||
.kpi { background: var(--card); padding: 12px 14px 11px; display: flex; flex-direction: column; min-width: 0; }
|
||
.kpi b { font-size: 20px; font-weight: 600; letter-spacing: -.01em; font-variant-numeric: tabular-nums; line-height: 1.15; }
|
||
.kpi span { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin-top: 3px; }
|
||
.kpi small { font-size: 11px; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.chart { position: relative; margin-top: 8px; padding: 12px 14px 8px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; flex: none; }
|
||
.chart .peak { font-size: 10.5px; color: var(--faint); font-variant-numeric: tabular-nums; text-align: right; margin: 0 0 5px; }
|
||
.chart .bars { display: flex; align-items: flex-end; gap: 3px; height: 72px; border-bottom: 1px solid var(--line-2); }
|
||
.chart .bar { flex: 1 1 0; min-width: 2px; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; border-radius: 3px 3px 0 0; overflow: hidden; }
|
||
.chart .bar:hover { background: var(--pill); }
|
||
.chart .bar i { display: block; background: var(--accent); }
|
||
.chart .bar i.in { opacity: .38; }
|
||
.chart .labels { display: flex; gap: 3px; margin-top: 5px; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.chart .labels span { flex: 1 1 0; min-width: 0; white-space: nowrap; overflow: visible; }
|
||
/* the last label can be wider than its bar's column: let it spill left, not off the card */
|
||
.chart .labels span:last-child { display: flex; justify-content: flex-end; }
|
||
.row.stat .who { flex: 0 0 180px; }
|
||
.row.stat .who .name.faint { color: var(--faint); font-weight: 400; }
|
||
.row.stat .share { flex: 1 1 auto; height: 4px; border-radius: 2px; background: var(--pill); overflow: hidden; margin: 0 6px; }
|
||
.row.stat .share i { display: block; height: 100%; border-radius: 2px; background: var(--accent); opacity: .7; }
|
||
.row.stat .num { display: flex; flex-direction: column; align-items: flex-end; flex: none; min-width: 64px; font-variant-numeric: tabular-nums; }
|
||
.row.stat .num b { font-weight: 600; }
|
||
.row.stat .num small { font-size: 10.5px; color: var(--muted); white-space: nowrap; }
|
||
.row.stat .cost { flex: none; min-width: 58px; text-align: right; color: var(--green); font-variant-numeric: tabular-nums; font-size: 12px; }
|
||
.usage-note { padding: 10px 4px 2px; font-size: 11px; color: var(--faint); user-select: text; -webkit-user-select: text; }
|
||
.usage-pane { display: flex; flex-direction: column; flex: none; }
|
||
.usage-pane[hidden] { display: none; }
|
||
|
||
/* ---- requests, a segment of usage: the ledger ------------------------------ */
|
||
#ledgerPane { min-width: 0; }
|
||
#ledgerPane .sess-tools .segs .opt { height: 22px; }
|
||
#ledExport { flex: none; font-size: 12px; }
|
||
/* the totals and the trend over the requests listed: a strip of four totals,
|
||
then a chart of them by the hour, day or week beside a ranking of who they
|
||
were of — by provider, agent or model — which is also the chart's legend */
|
||
.led-dash { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
|
||
.led-dash[hidden] { display: none; }
|
||
.led-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
|
||
.led-strip .blk { min-width: 0; padding: 11px 15px 10px; }
|
||
.led-strip .blk + .blk { border-left: 1px solid var(--line-2); }
|
||
.led-strip .k { display: block; font-size: 11px; color: var(--muted); }
|
||
.led-strip .v { display: block; margin-top: 2px; font-size: 22px; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.2; white-space: nowrap; }
|
||
.led-strip .v.cost { color: var(--green); }
|
||
.led-strip .sub { display: block; margin-top: 3px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.led-strip .sub b { font-weight: 600; color: var(--fg-2); }
|
||
.led-strip .meter { height: 5px; margin-top: 8px; border-radius: 3px; background: var(--pill); overflow: hidden; }
|
||
.led-strip .meter i { display: block; height: 100%; border-radius: 3px; background: var(--green); }
|
||
.led-trend { padding: 10px 14px 10px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
|
||
.led-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
||
.led-bar .grow { flex: 1; }
|
||
.led-by { font-size: 11.5px; color: var(--muted); }
|
||
.led-body { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 272px; gap: 18px; }
|
||
.led-chart { min-width: 0; }
|
||
.led-chart .plot { position: relative; height: 236px; }
|
||
.led-chart svg { display: block; width: 100%; height: 100%; overflow: visible; font-family: var(--font); font-variant-numeric: tabular-nums; }
|
||
.led-chart .grid { stroke: var(--line-2); stroke-width: 1; stroke-dasharray: 2 3; }
|
||
.led-chart .axis { fill: var(--muted); font-size: 10.5px; }
|
||
.led-chart .hot { fill: var(--pill); }
|
||
.led-chart rect.col { transition: opacity .12s; }
|
||
.led-chart .led-day { cursor: pointer; outline: none; }
|
||
.led-chart .led-day:focus-visible { stroke: var(--accent); stroke-width: 1; }
|
||
.led-chart .tip { position: absolute; top: 2px; z-index: 2; min-width: 172px; max-width: 260px; padding: 8px 10px 7px; background: var(--pop-bg); border-radius: 9px; box-shadow: var(--shadow); font-size: 11.5px; pointer-events: none; }
|
||
.led-chart .tip[hidden] { display: none; }
|
||
.led-chart .tip b { display: block; margin-bottom: 4px; font-weight: 600; }
|
||
.led-chart .tip div { display: flex; align-items: center; gap: 6px; line-height: 1.6; }
|
||
.led-chart .tip div span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.led-chart .tip i { width: 7px; height: 7px; border-radius: 2px; flex: none; }
|
||
.led-chart .tip em { margin-left: auto; padding-left: 12px; font-style: normal; font-variant-numeric: tabular-nums; }
|
||
.led-chart .tip .sum { margin-top: 3px; padding-top: 3px; border-top: 1px solid var(--line-2); color: var(--muted); }
|
||
.led-chart .none { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--muted); text-align: center; padding: 0 20px; }
|
||
.led-rank { min-width: 0; display: flex; flex-direction: column; gap: 1px; align-content: start; }
|
||
.led-rank .rk { display: block; width: 100%; padding: 6px 8px 7px; border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
|
||
.led-rank .rk:hover { background: var(--pill); }
|
||
.led-rank .rk.on { background: var(--accent-soft); }
|
||
.led-rank .rk.plain { cursor: default; }
|
||
.led-rank .rk.plain:hover { background: transparent; }
|
||
.led-rank .rk-a { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 12px; }
|
||
.led-rank .rk-sw { width: 8px; height: 8px; border-radius: 2px; flex: none; }
|
||
.led-rank .rk-a .ic { width: 13px; height: 13px; flex: none; }
|
||
.led-rank .rk-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
|
||
.led-rank .rk-val { margin-left: auto; padding-left: 8px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.led-rank .rk-bar { height: 4px; margin: 5px 0 4px 15px; border-radius: 2px; background: var(--pill); overflow: hidden; }
|
||
.led-rank .rk.on .rk-bar { background: var(--card); }
|
||
.led-rank .rk-bar i { display: block; height: 100%; border-radius: 2px; }
|
||
.led-rank .rk-b { margin-left: 15px; font-size: 10.5px; line-height: 1.45; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.led-rank .rk-b .rk-bad { color: var(--red); }
|
||
/* beside the chart, the ranking is as tall as the chart and scrolls in itself,
|
||
however many there are: the chart sizes the row, not the list. No scrollbar,
|
||
as the views have none: the edge with more beyond it fades out instead */
|
||
@media (min-width: 861px) {
|
||
.led-body > .led-rank { height: 0; min-height: 100%; overflow-y: auto; overscroll-behavior-y: contain; scrollbar-width: none; }
|
||
.led-body > .led-rank::-webkit-scrollbar { width: 0; height: 0; }
|
||
.led-body > .led-rank.more-below { -webkit-mask-image: linear-gradient(#000 calc(100% - 28px), transparent); mask-image: linear-gradient(#000 calc(100% - 28px), transparent); }
|
||
.led-body > .led-rank.more-above { -webkit-mask-image: linear-gradient(transparent, #000 28px); mask-image: linear-gradient(transparent, #000 28px); }
|
||
.led-body > .led-rank.more-above.more-below { -webkit-mask-image: linear-gradient(transparent, #000 28px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(transparent, #000 28px, #000 calc(100% - 28px), transparent); }
|
||
/* where the ranking is scrolled to, and that there is more: a slim rail in
|
||
the card's margin beside it, its thumb dragged or the rail clicked */
|
||
.led-rail { position: absolute; right: -9px; width: 5px; border-radius: 3px; background: var(--pill); cursor: default; touch-action: none; }
|
||
.led-rail[hidden] { display: none; }
|
||
.led-rail i { position: absolute; left: 0; top: 0; width: 100%; min-height: 24px; border-radius: 3px; background: var(--faint); opacity: .7; transition: opacity .12s; }
|
||
.led-body:hover .led-rail i, .led-rail.drag i { opacity: 1; }
|
||
.led-rail.drag i, .led-rail i:hover { background: var(--muted); }
|
||
}
|
||
@media (max-width: 860px) {
|
||
.led-body { grid-template-columns: minmax(0, 1fr); gap: 8px; }
|
||
.led-rail { display: none; }
|
||
.led-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||
.led-strip .blk:nth-child(3) { border-left: 0; }
|
||
.led-strip .blk:nth-child(n + 3) { border-top: 1px solid var(--line-2); }
|
||
}
|
||
/* over the requests: their sum, and at its right the request archive's switch */
|
||
.led-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin: 0 2px 7px; min-width: 0; }
|
||
.led-head .led-sum { margin: 0; min-width: 0; }
|
||
.led-arch { display: inline-flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }
|
||
.led-arch-sw { display: inline-flex; align-items: center; gap: 7px; padding: 2px 0; background: none; border: 0; font: inherit; font-size: 11.5px; color: var(--muted); cursor: pointer; }
|
||
.led-arch-sw:hover, .led-arch-sw.on { color: var(--fg); }
|
||
.led-arch-sw:disabled { opacity: .6; cursor: default; }
|
||
.led-arch-sw .lib-switch { width: 28px; height: 16px; }
|
||
.led-arch-sw .lib-switch i { width: 12px; height: 12px; }
|
||
.led-arch-sw .lib-switch.on i { transform: translateX(12px); }
|
||
.led-arch-err { font-size: 11px; color: var(--red); cursor: default; }
|
||
.led-sum { margin: 0 2px 7px; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
/* the table scrolls sideways in its own box, never the page */
|
||
.led-wrap { max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
|
||
.led-wrap.none { overflow: visible; }
|
||
/* its own scrollbar is at the table's foot, fifty rows down and out of
|
||
sight (#799): this one stands in for it, held at the bottom of the window
|
||
while the table is in it, and drawn always, the Mac's overlay one too */
|
||
.led-wrap::-webkit-scrollbar { height: 0; }
|
||
.led-hscroll { position: sticky; bottom: 0; z-index: 2; overflow-x: auto; overflow-y: hidden; height: 12px; margin-top: 2px; background: var(--bg); }
|
||
.led-hscroll[hidden] { display: none; }
|
||
.led-hscroll > div { height: 1px; }
|
||
.led-hscroll::-webkit-scrollbar { height: 10px; background: transparent; }
|
||
.led-hscroll::-webkit-scrollbar-thumb { background: var(--faint); border: 2px solid transparent; border-radius: 10px; background-clip: padding-box; }
|
||
.led-hscroll::-webkit-scrollbar-thumb:hover { background-color: var(--muted); }
|
||
.led-hscroll::-webkit-scrollbar-button, .led-hscroll::-webkit-scrollbar-corner { display: none; }
|
||
.led-none { padding: 18px 16px; color: var(--muted); text-align: center; line-height: 1.5; }
|
||
.led-sk { padding: 11px 14px; }
|
||
.led-sk + .led-sk { border-top: 1px solid var(--line-2); }
|
||
.led { width: 100%; border-collapse: collapse; font-size: 11.5px; font-variant-numeric: tabular-nums; }
|
||
.led th { padding: 7px 9px 6px; background: var(--card); border-bottom: 1px solid var(--line); font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); text-align: left; white-space: nowrap; }
|
||
.led td { padding: 6px 9px; border-top: 1px solid var(--line-2); white-space: nowrap; color: var(--fg); user-select: text; -webkit-user-select: text; }
|
||
.led tbody tr:first-child td { border-top: 0; }
|
||
.led tbody tr:hover td { background: var(--card-2, var(--pill)); }
|
||
.led .n { text-align: right; }
|
||
.led .faint { color: var(--faint); }
|
||
.led .muted { color: var(--muted); }
|
||
.led th, .led .when, .led .model-value { color: var(--fg-2); }
|
||
.led .when .text { padding: 0; font: inherit; }
|
||
.led .when .led-route-link { text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
|
||
.led .when .led-route-link:hover { text-decoration-style: solid; }
|
||
#ledRoute { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; }
|
||
#ledRoute[hidden] { display: none; }
|
||
#ledRouteClear { font-size: 18px; padding: 2px 6px; }
|
||
.led .model, .led .where { max-width: 200px; overflow: hidden; text-overflow: ellipsis; }
|
||
.led .where { color: var(--fg-2); }
|
||
.led .where-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.led .source-badges { display: flex; flex-wrap: nowrap; gap: 4px; margin-top: 4px; }
|
||
.led .price-reference { font-size: 10px; color: var(--muted); }
|
||
.led .cost { color: var(--green); }
|
||
.led .cost.faint { color: var(--faint); }
|
||
.led .who { display: inline-flex; align-items: center; gap: 6px; }
|
||
.led .who .ic { width: 14px; height: 14px; flex: none; }
|
||
.led .swap { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; font-size: 10.5px; line-height: 16px; padding: 0 5px; border-radius: 5px; color: var(--amber); background: var(--amber-soft); }
|
||
.led .st { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); }
|
||
.led .st .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: none; }
|
||
.led tr.bad .st { color: var(--red); font-weight: 600; }
|
||
.led tr.bad .st .dot { background: var(--red); }
|
||
/* Source chips use identity/channel colors; latency alone uses traffic lights.
|
||
Existing theme tokens keep these legible in both native color schemes. */
|
||
.led .source-badges .src { flex: none; }
|
||
.led .src { --badge-ink: var(--tk-v); --badge-bg: color-mix(in srgb, var(--badge-ink) 10%, var(--card)); display: inline-flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 550; line-height: 16px; padding: 0 6px; border: 1px solid color-mix(in srgb, var(--badge-ink) 19%, transparent); border-radius: 5px; color: var(--badge-ink); background: var(--badge-bg); vertical-align: 1px; }
|
||
.led .src.official { --badge-ink: var(--tk-s); --badge-bg: color-mix(in srgb, var(--badge-ink) 7%, var(--card)); font-size: 9px; font-weight: 650; letter-spacing: .035em; }
|
||
.led .src.official::before { content: ""; width: 6px; height: 3.5px; border-left: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-1px) rotate(-45deg); }
|
||
.led .src.access-api { --badge-ink: var(--tk-f); }
|
||
.led .src.access-subscription { --badge-ink: var(--tk-k); }
|
||
.led .duration { font-weight: 550; }
|
||
.led .duration-fast { color: var(--tk-s); }
|
||
.led .duration-slow { color: var(--amber); }
|
||
.led .duration-long { color: var(--red); }
|
||
.led .duration.faint { font-weight: 400; }
|
||
.led tr.led-row { cursor: pointer; }
|
||
.led tr.led-row:focus-visible { outline: 2px solid var(--accent, var(--fg-2)); outline-offset: -2px; }
|
||
.led tr.open td { background: var(--card-2, var(--pill)); }
|
||
.led tr.led-detail td { padding: 0; white-space: normal; background: var(--card-2, var(--pill)); }
|
||
.led-box { position: sticky; left: 0; box-sizing: border-box; width: min(100%, calc(var(--ledw, 720px) - 2px), 900px); padding: 8px 12px 11px; }
|
||
.led-dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 14px; margin: 0; font-size: 11.5px; }
|
||
.led-dl dt { color: var(--muted); }
|
||
.led-dl dd { margin: 0; min-width: 0; color: var(--fg); overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.led-dl dd.bad { color: var(--red); font-weight: 600; }
|
||
.led-dl dd.said { color: var(--fg); white-space: pre-wrap; }
|
||
.led-dl dd.muted { color: var(--muted); }
|
||
.led-dl .led-route-link { padding: 0; font: inherit; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
|
||
/* what was said in a request, in its details */
|
||
.led-cx { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line-2); }
|
||
.cx-sec + .cx-sec { margin-top: 10px; }
|
||
.cx-sec h4 { margin: 0 0 4px; font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
|
||
.cx-part { margin: 0 0 6px; }
|
||
.cx-h { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; font-size: 10.5px; color: var(--muted); }
|
||
.cx-role { padding: 0 6px; border-radius: 5px; background: var(--pill); font-size: 10.5px; line-height: 16px; color: var(--fg-2); }
|
||
.cx-role.user { color: var(--accent); background: var(--accent-soft); }
|
||
.cx-role.assistant { color: var(--green); background: var(--green-soft); }
|
||
.cx-name { font: 11px var(--code); color: var(--fg-2); }
|
||
.cx-t { margin: 0; padding: 7px 9px; border-radius: 8px; background: var(--card); border: 1px solid var(--line-2); font: 11.5px/1.5 var(--code); color: var(--fg); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.cx-cut { color: var(--muted); font-style: normal; }
|
||
.cx-part.clamp .cx-t { max-height: 176px; overflow: hidden; -webkit-mask-image: linear-gradient(#000 72%, transparent); mask-image: linear-gradient(#000 72%, transparent); }
|
||
.cx-more { margin-top: 2px; font-size: 11px; }
|
||
details.cx-part > summary { list-style: none; cursor: pointer; }
|
||
details.cx-part > summary::-webkit-details-marker { display: none; }
|
||
details.cx-part > summary .cx-h { margin-bottom: 0; }
|
||
details.cx-part > summary .cx-h::after { content: "▸"; margin-left: 2px; color: var(--faint); }
|
||
details.cx-part[open] > summary .cx-h::after { content: "▾"; }
|
||
details.cx-part[open] > summary .cx-h { margin-bottom: 2px; }
|
||
.cx-none { margin: 0; font-size: 11.5px; color: var(--muted); }
|
||
.cx-src { margin: 8px 0 0; font-size: 10.5px; color: var(--faint); }
|
||
.led-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 8px; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.led-pager[hidden] { display: none; }
|
||
.led-pager .text { font-size: 12px; }
|
||
|
||
/* ---- sessions, a segment of usage ------------------------------------------ */
|
||
.sess-tools { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; flex: none; }
|
||
.sess-tools .grow { flex: 1; }
|
||
.sess-filter { width: 220px; max-width: 100%; height: 26px; padding: 0 9px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); color: var(--fg); font-size: 12px; outline: none; }
|
||
.sess-filter:focus { border-color: var(--accent); }
|
||
.sess-tools { flex-wrap: wrap; row-gap: 6px; }
|
||
.sess-pick { flex: none; display: inline-flex; align-items: center; gap: 4px; max-width: 180px; height: 26px; padding: 0 7px 0 9px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font: inherit; font-size: 12px; cursor: default; }
|
||
.sess-pick span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.sess-pick svg { flex: none; opacity: .7; transition: transform .15s var(--ease); }
|
||
.sess-pick:hover { background: var(--pill); }
|
||
.sess-pick.set { color: var(--fg); border-color: var(--line-2); background: var(--pill); }
|
||
.sess-pick.open svg { transform: rotate(180deg); }
|
||
.pop.proto-menu.sess-menu { width: 300px; max-height: min(360px, 70vh); overflow-y: auto; overscroll-behavior: contain; }
|
||
.sess-menu .pm-name, .sess-menu .pm-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.pop.proto-menu.sess-menu { width: 340px; padding-top: 0; display: block; background: var(--card); }
|
||
.sess-menu .sc-top { position: sticky; top: 0; z-index: 1; padding: 4px 0 6px; background: var(--card); }
|
||
.sess-menu .sc-q { display: block; width: 100%; box-sizing: border-box; height: 28px; padding: 0 9px; border: 1px solid var(--line); border-radius: 7px; background: var(--pill); color: var(--fg); font: inherit; font-size: 12.5px; outline: none; }
|
||
.sess-menu .sc-q:focus { border-color: var(--accent, var(--fg)); }
|
||
.sess-menu .sc-list { display: grid; gap: 1px; }
|
||
.sess-menu .sc-none, .sess-menu .sc-more { padding: 8px 8px 6px; font-size: 11px; color: var(--muted); }
|
||
.sess-chart-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: -2px 0 8px; }
|
||
.sess-chart-head .label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
|
||
.sess-chart-head .grow { flex: 1; }
|
||
.sess-chart-head .segs { align-self: center; }
|
||
.sess-chart-head .segs .opt { height: 20px; padding: 0 9px; font-size: 11px; }
|
||
.chart .sess-chart-head .peak { margin: 0; align-self: flex-end; }
|
||
.sess-list { margin-top: 8px; }
|
||
/* the overview: six figures, the calendar, and four cards two by two */
|
||
.sess-pane { container-type: inline-size; }
|
||
.stats.six { grid-template-columns: repeat(6, minmax(0, 1fr)); }
|
||
@container (max-width: 820px) { .stats.six { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
|
||
@container (max-width: 420px) { .stats.six { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||
.kpi.stale, .sess-card.stale .sess-tops { opacity: .55; transition: opacity .2s; }
|
||
.l0 { background: var(--pill); }
|
||
.l1 { background: color-mix(in srgb, var(--accent) 22%, var(--pill)); }
|
||
.l2 { background: color-mix(in srgb, var(--accent) 45%, var(--pill)); }
|
||
.l3 { background: color-mix(in srgb, var(--accent) 70%, var(--pill)); }
|
||
.l4 { background: var(--accent); }
|
||
.sess-legend { display: inline-flex; align-items: center; gap: 3px; font-size: 10.5px; color: var(--faint); }
|
||
.sess-legend i { width: 10px; height: 10px; border-radius: 2.5px; }
|
||
.sess-legend span:first-child { margin-right: 2px; }
|
||
.sess-legend span:last-child { margin-left: 2px; }
|
||
.sess-cal-wrap { display: flex; align-items: flex-start; gap: 18px; padding-bottom: 4px; }
|
||
.sess-cal { flex: 1 1 auto; display: grid; grid-template-rows: auto repeat(7, auto); gap: 3px; min-width: 0; font-size: 10px; color: var(--muted); }
|
||
.sess-cal i { aspect-ratio: 1; border-radius: 3px; min-width: 0; }
|
||
.sess-cal s { aspect-ratio: 1; border-radius: 3px; min-width: 0; background: var(--pill); opacity: .45; }
|
||
.sess-cal i:hover { outline: 1px solid var(--fg-2); outline-offset: -1px; }
|
||
.sess-cal .wd { padding-right: 5px; line-height: 1; align-self: center; white-space: nowrap; }
|
||
.sess-cal .mo { white-space: nowrap; overflow: visible; line-height: 1.2; padding-bottom: 1px; }
|
||
.sess-cal-side { flex: none; display: flex; flex-direction: column; gap: 10px; min-width: 104px; padding-top: 14px; }
|
||
.sess-cal-side .fact { display: flex; flex-direction: column; }
|
||
.sess-cal-side b { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
|
||
.sess-cal-side span { font-size: 10.5px; color: var(--muted); }
|
||
.sess-cal-side small { font-size: 10.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
@container (max-width: 560px) { .sess-cal-wrap { flex-direction: column; gap: 10px; } .sess-cal-side { flex-direction: row; flex-wrap: wrap; gap: 16px; padding-top: 0; } }
|
||
.sess-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
|
||
.sess-grid[hidden] { display: none; }
|
||
.sess-card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px 10px; min-width: 0; display: flex; flex-direction: column; }
|
||
@container (max-width: 700px) { .sess-grid { grid-template-columns: minmax(0, 1fr); } }
|
||
.sess-card-head { display: flex; align-items: center; gap: 8px; margin: -2px 0 8px; min-height: 20px; }
|
||
.sess-card-head .label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
|
||
.sess-card-head .grow { flex: 1; }
|
||
.sess-card-head .segs .opt { height: 20px; padding: 0 9px; font-size: 11px; }
|
||
.sess-card-head .tz { font-size: 10.5px; color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.sess-card-foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 11px; color: var(--muted); }
|
||
.sess-card-foot .grow { flex: 1; }
|
||
.sess-none { color: var(--faint); font-size: 12px; padding: 18px 0; text-align: center; margin: auto 0; }
|
||
.sess-more { font-size: 11px; color: var(--faint); padding: 4px 2px 0; }
|
||
/* a card of bars is one grid: its names take the width the longest needs
|
||
and the bars what is left, every row's bar starting at the same place;
|
||
a window too narrow for that shortens the names, never a bar past 5em */
|
||
.sess-bars { display: grid; grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto 4.2em; column-gap: 10px; row-gap: 1px; }
|
||
.sess-bars.tools { grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto auto 2.8em; }
|
||
.sess-bars > * { grid-column: 1 / -1; }
|
||
.sess-bar { display: grid; grid-template-columns: subgrid; align-items: center; gap: 10px; height: 26px; padding: 0 6px; margin: 0 -6px; border: 0; border-radius: 6px; background: none; color: var(--fg-2); font: inherit; font-size: 12px; text-align: left; cursor: default; }
|
||
.sess-bar:hover { background: var(--pill); }
|
||
.sess-bar.on { background: var(--pill); color: var(--fg); font-weight: 550; }
|
||
.sess-bar .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.sess-bar .track { height: 6px; border-radius: 3px; background: var(--pill); overflow: hidden; }
|
||
.sess-bar.on .track, .sess-bar:hover .track { background: var(--card); }
|
||
.sess-bar .track i { display: block; height: 100%; border-radius: 3px; background: var(--accent); opacity: .75; }
|
||
.sess-bar .v { font-variant-numeric: tabular-nums; color: var(--fg-2); font-weight: 400; }
|
||
.sess-bar .c { font-variant-numeric: tabular-nums; color: var(--green); text-align: right; font-size: 11.5px; font-weight: 400; }
|
||
.sess-hours { display: grid; grid-template-columns: auto repeat(24, minmax(0, 1fr)); gap: 2px; font-size: 10px; color: var(--muted); }
|
||
.sess-hours i { height: 14px; border-radius: 2.5px; min-width: 0; }
|
||
.sess-hours i:hover { outline: 1px solid var(--fg-2); outline-offset: -1px; }
|
||
.sess-hours .wd { padding-right: 6px; line-height: 14px; white-space: nowrap; }
|
||
.sess-hours .hr { line-height: 1.4; white-space: nowrap; overflow: visible; font-variant-numeric: tabular-nums; }
|
||
.sess-card.wide { grid-column: 1 / -1; }
|
||
.sess-card.stale .sess-shape, .sess-card.stale .sess-tools-cols, .sess-card.stale .sess-skills { opacity: .55; transition: opacity .2s; }
|
||
.sess-shape { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; height: 150px; }
|
||
.sess-shape .col { display: flex; flex-direction: column; align-items: stretch; min-width: 0; gap: 4px; }
|
||
.sess-shape .plot { flex: 1; position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: stretch; gap: 4px; border-bottom: 1px solid var(--line); }
|
||
.sess-shape .plot b { font-size: 11px; font-weight: 600; text-align: center; font-variant-numeric: tabular-nums; color: var(--fg-2); }
|
||
.sess-shape .plot b.zero { color: var(--faint); font-weight: 500; }
|
||
.sess-shape .plot i { display: block; margin: 0 14%; border-radius: 5px 5px 0 0; background: color-mix(in srgb, var(--accent) 55%, transparent); transition: height .25s ease, background .15s; }
|
||
.sess-shape .plot i.none { height: 2px; border-radius: 1px; background: var(--line); }
|
||
.sess-shape .col.peak .plot i, .sess-shape .col:hover .plot i:not(.none) { background: var(--accent); }
|
||
.sess-shape .col span { font-size: 10.5px; color: var(--muted); text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||
.sess-tools-cols { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 22px; }
|
||
@container (max-width: 700px) { .sess-tools-cols { grid-template-columns: minmax(0, 1fr); } }
|
||
.sess-bar.tool .n { display: flex; align-items: center; gap: 7px; }
|
||
.sess-bar.tool .n span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.sess-bar.tool .track i { opacity: .85; }
|
||
.sess-bar.tool .s { font-size: 11px; color: var(--muted); white-space: nowrap; }
|
||
.sess-bar.tool .p { font-size: 11px; color: var(--faint); text-align: right; font-variant-numeric: tabular-nums; }
|
||
.sess-card .dot { flex: none; width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
||
.sess-tools-side { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
|
||
.sess-mix { display: flex; height: 10px; border-radius: 5px; overflow: hidden; gap: 2px; margin-top: 6px; }
|
||
.sess-mix i { min-width: 3px; }
|
||
.sess-kinds { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11.5px; color: var(--fg-2); }
|
||
.sess-kinds .kind { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||
.sess-kinds .kind b { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--fg); }
|
||
.sess-sub { font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--faint); margin-top: 6px; }
|
||
.sess-weeks { display: flex; align-items: flex-end; gap: 3px; height: 72px; }
|
||
.sess-weeks .bar { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 0; }
|
||
.sess-weeks .bar:hover { background: var(--pill); border-radius: 3px; }
|
||
.sess-weeks .stack { width: 100%; display: flex; flex-direction: column-reverse; border-radius: 3px; overflow: hidden; }
|
||
.sess-weeks .stack i { min-height: 1px; }
|
||
.sess-weeks-labels { display: flex; justify-content: space-between; font-size: 10px; color: var(--faint); }
|
||
.sess-skills { display: grid; grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto; column-gap: 10px; row-gap: 2px; }
|
||
.sess-skills > * { grid-column: 1 / -1; }
|
||
.sess-skill { display: grid; grid-template-columns: subgrid; padding: 4px 6px; margin: 0 -6px; border-radius: 6px; min-width: 0; }
|
||
.sess-skill:hover { background: var(--pill); }
|
||
.sess-skill .line, .sess-skill .sub { grid-column: 1 / -1; }
|
||
.sess-skill .line { display: grid; grid-template-columns: subgrid; align-items: center; gap: 10px; font-size: 12px; }
|
||
/* before subgrid (Safari 16) each row is a grid of its own, its name as
|
||
wide as it needs and its bar at least 5em */
|
||
@supports not (grid-template-columns: subgrid) {
|
||
.sess-bar { grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto 4.2em; }
|
||
.sess-bar.tool { grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto auto 2.8em; }
|
||
.sess-skill { display: block; }
|
||
.sess-skill .line { grid-template-columns: minmax(0, max-content) minmax(5em, 1fr) auto; }
|
||
}
|
||
.sess-skill .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg); font-weight: 550; }
|
||
.sess-skill .track { height: 6px; border-radius: 3px; background: var(--pill); overflow: hidden; }
|
||
.sess-skill:hover .track { background: var(--card); }
|
||
.sess-skill .track i { display: block; height: 100%; border-radius: 3px; background: var(--accent); opacity: .75; }
|
||
.sess-skill .v { font-variant-numeric: tabular-nums; color: var(--fg-2); }
|
||
.sess-skill .sub { font-size: 11px; color: var(--muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.sess-tops { display: flex; flex-direction: column; margin: 0 -14px -10px; min-height: 0; }
|
||
.row.sess.sess-top { min-height: 40px; gap: 10px; padding: 0 14px; }
|
||
.row.sess.sess-top .who { flex: 1 1 auto; min-width: 0; }
|
||
.row.sess.sess-top .name, .row.sess.sess-top .sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.row.sess.sess-top .v { flex: none; font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12px; }
|
||
.sess-tops .sess-detail { padding-left: 42px; }
|
||
.sess-wait { color: var(--muted); }
|
||
.sess-sk { flex-direction: column; align-items: stretch; justify-content: center; gap: 7px; min-height: 48px; }
|
||
.sess-item + .sess-item { border-top: 1px solid var(--line-2); }
|
||
.sess-item.open { background: color-mix(in srgb, var(--pill) 45%, transparent); }
|
||
.row.sess { cursor: default; min-height: 46px; }
|
||
.row.sess:hover { background: var(--pill); }
|
||
.row.sess .num { display: flex; flex-direction: column; align-items: flex-end; flex: none; min-width: 64px; font-variant-numeric: tabular-nums; }
|
||
.row.sess .num b { font-weight: 600; }
|
||
.row.sess .num small { font-size: 10.5px; color: var(--muted); white-space: nowrap; }
|
||
.row.sess .cost { flex: none; min-width: 58px; text-align: right; color: var(--green); font-variant-numeric: tabular-nums; font-size: 12px; }
|
||
.row.sess .cost.none { color: var(--faint); }
|
||
.row.sess .num.none b { color: var(--faint); font-weight: 400; }
|
||
/* a row of the Usage page's list opens on the Sessions page (#752) */
|
||
.row.sess.sess-link { cursor: pointer; }
|
||
.row.sess .sess-go { flex: none; display: inline-flex; color: var(--faint); }
|
||
.row.sess.sess-link:hover .sess-go, .row.sess.sess-link:focus-visible .sess-go { color: var(--fg-2); }
|
||
.sess-all { flex: none; white-space: nowrap; }
|
||
.sess-resume { flex: none; height: 24px; padding: 0 10px; border-radius: 7px; border: 0; background: var(--pill); color: var(--fg); font-size: 11.5px; font-weight: 500; white-space: nowrap; }
|
||
.sess-resume:hover { background: var(--pill-hover); }
|
||
.sess-resume.done { background: var(--green-soft); color: var(--green); }
|
||
.sess-term { flex: none; }
|
||
.sess-detail { display: flex; flex-direction: column; gap: 5px; padding: 2px 12px 11px 38px; font-size: 11.5px; user-select: text; -webkit-user-select: text; }
|
||
.sess-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||
.sess-line .k { flex: 0 0 64px; color: var(--muted); }
|
||
.sess-line .v { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg-2); }
|
||
.sess-line code { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--code); font-size: 11px; padding: 2px 6px; border-radius: 5px; background: var(--pill); }
|
||
.sess-line .copy { flex: none; }
|
||
.sess-models { display: grid; grid-template-columns: minmax(0, auto) 1fr auto; gap: 3px 12px; margin: 3px 0 2px 72px; font-variant-numeric: tabular-nums; }
|
||
.sess-models .model { font-family: var(--code); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.sess-models .n { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.sess-models .c { text-align: right; color: var(--green); }
|
||
.sess-models .c.none { color: var(--faint); }
|
||
@media (max-width: 560px) {
|
||
.row.sess .num small { display: none; }
|
||
.sess-filter { width: 150px; }
|
||
.sess-models { margin-left: 0; grid-template-columns: minmax(0, 1fr) auto; }
|
||
.sess-models .n { display: none; }
|
||
.sess-detail { padding-left: 12px; }
|
||
}
|
||
|
||
/* ---- the panel's tabs: agents, usage, profiles ---------------------------- */
|
||
/* outside the scrolling page, so they stay put under the header */
|
||
.ptabs { position: relative; display: flex; flex: none; gap: 2px; margin: 0 12px 8px; }
|
||
/* the view scrolls, so it clips at its own top: the card's edge is a ring
|
||
outside its box and needs the 2px the tabs give up to be drawn whole */
|
||
body.panel .view { padding-top: 2px; }
|
||
.ptabs > .thumb { top: 0; bottom: 0; border-radius: 7px; box-shadow: 0 1px 2px rgba(0, 0, 0, .08), var(--card-edge); }
|
||
.ptabs[hidden] { display: none; }
|
||
.ptabs button { position: relative; z-index: 1; flex: 1; display: flex; align-items: center; justify-content: center; gap: 3px; height: 26px; border-radius: 7px; font-size: 12px; color: var(--muted); transition: color .15s, background-color .15s; }
|
||
.ptabs button:hover:not(.on) { color: var(--fg-2); }
|
||
.ptabs button.on { color: var(--fg); font-weight: 550; }
|
||
.ptabs button[hidden] { display: none; }
|
||
.ptabs em { font-style: normal; font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
body.panel[data-ptab="usage"] :is(#agents, #panelRouting, #panelUsage),
|
||
body.panel[data-ptab="stats"] :is(#agents, #panelRouting, #panelQuota),
|
||
body.panel[data-ptab="routing"] :is(#agents, #panelQuota, #panelUsage),
|
||
body.panel[data-ptab="agents"] :is(#panelQuota, #panelRouting, #panelUsage) { display: none; }
|
||
|
||
/* ---- the panel's agents: one quiet line each, opened in place ------------ */
|
||
/* icon · name · model · effort · chevron, the last three in columns of their
|
||
own so the bars and chevrons line up down the list */
|
||
body.panel .row.agent { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; grid-template-rows: 36px; align-items: center; column-gap: 10px; row-gap: 0; min-height: 36px; padding: 0 12px; cursor: default; }
|
||
body.panel .row.agent .ag-handle { width: 20px; height: 20px; margin: 0; }
|
||
body.panel .row.agent .ic { width: 18px; height: 18px; }
|
||
body.panel .row.agent .who { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
||
body.panel .row.agent { transition: background-color .3s ease; }
|
||
body.panel .row.agent.open { background: var(--card-2); }
|
||
.ag-sum { display: grid; grid-template-columns: auto 12px 10px; align-items: center; gap: 10px; min-width: 0; max-width: 100%; font-size: 12px; color: var(--muted); }
|
||
.ag-sum .v { display: flex; align-items: center; justify-content: flex-end; min-width: 0; }
|
||
.ag-sum .vt { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
|
||
/* the logo comes in as its box opens from nothing to its own width (a
|
||
real width, --w, measured on the way in, which every engine lays out
|
||
frame by frame), the words easing aside on the row's spring; the logo
|
||
sits against them, fading and growing in a beat behind, and goes
|
||
first on the way out. The clip is padded past the discs' rings. */
|
||
.ag-sum .mi { display: flex; justify-content: flex-end; align-items: center; flex: none; width: 0; padding: 2px; margin: -2px -2px -2px -2px; overflow: hidden; transition: width .36s var(--row-spring), margin-right .36s var(--row-spring); }
|
||
.ag-sum .mi-in { display: flex; align-items: center; flex: none; width: max-content; opacity: 0; transform: scale(.6); transform-origin: 100% 50%; transition: opacity .14s ease, transform .3s var(--row-spring); }
|
||
.row.agent .ag-sum .mi .ic { width: 14px; height: 14px; }
|
||
.row.agent .ag-sum .mi .ic-stack .disc { width: 16px; height: 16px; }
|
||
.row.agent .ag-sum .mi .ic-stack .disc > .ic { width: 10px !important; height: 10px !important; }
|
||
.row.agent:hover .ag-sum .mi { width: calc(var(--w, 16px) + 4px); margin-right: 4px; transition: width .46s var(--row-spring), margin-right .46s var(--row-spring); }
|
||
.row.agent:hover .ag-sum .mi-in { opacity: 1; transform: none; transition: opacity .28s ease .08s, transform .52s var(--row-spring) .04s; }
|
||
@media (prefers-reduced-motion: reduce) { .ag-sum .mi, .ag-sum .mi-in, .row.agent:hover .ag-sum .mi, .row.agent:hover .ag-sum .mi-in { transition: none; } }
|
||
#addSheet { scroll-margin-top: 12px; }
|
||
.ag-sum .v.empty { color: var(--muted); }
|
||
.ag-sum .chev { display: inline-flex; width: 10px; color: var(--faint); transform: rotate(-90deg); transition: transform .4s var(--row-spring); }
|
||
.row.agent.open .ag-sum .chev { transition-duration: .48s; }
|
||
.row.agent.open .ag-sum .chev { transform: none; }
|
||
.eff { display: inline-flex; align-items: flex-end; gap: 1.5px; height: 10px; }
|
||
.eff i { width: 2.5px; border-radius: 1px; background: var(--faint); opacity: .45; }
|
||
.eff i:nth-child(1) { height: 4px; }
|
||
.eff i:nth-child(2) { height: 7px; }
|
||
.eff i:nth-child(3) { height: 10px; }
|
||
.eff[data-l="1"] i:nth-child(-n+1), .eff[data-l="2"] i:nth-child(-n+2), .eff[data-l="3"] i { background: var(--fg-2); opacity: 1; }
|
||
/* a row opens on a spring (ROW_OPEN / ROW_CLOSE in app.js, which the
|
||
panel's edge follows): the height sets off gently and settles, and what's
|
||
inside comes down a few px into place as it clears; closing, it lifts
|
||
and is gone before the height is, so nothing is left to smear */
|
||
body.panel { --row-spring: cubic-bezier(.25, .3, .1, 1); }
|
||
.ag-open { grid-column: 1 / -1; display: grid; grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .4s var(--row-spring), visibility 0s .4s; }
|
||
.row.agent.open .ag-open { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows .48s var(--row-spring); }
|
||
.ag-body { opacity: 0; transform: translateY(-6px); transition: opacity .16s ease, transform .4s var(--row-spring); }
|
||
.row.agent.open .ag-body { opacity: 1; transform: none; transition: opacity .3s ease .06s, transform .48s var(--row-spring); }
|
||
.ag-in { min-height: 0; overflow: hidden; }
|
||
/* the room over the lines is inside what opens: a shut row is 36px, no more */
|
||
.ag-body { display: flex; flex-direction: column; gap: 8px; padding: 9px 0 12px 30px; transform-origin: 50% 0; }
|
||
.ag-open .field { display: flex; justify-content: flex-start; width: 100%; height: 30px; gap: 8px; padding: 0 10px; border-radius: 8px; background: var(--card); font-size: 12.5px; box-shadow: inset 0 0 0 1px var(--pill-line); }
|
||
body.panel .ag-open .field:hover { background: var(--card); box-shadow: inset 0 0 0 1px var(--pill-line), var(--pill-shadow); }
|
||
body.panel .ag-open .field.open { box-shadow: inset 0 0 0 1px var(--accent); }
|
||
/* wide enough for the longest name an agent's own settings go by
|
||
(Aside's standard, Claude Code's thinking), which 44px cut to stand... */
|
||
.ag-open .field .k { order: 0; width: 62px; text-align: left; font-size: 11px; color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.ag-open .field .v { order: 1; flex: 1 1 auto; font-weight: 400; text-align: left; }
|
||
.ag-open .field > .ic, .ag-open .field > .ic-stack { order: 2; flex: none; }
|
||
.row.agent .ag-open .field .ic { width: 14px; height: 14px; }
|
||
.ag-open .field .chev { order: 3; margin-left: 0; transform: none; }
|
||
.ag-open .effort-control { padding: 2px 4px 0; }
|
||
.eslide { --p: 0; position: relative; height: 20px; cursor: pointer; touch-action: none; outline: none; }
|
||
.eslide .rail { position: absolute; left: 8px; right: 8px; top: 8px; height: 4px; border-radius: 999px; background: var(--line); }
|
||
.eslide .fill { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--p) * 100%); border-radius: inherit; background: var(--fg); transition: width .26s var(--ease); }
|
||
.eslide .knob { position: absolute; z-index: 4; top: 2px; left: calc(8px + var(--p) * (100% - 16px)); width: 16px; height: 16px; margin-left: -8px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .18), 0 1px 3px rgba(0, 0, 0, .22); transition: left .26s var(--ease), transform .14s var(--ease); }
|
||
.eslide:hover .knob { transform: scale(1.08); }
|
||
.eslide.drag .knob { transform: scale(.94); }
|
||
.eslide.drag .knob, .eslide.drag .fill { transition-duration: .14s; }
|
||
.eslide:focus-visible .knob { box-shadow: 0 0 0 .5px rgba(0, 0, 0, .18), 0 1px 3px rgba(0, 0, 0, .22), 0 0 0 3px var(--accent-soft); }
|
||
@media (prefers-reduced-motion: reduce) { .eslide .knob, .eslide .fill, .ag-open, .ag-body { transition: none; } }
|
||
.ag-open .effort-head { margin-bottom: 4px; }
|
||
.ag-open .effort-head span { font-size: 11px; color: var(--faint); }
|
||
.ag-open .extras-cell { display: flex; justify-content: flex-start; gap: 6px; }
|
||
.ag-open .extras-cell .field { width: 30px; padding: 0; justify-content: center; }
|
||
body.panel .row.agent .ag-fix { left: 21px; top: 22px; }
|
||
body.panel .agent-fold-cap { padding-left: 12px; }
|
||
/* "Show 9 more", the list's last line, where the names start */
|
||
body.panel .agent-more { justify-content: flex-start; gap: 6px; padding: 9px 14px; }
|
||
|
||
/* ---- the panel's profiles: Profiles at the Agents tab's foot, left, opens
|
||
them over the list, upward from it ------------------------------------------ */
|
||
.prof-btn { display: inline-flex; align-items: center; gap: 4px; margin-left: -7px; }
|
||
.prof-btn em { font-style: normal; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.prof-btn[aria-expanded="true"] { color: var(--fg); background: var(--pill-hover); }
|
||
body.panel:not([data-ptab="agents"]) .prof-btn { display: none; }
|
||
body.panel .foot .status { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
body.panel .profiles { display: none; }
|
||
/* the chips a line of their own; a name field opened goes beside the button */
|
||
body.panel .profiles.open {
|
||
display: flex; position: fixed; z-index: 30; left: 8px; width: min(360px, calc(100vw - 16px)); min-height: 0;
|
||
flex-wrap: wrap; align-items: center; align-content: flex-start; gap: 8px; padding: 10px; overflow-y: auto; overscroll-behavior: contain;
|
||
background: var(--pop-bg); -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
|
||
border: 1px solid var(--line); border-radius: 11px; box-shadow: var(--shadow);
|
||
transform-origin: 24px bottom; --pop-dy: 6px;
|
||
animation: pop-fade .18s ease-out, pop-in .42s cubic-bezier(.16, 1, .3, 1);
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { body.panel .profiles.open { animation: pop-fade .12s ease-out; } }
|
||
body.panel .profiles > .label { display: block; flex: 1 1 100%; padding: 0 2px; }
|
||
body.panel .profiles .chips { flex: 1 1 100%; flex-wrap: wrap; }
|
||
body.panel .profiles .chips .hint { white-space: normal; line-height: 1.4; padding: 0 4px; color: var(--muted); }
|
||
body.panel .profiles.naming .chips .hint { display: none; }
|
||
body.panel .profiles #save,
|
||
body.panel .profiles > .chip-input { margin: 0; }
|
||
body.panel .profiles #save { height: 25px; } /* the field's: the line keeps its height as it opens */
|
||
|
||
/* ---- the panel's usage tab: accounts under their vendor, windows as rings -- */
|
||
.panel-quota { flex: none; display: flex; flex-direction: column; gap: 14px; padding: 2px 2px 6px; }
|
||
.pq-group { display: flex; flex-direction: column; gap: 8px; }
|
||
.pq-gh { display: flex; align-items: center; gap: 8px; font-size: 10.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); }
|
||
.pq-gh .ic { width: 14px; height: 14px; flex: none; }
|
||
.pq-gn { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
/* how many accounts: a quiet count set by the name, on its cap height */
|
||
.pq-count { flex: none; min-width: 16px; height: 15px; padding: 0 5px; box-sizing: border-box; border-radius: 999px; display: inline-grid; place-items: center; background: color-mix(in srgb, var(--fg) 7%, transparent); color: var(--muted); font-size: 9.5px; font-weight: 600; line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums; }
|
||
.pq-gnote { flex: none; margin-left: auto; font-size: 12px; font-weight: 400; letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums; }
|
||
.pq-gnote.ends { color: var(--amber); }
|
||
/* used or left: a quiet pill at the right, over the rings; lit a moment
|
||
when it turns */
|
||
.pq-mode { flex: none; margin-left: auto; height: 15px; padding: 0 6px; border-radius: 999px; background: color-mix(in srgb, var(--fg) 7%, transparent); color: var(--muted); font-size: 9.5px; font-weight: 600; line-height: 15px; letter-spacing: .04em; text-transform: uppercase; transition: background .12s, color .12s; }
|
||
.pq-more { align-self: flex-start; height: 20px; padding: 0 8px; border-radius: 999px; background: color-mix(in srgb, var(--fg) 7%, transparent); color: var(--muted); font-size: 11px; transition: background .12s, color .12s; }
|
||
.pq-more:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); color: var(--fg); }
|
||
.pq-mode:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); color: var(--fg); }
|
||
.pq-gnote + .pq-mode { margin-left: 0; }
|
||
.pq-mode.flash { animation: pq-mode-flash .9s ease-out; }
|
||
@keyframes pq-mode-flash { 0%, 30% { background: var(--accent-soft); color: var(--accent); } }
|
||
@media (prefers-reduced-motion: reduce) { .pq-mode.flash { animation: none; } }
|
||
.pq-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px 12px; padding: 10px 12px; border-radius: 11px; background: var(--card); box-shadow: var(--card-edge); }
|
||
.pq-user { font-size: 12.5px; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.pq-sub { font-size: 11px; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||
.pq-sub.err { color: var(--muted); white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
|
||
.pq-rings { grid-row: 1 / 3; grid-column: 2; display: flex; gap: 12px; }
|
||
.pq-ring { display: flex; flex-direction: column; align-items: center; gap: 3px; cursor: pointer; }
|
||
.pq-dial { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: conic-gradient(var(--fg-2) calc(var(--p) * 1%), color-mix(in srgb, var(--fg) 9%, transparent) 0); }
|
||
.pq-dial b { width: 27px; height: 27px; border-radius: 50%; display: grid; place-items: center; background: var(--card); font-size: 9.5px; font-weight: 600; color: var(--fg-2); font-variant-numeric: tabular-nums; }
|
||
.pq-ring.full .pq-dial { background: conic-gradient(var(--amber) calc(var(--p) * 1%), color-mix(in srgb, var(--amber) 18%, transparent) 0); }
|
||
.pq-ring.full b { color: var(--fg); }
|
||
.pq-rn { max-width: 44px; font-size: 9.5px; line-height: 1.2; color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.pq-rn2 { display: flex; flex-direction: column; align-items: center; }
|
||
.pq-rn2 > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
|
||
/* the first window's current cycle, a thin line across the card (#651) */
|
||
.pq-spark-box { grid-column: 1 / -1; display: block; height: 16px; }
|
||
.pq-spark { display: block; width: 100%; height: 16px; overflow: hidden; }
|
||
.pq-spark .qc-line { stroke-width: 1.2; }
|
||
/* a Codex account's rate-limit resets, under a hairline across the card */
|
||
.pq-resets { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; margin-top: 5px; padding-top: 7px; border-top: 1px solid var(--line-2); font-size: 11px; font-variant-numeric: tabular-nums; }
|
||
.resets-words { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.resets-n { color: var(--fg-2); }
|
||
.resets-until { color: var(--faint); }
|
||
.pq-use { margin-left: auto; flex: none; height: 20px; padding: 0 9px; border-radius: 999px; background: color-mix(in srgb, var(--fg) 7%, transparent); color: var(--fg-2); font-size: 11px; white-space: nowrap; transition: background .12s, color .12s; }
|
||
.pq-use:hover { background: color-mix(in srgb, var(--fg) 12%, transparent); color: var(--fg); }
|
||
/* a Codex account spending its resets by itself (#719): a standing say of
|
||
the account's, held or not, its two times in words beside a switch */
|
||
.quota-autoreset, .pq-autoreset { display: flex; align-items: center; gap: 8px; color: var(--muted); }
|
||
.quota-autoreset { margin-top: 8px; font-size: 10.5px; }
|
||
.quota-resets + .quota-autoreset { margin-top: 6px; }
|
||
.subscription-card.several .quota-autoreset + .subscription-account { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line); }
|
||
.pq-autoreset { grid-column: 1 / -1; margin-top: 5px; padding-top: 7px; border-top: 1px solid var(--line-2); font-size: 11px; }
|
||
.pq-resets + .pq-autoreset { margin-top: 5px; padding-top: 0; border-top: 0; }
|
||
.ar-say { flex: 1; min-width: 0; line-height: 1.35; }
|
||
.ar-say b { font-weight: 500; color: var(--fg-2); }
|
||
.lib-switch.auto-reset { width: 28px; height: 16px; padding: 0; border: 0; cursor: pointer; }
|
||
.lib-switch.auto-reset i { width: 12px; height: 12px; }
|
||
.lib-switch.auto-reset.on i { transform: translateX(12px); }
|
||
.lib-switch.auto-reset:disabled { opacity: .6; cursor: default; }
|
||
.resets-kept { color: var(--faint); }
|
||
.resets-kept.on { color: var(--accent); }
|
||
/* in brief: the resets held and the say, beside the account's name */
|
||
.subscription-account .acct-auto { flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||
.subscription-account .acct-auto.on { color: var(--accent); }
|
||
.subscription-account .acct-auto-n { color: var(--muted); }
|
||
.subscription-account .acct-auto + .plan { margin-left: 0; }
|
||
.subscription-account .acct-auto + .quota-every { margin-left: 4px; }
|
||
.pq-bals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
|
||
.pq-card.bal { grid-template-columns: minmax(0, 1fr); }
|
||
.pq-bn { display: flex; align-items: center; gap: 6px; }
|
||
.pq-bn > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.pq-bn .ic { width: 14px; height: 14px; flex: none; }
|
||
.pq-amt { font-size: 15px; font-weight: 600; letter-spacing: -.01em; color: var(--fg); font-variant-numeric: tabular-nums; }
|
||
/* a balance field's several amounts on a balance's card (#420) */
|
||
.pq-lead { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
|
||
.pq-lead > span { min-width: 0; font-size: 11px; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.pq-bp { display: flex; align-items: baseline; gap: 6px; }
|
||
.pq-bp > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.pq-bp > b { margin-left: auto; flex: none; font-weight: 600; color: var(--fg-2); }
|
||
.pq-card.bal .quota-track { margin-top: 0; }
|
||
.pq-asof { color: var(--amber); }
|
||
.pq-card.stale > .pq-sub { white-space: normal; text-overflow: clip; overflow-wrap: anywhere; }
|
||
.pq-card > .pq-asof { grid-column: 1 / -1; }
|
||
.pq-card > .quota-balance { grid-column: 1 / -1; margin-top: 4px; }
|
||
.pq-card .skeleton.sk-aq { width: 130px; height: 9px; border-radius: 4px; }
|
||
.pq-card .skeleton.sk-ring { width: 34px; height: 34px; border-radius: 50%; }
|
||
/* the panel's footer: a hairline over it, as much room above as below */
|
||
/* even to the eye: the rule above is a pixel of the top's space, and the
|
||
panel's rim takes about one off the bottom's, so 1+5 over, 7 under */
|
||
body.panel .foot { min-height: 0; padding: 5px 8px 7px 14px; border-top: 1px solid var(--line-2); }
|
||
.pq-age { font-size: 12px; color: var(--muted); white-space: nowrap; }
|
||
.pq-age:not([hidden]) + .status:empty { display: none; }
|
||
#view-agents.loading .panel-quota { visibility: hidden; }
|
||
|
||
/* ---- profiles ------------------------------------------------------------- */
|
||
.profiles { display: flex; align-items: center; gap: 10px; padding: 10px 4px 2px; min-height: 36px; flex: none; }
|
||
.profiles .label { flex: none; }
|
||
.profiles .chips { flex: 1 1 0; min-width: 0; padding: 0; min-height: 0; }
|
||
.profiles #save { margin-left: auto; flex: none; }
|
||
.profiles > .chip-input { margin-left: auto; flex: none; }
|
||
.profiles > .chip-input + #save { margin-left: 0; }
|
||
/* switching profile is what the panel is opened for: a target to hit, not a tag */
|
||
.profiles .chips { gap: 8px; }
|
||
.profiles .chip { height: 30px; padding: 0 6px 0 13px; font-size: 13px; }
|
||
.profiles .chip .x { width: 20px; height: 20px; font-size: 13px; }
|
||
.profiles .chips .hint { line-height: 30px; }
|
||
.row-head { display: flex; align-items: center; height: 26px; }
|
||
.label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
|
||
/* several accounts: the button opening the ones in brief, in the head */
|
||
.subscription-card .quota-more { margin: -4px -7px -4px auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: 11px; color: var(--muted); }
|
||
.subscription-card .quota-more:hover { color: var(--fg); }
|
||
.text { font-size: 12px; color: var(--ctl-fg); padding: 3px 7px; border-radius: 6px; transition: background .12s, color .12s; white-space: nowrap; }
|
||
.text:hover { color: var(--fg); background: var(--pill); }
|
||
.text.action { height: 27px; padding: 0 10px; border: 1px solid var(--line); background: var(--card); color: var(--fg-2); box-shadow: 0 1px 1px rgba(0, 0, 0, .04); display: inline-flex; align-items: center; justify-content: center; }
|
||
.text.action:hover { border-color: var(--muted); background: var(--card-2); color: var(--fg); }
|
||
.text.primary { color: var(--accent-fg); background: var(--accent); font-weight: 500; }
|
||
.text.primary:hover { filter: brightness(1.08); }
|
||
.text.danger:hover { color: var(--red); background: var(--red-soft); }
|
||
.chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0 6px; min-height: 12px; }
|
||
.chip {
|
||
display: inline-flex; align-items: center; gap: 2px;
|
||
height: 25px; padding: 0 5px 0 10px;
|
||
border-radius: 999px;
|
||
border: 1px solid var(--line);
|
||
background: var(--card);
|
||
font-size: 12px;
|
||
transition: border-color .12s, background .12s, color .12s;
|
||
}
|
||
.chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
|
||
.chip .lib { width: 5px; height: 5px; margin: 0 2px 0 4px; border-radius: 50%; background: var(--accent); opacity: .7; flex: none; }
|
||
.chip .x { width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; line-height: 1; opacity: 0; transition: opacity .12s; }
|
||
.chip:hover .x { opacity: .6; }
|
||
.chip .x:hover { opacity: 1; background: rgba(127, 127, 127, .2); }
|
||
.chip .x.arm { width: auto; padding: 0 7px; border-radius: 10px; font-size: 11.5px; opacity: 1; color: var(--red); background: var(--red-soft); white-space: nowrap; }
|
||
.chip .x.arm:hover { background: var(--red-soft); }
|
||
/* a profile's details: what it holds, by agent, and its Apply (#467) */
|
||
.profiles .chip.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
|
||
.prof-detail {
|
||
flex: 1 1 100%; min-width: 0; box-sizing: border-box; padding: 9px 12px 10px;
|
||
border: 1px solid var(--line); border-radius: 10px; background: var(--card); font-size: 12px;
|
||
}
|
||
.pd-head { display: flex; align-items: center; gap: 10px; }
|
||
.pd-head.pd-foot { margin-top: 10px; }
|
||
body.window .profiles.detailed { align-items: flex-start; }
|
||
body.window .profiles.detailed > .label { line-height: 30px; }
|
||
body.window .profiles.detailed > #save { margin-top: 4px; }
|
||
.pd-name { flex: 1 1 auto; min-width: 0; font-weight: 600; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.pd-apply { flex: none; height: 24px; padding: 0 12px; }
|
||
.pd-close { flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 6px; background: none; color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer; }
|
||
.pd-close:hover { color: var(--fg); background: rgba(127, 127, 127, .15); }
|
||
.pd-agent { margin-top: 9px; }
|
||
.pd-gh { display: flex; align-items: center; gap: 6px; font-weight: 500; color: var(--fg-2); }
|
||
.pd-gh .ic { width: 14px; height: 14px; flex: none; }
|
||
.pd-gn { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.pd-fields { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px 12px; margin: 4px 0 0 20px; line-height: 1.5; }
|
||
.pd-fields dt { color: var(--muted); }
|
||
.pd-fields dd { margin: 0; min-width: 0; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.pd-fields dd.pd-default, .pd-fields dd.pd-hidden { color: var(--faint); }
|
||
.pd-none { margin-top: 8px; font-size: 11.5px; line-height: 1.4; color: var(--muted); }
|
||
/* its save, update or use on the way (profileAction) */
|
||
.chip.pending { opacity: .55; pointer-events: none; }
|
||
.chip-input {
|
||
height: 25px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--accent);
|
||
background: var(--card); outline: none; width: 140px; font-size: 12px;
|
||
}
|
||
/* its accent border is the focus: the page's focus ring over it doubled it,
|
||
and the panel's list, 2px under the tabs, cut its top off */
|
||
.chip-input:focus-visible { outline: none; }
|
||
.chips .hint { font-size: 11.5px; color: var(--muted); line-height: 25px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
|
||
/* ---- footer --------------------------------------------------------------- */
|
||
.foot { display: flex; align-items: center; gap: 2px; padding: 0 8px 6px 14px; min-height: 28px; flex: none; }
|
||
body.window .foot { padding-left: 18px; }
|
||
.status { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .3s; }
|
||
.status.ok { color: var(--green); }
|
||
.status.err { color: var(--red); }
|
||
.status.warn { color: var(--amber); }
|
||
/* an outcome (Refresh, Test models…) stands out from the corner it is in:
|
||
a solid pill in its colour, over a window the desktop shows through */
|
||
.status.ok, .status.err, .status.warn { font-size: 12.5px; font-weight: 500; padding: 3px 10px; border-radius: 999px; background: color-mix(in srgb, currentColor 16%, var(--bg)); box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 30%, transparent); }
|
||
.status.lift { position: fixed; z-index: 21; font-size: 12.5px; font-weight: 500; padding: 3px 10px; border-radius: 999px; background: color-mix(in srgb, currentColor 16%, var(--card)); left: 50%; bottom: 18px; transform: translateX(-50%); max-width: calc(100vw - 32px); box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 30%, transparent), 0 6px 20px rgba(0, 0, 0, .28); animation: fade-in .2s var(--ease); }
|
||
|
||
/* ---- picker popover ------------------------------------------------------- */
|
||
.pop {
|
||
position: fixed; z-index: 30; /* above the modal (20): a picker opened from the provider editor must show over it */
|
||
width: 320px; max-height: 340px;
|
||
display: flex; flex-direction: column;
|
||
background: var(--pop-bg);
|
||
-webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
|
||
border-radius: 11px;
|
||
box-shadow: var(--shadow);
|
||
overflow: hidden;
|
||
/* it grows out of the button it drops from (--ox, its middle), quick to
|
||
answer and a long soft settle with no bounce, the way iOS's menus come;
|
||
it shows at once and fades out ahead of its motion on the way out */
|
||
transform-origin: var(--ox, 24px) top;
|
||
animation: pop-fade .18s ease-out, pop-in .42s cubic-bezier(.16, 1, .3, 1);
|
||
}
|
||
.pop.up { transform-origin: var(--ox, 24px) bottom; --pop-dy: 6px; }
|
||
@keyframes pop-fade { from { opacity: 0; } }
|
||
@keyframes pop-in { from { transform: translateY(var(--pop-dy, -6px)) scale(.94); } }
|
||
/* a closed picker's likeness going: it sinks back toward the button */
|
||
.pop.leaving { pointer-events: none; animation: pop-out .22s cubic-bezier(.4, 0, .7, .2) forwards; }
|
||
@keyframes pop-out { to { opacity: 0; transform: translateY(calc(var(--pop-dy, -6px) * .6)) scale(.96); } }
|
||
@media (prefers-reduced-motion: reduce) { .pop { animation: pop-fade .12s ease-out; } .pop.leaving { animation: none; } }
|
||
.pop .search { display: flex; align-items: center; gap: 8px; padding: 0 12px; border-bottom: 1px solid var(--line-2); color: var(--faint); }
|
||
.pop input { flex: 1; background: none; border: 0; outline: none; height: 36px; font-size: 13px; }
|
||
.pop input::placeholder { color: var(--faint); }
|
||
.picker-body { display: flex; min-height: 0; flex: 1 1 auto; }
|
||
#pickerRail[hidden] { display: none; }
|
||
#pickerRail { position: relative; width: 43px; padding: 6px 5px; border-right: 1px solid var(--line-2); display: flex; flex-direction: column; align-items: center; gap: 3px; flex: none; overflow-y: auto; overflow-x: hidden; scrollbar-width: none; }
|
||
/* it draws its own thumb (.rail-thumb) */
|
||
#pickerRail::-webkit-scrollbar { width: 0; height: 0; }
|
||
.rail-thumb { position: absolute; z-index: 0; top: 0; left: 5px; width: 31px; height: 31px; border-radius: 8px; opacity: 0; background: var(--sel); box-shadow: inset 0 0 0 1px var(--line-2), 0 1px 2px rgba(0, 0, 0, .06); pointer-events: none; transition: transform 260ms cubic-bezier(.22, 1, .36, 1), opacity 100ms ease-out; will-change: transform; }
|
||
.rail-item { position: relative; z-index: 1; width: 31px; height: 31px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: var(--muted); flex: none; transition: color 150ms ease-out, transform 150ms cubic-bezier(.25, 1, .5, 1); }
|
||
.rail-item:hover { color: var(--fg); background: color-mix(in srgb, var(--pill) 68%, transparent); }
|
||
.rail-item:active { transform: scale(.94); }
|
||
.rail-item.on { color: var(--fg); background: transparent; }
|
||
.rail-item .ic { width: 16px; height: 16px; transition: transform 220ms cubic-bezier(.22, 1, .36, 1); }
|
||
.rail-item.on .ic { transform: scale(1.04); }
|
||
/* a rail icon's name, drawn beside it (renderPickerRail's showRailTip) */
|
||
.rail-tip { position: fixed; z-index: 31; top: 0; left: 0; transform: translate(-3px, -50%); padding: 3px 8px; border-radius: 6px; background: var(--fg); color: var(--bg); font-size: 11.5px; font-weight: 500; line-height: 16px; white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; pointer-events: none; opacity: 0; visibility: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, .18); transition: opacity 90ms ease-out, transform 140ms cubic-bezier(.22, 1, .36, 1), visibility 0s 90ms; }
|
||
.rail-tip.left { transform: translate(3px, -50%); }
|
||
.rail-tip.on { opacity: 1; visibility: visible; transform: translate(0, -50%); transition: opacity 90ms ease-out, transform 140ms cubic-bezier(.22, 1, .36, 1); }
|
||
@media (prefers-reduced-motion: reduce) { .rail-tip, .rail-tip.on { transition: none; } }
|
||
.rail-sep { width: 24px; height: 1px; margin: 2px 0; background: var(--line-2); flex: none; }
|
||
.pop ul { list-style: none; overflow-y: auto; padding: 5px; min-width: 0; flex: 1 1 auto; contain: paint; }
|
||
.pop li {
|
||
display: flex; align-items: center; gap: 9px;
|
||
height: 30px; padding: 0 8px; border-radius: 7px;
|
||
white-space: nowrap; font-size: 12.5px;
|
||
}
|
||
.pop li .ic { width: 16px; height: 16px; }
|
||
.pop li .option-words { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; gap: 9px; }
|
||
.pop li .v { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
|
||
.pop li .badge.free, .pop li .badge.ctx, .pop li .badge.rate, .pop li .badge.path { flex: none; margin-left: -4px; padding: 0 4px; font-size: 9px; line-height: 14px; align-self: center; }
|
||
.pop li .n { flex: 1 1 0; min-width: 0; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
|
||
.pop li .favorite { display: none; align-items: center; justify-content: center; color: var(--faint); width: 24px; height: 24px; border-radius: 6px; flex: none; }
|
||
.pop li:hover .favorite, .pop li .favorite.on { display: inline-flex; }
|
||
.pop li .favorite:hover { color: var(--amber); background: var(--pill-hover); }
|
||
.pop li .favorite.on { color: var(--amber); }
|
||
/* not a favourite: an outline star, on hover; a favourite: a filled one, always */
|
||
.pop li .favorite.on path { fill: currentColor; }
|
||
.pop.explained li { height: auto; padding: 7px 8px; white-space: normal; align-items: flex-start; }
|
||
.pop.explained li .option-words { flex-direction: column; align-items: flex-start; gap: 2px; }
|
||
.pop.explained li .n { flex: none; overflow: visible; line-height: 1.4; }
|
||
.pop.model-picker { max-height: 420px; border: 1px solid var(--line); }
|
||
.pop.model-picker .search { min-height: 39px; }
|
||
.pop.model-picker .search input { height: 38px; }
|
||
.pop.model-picker li:not(.group) { height: 34px; padding: 0 8px; }
|
||
.pop.model-picker li .option-words { flex-direction: row; align-items: baseline; justify-content: flex-start; gap: 9px; }
|
||
.pop.model-picker li .v { max-width: 62%; font-size: 12.5px; line-height: 18px; flex: 0 1 auto; }
|
||
.pop.model-picker li .n { width: auto; flex: 1 1 0; font-size: 10.5px; line-height: 18px; }
|
||
.pop.model-picker li.group { height: 24px; padding-top: 7px; }
|
||
/* the effort slider: a thin track filled in the text colour up to the
|
||
level, a dot at every stop, the ends named beneath it */
|
||
.pop.effort-picker { max-height: none; border-radius: 12px; }
|
||
.effort-control { padding: 12px 14px 11px; }
|
||
.effort-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; font-size: 11.5px; }
|
||
.effort-head span { color: var(--muted); }
|
||
.effort-head b { margin-left: auto; color: var(--fg); font-size: 12.5px; font-weight: 600; }
|
||
.effort-track { --fill: 0%; position: relative; height: 20px; }
|
||
.effort-ticks { position: absolute; z-index: 3; left: 8px; right: 8px; top: 8.5px; height: 3px; pointer-events: none; }
|
||
.effort-ticks i { position: absolute; left: calc(var(--at) * 100%); width: 3px; height: 3px; margin-left: -1.5px; border-radius: 50%; background: var(--faint); transition: background-color 120ms ease-out; }
|
||
.effort-ticks i.on { background: var(--card); opacity: .7; }
|
||
.effort-ticks i.cur { opacity: 0; }
|
||
.effort-control input[type="range"] { --fill: 0%; position: relative; z-index: 2; display: block; width: 100%; height: 20px; margin: 0; padding: 0; appearance: none; -webkit-appearance: none; background: transparent; outline: none; cursor: pointer; }
|
||
.effort-control input[type="range"]::-webkit-slider-runnable-track { height: 4px; border-radius: 999px; background: linear-gradient(90deg, var(--fg) 0 var(--fill), var(--line) var(--fill) 100%); }
|
||
.effort-control input[type="range"]::-webkit-slider-thumb { width: 16px; height: 16px; margin-top: -6px; border: 0; border-radius: 50%; appearance: none; -webkit-appearance: none; background: #fff; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .18), 0 1px 3px rgba(0, 0, 0, .22); transition: transform 140ms cubic-bezier(.25, 1, .5, 1); }
|
||
.effort-control input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.08); }
|
||
.effort-control input[type="range"]:active::-webkit-slider-thumb { transform: scale(.94); }
|
||
.effort-control input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 .5px rgba(0, 0, 0, .18), 0 1px 3px rgba(0, 0, 0, .22), 0 0 0 3px var(--accent-soft); }
|
||
.effort-ends { display: flex; justify-content: space-between; margin-top: 5px; font-size: 10.5px; color: var(--muted); opacity: .8; }
|
||
.pop li.sel { background: var(--sel); }
|
||
.pop li .check { color: var(--accent); display: none; margin-left: auto; flex: none; }
|
||
.pop li.cur .check { display: inline-flex; }
|
||
.pop li.group { height: 22px; padding: 6px 8px 0; font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--faint); pointer-events: none; }
|
||
.pop li.group:not(:first-child) { margin-top: 2px; }
|
||
.pop li.reset { margin-bottom: 3px; }
|
||
.pop li.reset .v { color: var(--fg); }
|
||
.pop li.reset .ic { opacity: .75; }
|
||
.pop li.custom .v { color: var(--fg); }
|
||
.pop li.custom .n { color: var(--muted); }
|
||
/* the models on the agent's own account through magpie, folded into one
|
||
row (#496): a chevron says it opens, turned down while open */
|
||
.pop li.fold .v { color: var(--muted); }
|
||
.pop li.fold .chev { display: inline-flex; margin-left: auto; flex: none; color: var(--faint); transition: transform .18s cubic-bezier(.22, 1, .36, 1); }
|
||
.pop li.fold.open .chev { transform: rotate(90deg); }
|
||
@media (prefers-reduced-motion: reduce) { .pop li.fold .chev { transition: none; } }
|
||
/* a model kept for routing groups, found by the filter: why it isn't
|
||
offered, and what to do, below the choices */
|
||
.pop li.kept, .pop.model-picker li.kept { height: auto; align-items: flex-start; padding: 8px; margin-top: 3px; border-top: 1px solid var(--line); border-radius: 0; white-space: normal; cursor: default; }
|
||
.pop li.kept .ic { margin-top: 1px; flex: none; }
|
||
.pop li.kept .kept-words { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
|
||
.pop li.kept .kept-words b { color: var(--fg); font-weight: 500; font-size: 12.5px; }
|
||
.pop li.kept .text.action { flex: none; align-self: center; height: 25px; }
|
||
.model-hint.warn { color: var(--amber); }
|
||
.model-hint .text { margin-left: 4px; }
|
||
.pop .none { padding: 10px 12px; color: var(--muted); font-size: 12px; white-space: normal; line-height: 1.45; }
|
||
.pop.keying .search { border-bottom-color: var(--accent); color: var(--accent); }
|
||
.pop .none b { color: var(--fg); font-weight: 500; }
|
||
|
||
/* ---- gateway page --------------------------------------------------------- */
|
||
/* Loading keeps the final geometry in place, so entering Gateway feels calm
|
||
even while provider discovery and account checks are still running. */
|
||
.pv-sk-row { min-height: 45px; }
|
||
.pv-sk-icon { width: 18px; height: 18px; border-radius: 5px; flex: none; }
|
||
.pv-sk-who { display: flex; flex-direction: column; justify-content: center; gap: 6px; }
|
||
.pv-sk-name { width: 112px; height: 11px; }
|
||
.pv-sk-sub { width: min(260px, 64%); height: 8px; }
|
||
.pv-sk-key { width: 64px; height: 18px; border-radius: 9px; flex: none; }
|
||
#view-providers.loading .after-list { visibility: hidden; }
|
||
/* the agents' rows while they are first read: the icon, the name and the two setting columns */
|
||
.ag-sk-icon { width: 18px; height: 18px; border-radius: 5px; flex: none; }
|
||
body.window .ag-sk-icon { width: 22px; height: 22px; border-radius: 6px; }
|
||
.ag-sk-name { width: 92px; height: 11px; }
|
||
.ag-sk-field { height: 25px; border-radius: 6px; }
|
||
.ag-sk-row:nth-child(2n) .ag-sk-name { width: 64px; }
|
||
.ag-sk-row:nth-child(3n) .ag-sk-name { width: 78px; }
|
||
/* the panel's rows: what is set, as words at the right, then its bars and chevron */
|
||
.ag-sk-sum { display: flex; align-items: center; gap: 10px; }
|
||
.ag-sk-value { width: 96px; height: 10px; }
|
||
.ag-sk-row:nth-child(2n) .ag-sk-value { width: 124px; }
|
||
.ag-sk-row:nth-child(3n) .ag-sk-value { width: 72px; }
|
||
.ag-sk-bars { width: 13px; height: 12px; border-radius: 3px; margin-right: 20px; }
|
||
#view-agents.loading .profiles { visibility: hidden; }
|
||
.gw-sk-dot { width: 8px; height: 8px; margin: 0 7px; border-radius: 50%; flex: none; }
|
||
.gw-sk-who { display: flex; flex-direction: column; justify-content: center; gap: 6px; }
|
||
.gw-sk-title { width: 118px; height: 12px; }
|
||
.gw-sk-sub { width: min(330px, 72%); height: 8px; }
|
||
.gw-sk-url { width: 154px; height: 24px; border-radius: 6px; flex: none; }
|
||
.gw-sk-label { width: 46px; height: 8px; align-self: center; justify-self: end; }
|
||
.gw-sk-field { min-height: 30px; display: flex; flex-direction: column; justify-content: center; gap: 5px; }
|
||
.gw-sk-field .skeleton { width: min(310px, 72%); height: 10px; }
|
||
.gw-sk-field .skeleton.short { width: min(210px, 48%); height: 7px; }
|
||
.gw-sk-row { pointer-events: none; }
|
||
.gw-sk-model { width: 190px; height: 10px; }
|
||
.gw-sk-provider { width: 82px; height: 9px; }
|
||
.gw-sk-call { cursor: default; pointer-events: none; }
|
||
.gw-sk-call .skeleton { height: 8px; }
|
||
.gw-sk-call .time { width: 54px; }
|
||
.gw-sk-call .agent { width: 62px; }
|
||
.gw-sk-call .model { width: 150px; }
|
||
.gw-sk-call .result { width: 68px; }
|
||
/* the status card: a dot where the logo would be, the URL as a pill */
|
||
.gwcard { margin: 4px 0 2px; }
|
||
.gw .dot { width: 8px; height: 8px; margin: 0 7px; border-radius: 50%; background: var(--amber); flex: none; box-shadow: 0 0 0 3px var(--amber-soft); }
|
||
.gw .dot.on { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); }
|
||
.gw .who { flex: 1 1 auto; }
|
||
.gw .name .state { margin-left: 8px; font-size: 11px; font-weight: 500; color: var(--green); }
|
||
.gw .dot:not(.on) ~ .who .state { color: var(--amber); }
|
||
.gw .sub.old { white-space: normal; overflow: visible; text-overflow: clip; }
|
||
.gw .url { display: inline-flex; align-items: center; height: 24px; padding: 0 8px; border-radius: 6px; background: var(--pill); box-shadow: inset 0 0 0 1px var(--line-2); flex: none; transition: background .12s, box-shadow .12s; }
|
||
.gw .url:hover { background: var(--pill-hover); box-shadow: inset 0 0 0 1px var(--line); }
|
||
.gw .url code { color: var(--fg-2); font-size: 11px; }
|
||
.gw .url:hover code { color: var(--fg); }
|
||
#view-gateway .row-head, #view-usage .row-head { margin: 14px 0 6px; padding: 0 2px; }
|
||
#view-usage .row-head.quota-head { margin: 6px 0 6px; }
|
||
#view-gateway .row-head .note { font-size: 11px; color: var(--faint); }
|
||
/* providers switched off, folded below the ones on */
|
||
#view-providers .off-head { margin: 14px 0 6px; padding: 0 2px; flex: none; }
|
||
#view-providers .off-head .note { font-size: 11px; color: var(--faint); }
|
||
/* the Models head folds the list away: a chevron, the label, how many */
|
||
.fold { display: inline-flex; align-items: center; gap: 5px; margin-left: -4px; padding: 3px 6px 3px 4px; border-radius: 6px; color: var(--faint); transition: background .12s, color .12s; }
|
||
.fold:hover { background: var(--pill); color: var(--muted); }
|
||
.fold svg { flex: none; transform: rotate(90deg); transition: transform .15s ease-out; }
|
||
.fold[aria-expanded="false"] svg { transform: none; }
|
||
.fold .note { font-variant-numeric: tabular-nums; }
|
||
/* Connect folded: the base URL stays in its head, to copy */
|
||
#connectNote.brief { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
|
||
#connectNote.brief code { font-size: 11px; color: var(--fg-2); user-select: text; -webkit-user-select: text; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
#connectNote.brief .copy { width: 20px; height: 20px; }
|
||
|
||
/* the connect card: label column, then the value with a copy button */
|
||
.connect { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 10px 14px; align-items: start; padding: 12px 14px 14px; }
|
||
.connect > div { min-width: 0; }
|
||
.connect label { font-size: 12px; color: var(--fg-2); text-align: right; padding-top: 4px; }
|
||
.connect .hint { font-size: 11px; color: var(--fg-2); margin-top: 4px; line-height: 1.4; }
|
||
.connect .val { display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 4px 0 9px; border-radius: 7px; background: var(--pill); box-shadow: inset 0 0 0 1px var(--line-2); max-width: 100%; }
|
||
.connect .val code { font-size: 12px; color: var(--fg); user-select: text; -webkit-user-select: text; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.connect .val > .val { min-width: 0; height: auto; padding: 0; background: none; box-shadow: none; }
|
||
.connect .segs { margin-top: -1px; }
|
||
.connect .stack { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
|
||
@media (max-width: 520px) {
|
||
.connect { grid-template-columns: 48px minmax(0, 1fr); column-gap: 8px; padding-left: 10px; padding-right: 10px; }
|
||
}
|
||
.copy { width: 22px; height: 22px; border-radius: 5px; display: inline-flex; align-items: center; justify-content: center; color: var(--muted); flex: none; transition: background .12s, color .12s; }
|
||
.copy:hover { background: var(--pill-hover); color: var(--fg); }
|
||
.copy.done { color: var(--green); background: var(--green-soft); animation: copy-pop .36s var(--ease); }
|
||
@keyframes copy-pop { 0% { transform: scale(.55); } 55% { transform: scale(1.16); } 100% { transform: scale(1); } }
|
||
.snip-wrap { position: relative; min-width: 0; }
|
||
.snip { margin: 0; padding: 10px 40px 10px 12px; border-radius: 9px; background: var(--card); border: 1px solid var(--line); overflow-x: auto; line-height: 1.55; }
|
||
.snip code { font-size: 11.5px; color: var(--fg); white-space: pre; user-select: text; -webkit-user-select: text; }
|
||
.snip-wrap > .copy { position: absolute; top: 6px; right: 6px; background: var(--card); }
|
||
.snip-wrap > .copy:hover { background: var(--pill-hover); }
|
||
.snip-wrap > .copy.done { background: var(--green-soft); }
|
||
.tk-s { color: var(--tk-s); } .tk-k { color: var(--tk-k); } .tk-f { color: var(--tk-f); } .tk-n { color: var(--tk-n); }
|
||
.tk-v { color: var(--tk-v); } .tk-o { color: var(--tk-o); } .tk-c { color: var(--tk-c); font-style: italic; }
|
||
.snip::-webkit-scrollbar { height: 0; }
|
||
|
||
/* the model list: id first, the human name and vendor under it */
|
||
.row.model { min-height: 40px; cursor: default; }
|
||
.row.model:hover { background: var(--card-2); }
|
||
.row.model.selected { background: var(--sel); }
|
||
.row.model .name { font: 12px var(--code); }
|
||
.row.model .who { user-select: text; -webkit-user-select: text; cursor: text; }
|
||
.row.model .sub { color: var(--fg-2); }
|
||
.row.model .copy { opacity: 0; }
|
||
.row.model:hover .copy, .row.model.selected .copy { opacity: 1; }
|
||
.row.model .copy.done { opacity: 1; }
|
||
|
||
/* recent calls */
|
||
.activity { padding: 5px 8px 6px; font-size: 11.5px; }
|
||
.activity .none { padding: 8px 6px; color: var(--muted); line-height: 1.45; }
|
||
.activity .activity-more { display: flex; align-items: center; justify-content: center; width: 100%; height: 25px; margin-top: 2px; font-size: 11px; color: var(--muted); }
|
||
.call-item + .call-item { border-top: 1px solid transparent; }
|
||
.call-item.open { margin: 2px 0 5px; border-radius: 8px; background: var(--card-2); box-shadow: inset 0 0 0 1px var(--line-2); overflow: hidden; }
|
||
.call { display: flex; align-items: center; gap: 10px; height: 24px; padding: 0 6px; border-radius: 6px; white-space: nowrap; cursor: pointer; outline: none; }
|
||
.call:hover { background: var(--pill); }
|
||
.call:focus-visible { box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 2px var(--accent-soft); }
|
||
.call-chev { width: 10px; height: 16px; display: inline-flex; align-items: center; justify-content: center; color: var(--faint); flex: none; transition: transform .15s ease-out, color .12s; }
|
||
.call:hover .call-chev { color: var(--muted); }
|
||
.call-item.open .call-chev { transform: rotate(90deg); }
|
||
.call .when { color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.call .a { color: var(--fg-2); flex: 0 0 auto; max-width: 90px; overflow: hidden; text-overflow: ellipsis; }
|
||
.call .m { font-family: var(--code); font-size: 11px; color: var(--fg); overflow: hidden; text-overflow: ellipsis; }
|
||
.call .p { color: var(--muted); }
|
||
.call .st { color: var(--green); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; max-width: 55%; }
|
||
.call-item.bad .st { color: var(--red); }
|
||
.call-details { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1px; border-top: 1px solid var(--line-2); background: var(--line-2); }
|
||
.call-body { min-width: 0; background: var(--card); }
|
||
.call-body-head { height: 29px; padding: 0 8px 0 10px; display: flex; align-items: center; gap: 7px; color: var(--muted); }
|
||
.call-body-label { font-size: 10.5px; font-weight: 600; letter-spacing: .015em; }
|
||
.call-body-truncated { font-size: 9.5px; color: var(--amber); }
|
||
.call-body .copy { width: 20px; height: 20px; }
|
||
.call-body pre { margin: 0; padding: 9px 10px 11px; min-height: 54px; max-height: 280px; overflow: auto; border-top: 1px solid var(--line-2); background: var(--code-bg, var(--card-2)); }
|
||
.call-body code { display: block; font: 10.5px/1.5 var(--code); color: var(--fg-2); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; tab-size: 2; }
|
||
.call-body code.empty { color: var(--faint); font-family: var(--font); }
|
||
@media (max-width: 760px) { .call-details { grid-template-columns: 1fr; } }
|
||
/* a call the request archive kept: read back under the bodies, the whole width */
|
||
.call-archive { grid-column: 1 / -1; min-width: 0; background: var(--card); }
|
||
.call-archive-id { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 10px var(--code); color: var(--faint); }
|
||
.call-archive .call-body-head button.text { flex: none; }
|
||
.call-archive-err { padding: 0 10px 9px; font-size: 11px; color: var(--red); overflow-wrap: anywhere; }
|
||
.call-archive-big { margin: 0; padding: 9px 10px 11px; border-top: 1px solid var(--line-2); font-size: 11px; color: var(--muted); }
|
||
/* a request's row on the Usage page: its archive under what is known of it */
|
||
.led-archive { margin-top: 10px; border: 1px solid var(--line-2); border-radius: 8px; overflow: hidden; }
|
||
.led-archive .call-details { grid-template-columns: minmax(0, 1fr); }
|
||
/* a streamed reply: read as its reply, its events or as it came */
|
||
.call-body-count { font-size: 9.5px; color: var(--faint); white-space: nowrap; }
|
||
.call-body-head .sse-views { align-self: center; padding: 1.5px; border-radius: 6px; }
|
||
.call-body-head .sse-views .opt { height: 19px; padding: 0 8px; font-size: 10.5px; }
|
||
.call-body-head .sse-views .thumb { top: 1.5px; bottom: 1.5px; }
|
||
.sse-ev { display: block; }
|
||
.sse-ev + .sse-ev { margin-top: 9px; padding-top: 9px; border-top: 1px dashed var(--line-2); }
|
||
.sse-name { color: var(--muted); }
|
||
.call-body-foot { height: 27px; padding: 0 6px 0 10px; display: flex; align-items: center; gap: 7px; border-top: 1px solid var(--line-2); font-size: 10.5px; color: var(--muted); }
|
||
.call-body-foot[hidden] { display: none; }
|
||
.call-body-foot .link { font-size: 11px; }
|
||
|
||
/* ---- providers page ------------------------------------------------------- */
|
||
.provider .chev { color: var(--faint); display: inline-flex; transition: transform .15s; }
|
||
.provider.selected .chev { transform: rotate(90deg); }
|
||
/* a provider row: logo, name, the agents on it, key status */
|
||
.provider .who { flex: 1 1 auto; }
|
||
.provider .name .badge { margin-left: 6px; }
|
||
.badge { font-size: 9.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; padding: 1px 5px; border-radius: 4px; background: var(--amber-soft); color: var(--amber); vertical-align: 1px; }
|
||
.provider.selected { background: var(--card-2); }
|
||
/* switched off (#163): kept, dimmed, and said so by its name */
|
||
.provider.off > .ic, .provider.off .who .sub, .provider.off .uses, .provider.off .key { opacity: .45; }
|
||
.provider.off .name { color: var(--muted); }
|
||
.badge.off { background: var(--pill); color: var(--muted); }
|
||
.badge.free { background: var(--green-soft); color: var(--green); }
|
||
/* a model's context, when it is a large one: grey, as it is a fact, not a warning */
|
||
/* which way a model goes (#726): through magpie, or straight to its vendor */
|
||
.badge.path { letter-spacing: .02em; text-transform: none; white-space: nowrap; }
|
||
.badge.path.via { background: var(--accent-soft); color: var(--accent); }
|
||
.badge.path.direct { background: var(--pill); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); }
|
||
.badge.ctx { background: var(--pill); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); letter-spacing: .02em; }
|
||
.badge.wsl { background: var(--pill); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); letter-spacing: .02em; text-transform: none; }
|
||
/* a model's credit rate (0.5×): grey, a fact to pick by; a discount's price before it struck through */
|
||
.badge.rate { background: var(--pill); color: var(--muted); letter-spacing: .02em; text-transform: none; font-variant-numeric: tabular-nums; display: inline-flex; gap: 3px; }
|
||
.badge.rate s { font-weight: 500; opacity: .75; }
|
||
/* the one API a model is asked on, picked by the user: the accent, as a choice made */
|
||
.badge.mapi-tag { background: var(--accent-soft); color: var(--accent); letter-spacing: .02em; text-transform: none; }
|
||
.mchip .badge { margin: 0 -3px 0 1px; padding: 0 4px; font-size: 9px; line-height: 14px; }
|
||
.row.model .name .badge { margin-left: 6px; padding: 0 4px; font: 600 9px/14px var(--font); }
|
||
.row.model .minfo { display: inline-flex; align-items: center; gap: 4px; flex: none; margin-left: 8px; cursor: help; }
|
||
.row.model .minfo .badge { display: inline-flex; align-items: center; padding: 0 5px; font: 600 9.5px/16px var(--font); letter-spacing: .02em; text-transform: none; background: var(--pill); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line); vertical-align: 0; }
|
||
.row.model .minfo .mi-ctx { font-variant-numeric: tabular-nums; }
|
||
.row.model .minfo .mi-img { padding: 0 4px; }
|
||
.row.model .minfo .mi-img svg { display: block; }
|
||
.provider .pswitch { margin-left: 8px; }
|
||
.editor .off-note { grid-column: 1 / -1; }
|
||
.uses { display: flex; align-items: center; gap: 4px; margin-left: auto; flex: none; }
|
||
.use {
|
||
width: 26px; height: 26px; border-radius: 8px;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
background: var(--pill); box-shadow: inset 0 0 0 1px var(--line-2);
|
||
transition: background .12s, box-shadow .12s, color .12s;
|
||
}
|
||
.use .ic { width: 16px; height: 16px; }
|
||
.use:hover, .use.open { background: var(--pill-hover); box-shadow: inset 0 0 0 1px var(--line); }
|
||
.use.open { box-shadow: inset 0 0 0 1px var(--accent); }
|
||
.use.add { background: none; box-shadow: none; border: 1px dashed var(--line); color: var(--faint); }
|
||
.use.add:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
|
||
.key { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: 6px; font: 11px var(--code); color: var(--muted); white-space: nowrap; flex: none; margin-left: 4px; width: 128px; overflow: hidden; font-variant-numeric: tabular-nums; }
|
||
.key::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: none; }
|
||
.key > span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
|
||
.key.free { font-family: var(--font); color: var(--faint); }
|
||
.key.free::before { background: var(--faint); }
|
||
.key.none { font-family: var(--font); color: var(--amber); background: var(--amber-soft); }
|
||
.key.none::before { background: var(--amber); }
|
||
.key.acct { font-family: var(--font); }
|
||
.acct { display: flex; align-items: center; gap: 8px; min-height: 26px; font-size: 12.5px; }
|
||
.acct .n { font-weight: 500; }
|
||
.acct .plan { color: var(--muted); font-size: 11.5px; padding: 1px 6px; border-radius: 5px; background: var(--pill-hover); }
|
||
/* a subscription's accounts: the one in use first, a way to add another */
|
||
.accts { display: grid; grid-template-columns: minmax(0, 1fr); border: 1px solid var(--line); border-radius: 10px; background: var(--card); overflow: hidden; }
|
||
.acc { display: flex; align-items: center; gap: 9px; min-height: 38px; padding: 5px 8px 5px 11px; font-size: 12.5px; text-align: left; }
|
||
.acc + .acc, .accts .signing { border-top: 1px solid var(--line-2); }
|
||
.editor .accts .keep-login { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-height: 34px; padding: 6px 11px; font-size: 12px; border-top: 1px solid var(--line-2); }
|
||
.editor .accts .keep-login .keep-as { max-width: 240px; }
|
||
.acc .n { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.acc .plan { color: var(--muted); font-size: 11px; padding: 1px 6px; border-radius: 5px; background: var(--pill); white-space: nowrap; }
|
||
.acc .grow { flex: 1; }
|
||
.acc .dot { width: 16px; height: 16px; flex: none; border-radius: 50%; display: grid; place-items: center; box-shadow: inset 0 0 0 1.5px var(--faint); color: var(--muted); }
|
||
.acc.in-use .dot { background: var(--fg); box-shadow: none; color: var(--card); }
|
||
.acc .using { font-size: 11px; color: var(--fg-2); padding: 2px 8px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); }
|
||
.acc .text.quiet { opacity: 0; transition: opacity .15s; }
|
||
.acc:hover .text.quiet { opacity: 1; }
|
||
.acc .text.quiet:focus-visible { opacity: 1; }
|
||
.acc.new { animation: sub-in .5s cubic-bezier(.2, .8, .2, 1); }
|
||
.acc.new .dot { animation: copy-pop .45s cubic-bezier(.2, .8, .2, 1); }
|
||
@keyframes sub-in { from { opacity: 0; transform: translateY(-4px); background: var(--pill-hover); } }
|
||
.acc.add { width: 100%; color: var(--fg-2); background: none; border: 0 solid var(--line-2); cursor: default; }
|
||
.acc + .acc.add { border-top-width: 1px; }
|
||
.acc.add .dot { box-shadow: inset 0 0 0 1.5px var(--faint); border-radius: 50%; }
|
||
.acc.add .n { font-weight: 450; }
|
||
.acc.add:hover { background: var(--card-2); color: var(--fg); }
|
||
.acc.add:hover .dot { box-shadow: inset 0 0 0 1.5px var(--fg); color: var(--fg); }
|
||
|
||
.acc .rename { font: inherit; font-weight: 500; color: inherit; background: none; border: 0; padding: 0; cursor: text; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.acc .rename:hover { text-decoration: underline dotted var(--faint); text-underline-offset: 3px; }
|
||
.acc .dot.tick { padding: 0; border: 0; background: none; cursor: default; transition: background .15s, box-shadow .15s; }
|
||
.acc .dot.tick:hover { box-shadow: inset 0 0 0 1.5px var(--fg); }
|
||
.acc.in-use .dot.tick { background: var(--fg); }
|
||
.acc.off .n, .acc.off .plan { opacity: .55; }
|
||
.acc .rename.mono { font-family: var(--code); font-size: 11.5px; font-weight: 450; }
|
||
.acc .rename-in { height: 24px; padding: 0 7px; font-size: 12.5px; max-width: 220px; }
|
||
.acc .plan.mono { font-family: var(--code); font-size: 10.5px; }
|
||
.acc.adding { display: grid; gap: 8px; padding: 10px 10px 8px 11px; background: var(--card-2); }
|
||
.acc.adding .kf { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 6px; }
|
||
.acc.adding .kb { display: flex; align-items: center; gap: 4px; }
|
||
.acc.adding .kb .grow { flex: 1; }
|
||
.acc + .acc.adding { border-top: 1px solid var(--line-2); }
|
||
@media (max-width: 520px) { .acc.adding .kf { grid-template-columns: 1fr; } }
|
||
.acc.adding .bulk-keys { width: 100%; box-sizing: border-box; resize: vertical; min-height: 84px; font-family: var(--code); font-size: 11.5px; line-height: 1.5; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--fg); }
|
||
.acc.adding .bulk-count { margin-left: 6px; white-space: nowrap; }
|
||
.acc .key-weight { display: none; flex: none; font-size: 11px; padding: 1px 6px; border-radius: 5px; color: var(--fg-2); background: var(--pill); border: 0; cursor: pointer; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||
.accts.weighted .acc .key-weight { display: inline-block; }
|
||
.acc .key-weight-in { width: 64px; flex: none; font-size: 12px; padding: 1px 6px; }
|
||
.acc .key-rest { flex: none; font-size: 11px; padding: 1px 6px; border-radius: 5px; color: var(--amber); background: var(--amber-soft); white-space: nowrap; }
|
||
.acc .proto { flex: none; display: inline-flex; align-items: center; gap: 3px; height: 20px; padding: 0 5px 0 7px; font: inherit; font-size: 11px; color: var(--muted); border: 0; border-radius: 5px; background: var(--pill); white-space: nowrap; cursor: default; transition: opacity .15s, background .12s, color .12s; }
|
||
.acc .proto svg { opacity: .7; transition: transform .15s var(--ease); }
|
||
.acc .proto.open svg { transform: rotate(180deg); }
|
||
.acc .proto:not(.set) { opacity: 0; background: none; box-shadow: inset 0 0 0 1px var(--line); }
|
||
.acc:hover .proto, .acc .proto.open, .acc.adding .proto { opacity: 1; }
|
||
.acc .proto:focus-visible { opacity: 1; }
|
||
.acc .proto.set { color: var(--fg-2); }
|
||
.acc .proto:hover, .acc .proto.open { color: var(--fg); background: var(--pill-hover); }
|
||
/* an account's or key's own models (#474): a badge like the key's protocol,
|
||
shown always once it keeps some only, and its picker under the row */
|
||
.acc .amodels { flex: none; display: inline-flex; align-items: center; height: 20px; padding: 0 7px; font: inherit; font-size: 11px; color: var(--muted); border: 0; border-radius: 5px; background: var(--pill); white-space: nowrap; cursor: default; transition: opacity .15s, background .12s, color .12s; }
|
||
.acc .amodels:not(.set) { opacity: 0; background: none; box-shadow: inset 0 0 0 1px var(--line); }
|
||
.acc:hover .amodels, .acc .amodels.open { opacity: 1; }
|
||
.acc .amodels:focus-visible { opacity: 1; }
|
||
.acc .amodels.set { color: var(--accent); background: var(--accent-soft); font-weight: 500; }
|
||
.acc .amodels:hover, .acc .amodels.open { color: var(--fg); background: var(--pill-hover); }
|
||
/* an account's usage cap: as the models pill, shown on hover till one is set */
|
||
.acc .acap { flex: none; display: inline-flex; align-items: center; height: 20px; padding: 0 7px; font: inherit; font-size: 11px; color: var(--muted); border: 0; border-radius: 5px; background: none; box-shadow: inset 0 0 0 1px var(--line); white-space: nowrap; cursor: default; opacity: 0; transition: opacity .15s, background .12s, color .12s; }
|
||
.acc:hover .acap, .acc .acap.open, .acc .acap:focus-visible, .acc .acap.set { opacity: 1; }
|
||
.acc .acap.set { color: var(--accent); background: var(--accent-soft); box-shadow: none; font-weight: 500; }
|
||
.acc .acap:hover, .acc .acap.open { color: var(--fg); background: var(--pill-hover); }
|
||
.acc .acap-in { width: 64px; }
|
||
.acc .acap-held { color: var(--fg); }
|
||
/* held for magpie's requests, not the agent signed in to it: a warning */
|
||
.acc .acap-held.acap-direct { color: var(--amber); }
|
||
.accts .acc.with-am { flex-wrap: wrap; row-gap: 3px; }
|
||
.acc .acct-models { flex-basis: 100%; display: grid; gap: 7px; padding: 6px 0 2px 25px; cursor: auto; }
|
||
.acc .acct-models .acm-foot { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||
.acc .acct-models .hint { font-size: 11px; color: var(--muted); line-height: 1.4; flex: 1 1 220px; }
|
||
.acc .acct-models .acm-foot .grow { flex: 0 0 0; }
|
||
.acc .n, .acc .rename { flex: 0 1 auto; }
|
||
.acc .plan { flex: none; }
|
||
#gatewayKeys .acc { min-width: 0; }
|
||
#gatewayKeys .acc .plan { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
/* a gateway key's own limit (#585): the badge, what it used under the
|
||
row, and its editor there */
|
||
#gatewayKeys .acc.with-limit { flex-wrap: wrap; row-gap: 3px; }
|
||
#gatewayKeys .amodels.limit.spent { color: var(--red); background: var(--red-soft); }
|
||
#gatewayKeys .key-limit { flex-basis: 100%; min-width: 0; padding: 0 0 2px 25px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
|
||
#gatewayKeys .key-limit.spent { color: var(--red); }
|
||
#gatewayKeys .key-limit-ed .key-limit { padding-left: 0; }
|
||
#gatewayKeys .klf { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); gap: 6px; }
|
||
#gatewayKeys .klf-field { display: grid; gap: 3px; min-width: 0; }
|
||
#gatewayKeys .klf-name { font-size: 11px; color: var(--muted); }
|
||
#gatewayKeys .klf input { width: 100%; min-width: 0; height: 28px; padding: 0 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); color: var(--fg); font: inherit; font-size: 12px; }
|
||
#gatewayKeys .klf-check { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-2); }
|
||
#gatewayKeys .klf-err { color: var(--red); }
|
||
#gatewayKeys .klf .klf-period { width: 100%; max-width: none; height: 28px; justify-content: space-between; color: var(--fg); }
|
||
@media (max-width: 520px) { #gatewayKeys .klf { grid-template-columns: 1fr; } }
|
||
/* the Settings row's picker: the key row's badge, always shown */
|
||
.row.pref .proto.pick { flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 3px; height: 24px; padding: 0 6px 0 9px; font: inherit; font-size: 12px; color: var(--fg-2); border: 0; border-radius: 7px; background: var(--pill); white-space: nowrap; cursor: default; transition: background .12s, color .12s; }
|
||
.row.pref .proto.pick svg { opacity: .7; transition: transform .15s var(--ease); }
|
||
.row.pref .proto.pick.open svg { transform: rotate(180deg); }
|
||
.row.pref .proto.pick:hover, .row.pref .proto.pick.open { color: var(--fg); background: var(--pill-hover); }
|
||
.row.pref .proto.pick.busy { opacity: .6; }
|
||
.pop.proto-menu { width: 262px; max-height: min(360px, 70vh); overflow-y: auto; overscroll-behavior: contain; padding: 4px; border: 1px solid var(--line); display: grid; gap: 1px; }
|
||
.proto-menu .pm-head { padding: 6px 8px 5px; font-size: 11px; color: var(--muted); }
|
||
.proto-menu .pm-item { display: flex; align-items: flex-start; gap: 7px; width: 100%; padding: 6px 8px 7px; border: 0; border-radius: 7px; background: none; color: var(--fg); font: inherit; text-align: left; cursor: default; outline: none; }
|
||
.proto-menu .pm-item:hover, .proto-menu .pm-item:focus { background: var(--pill); }
|
||
.proto-menu .pm-tick { width: 14px; height: 16px; flex: none; display: grid; place-items: center; color: var(--fg); }
|
||
.proto-menu .pm-words { display: grid; gap: 1px; min-width: 0; }
|
||
.proto-menu .pm-name { font-size: 12.5px; font-weight: 500; line-height: 16px; }
|
||
.proto-menu .pm-note { font-size: 11px; color: var(--muted); line-height: 15px; }
|
||
/* a subscription's allowance, under its name */
|
||
.accts .acc.with-aq { flex-wrap: wrap; row-gap: 3px; padding-top: 7px; padding-bottom: 8px; }
|
||
.acc .aq { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; padding-left: 25px; font-size: 10.5px; color: var(--muted); min-height: 14px; }
|
||
.acc .aq-w { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
|
||
.acc .aq-track { width: 54px; height: 4px; border-radius: 2px; background: var(--pill); overflow: hidden; }
|
||
.acc .aq-track i { display: block; height: 100%; border-radius: inherit; background: var(--fg-2); }
|
||
/* the account's usage cap: a tick across the meter where it stands */
|
||
.acc .aq-track.capped { position: relative; overflow: visible; }
|
||
.acc .aq-track.capped i { overflow: hidden; }
|
||
.acc .aq-cap { position: absolute; top: -2px; bottom: -2px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--accent); }
|
||
.acc .aq-w b { color: var(--fg-2); font-weight: 600; font-variant-numeric: tabular-nums; }
|
||
.acc .aq-w.full b, .acc .aq-w.full .aq-r { color: var(--fg); }
|
||
.acc .aq-w.full .aq-track i { background: var(--fg); }
|
||
.acc .aq-r { color: var(--muted); }
|
||
.acc .aq-k { color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.acc .aq-none { color: var(--faint); }
|
||
.acc .aq-asof { flex-basis: 100%; order: 1; color: var(--amber); overflow-wrap: anywhere; }
|
||
.acc .skeleton.sk-aq { width: 110px; height: 8px; border-radius: 4px; }
|
||
.acc .dot.tick.fixed { cursor: default; }
|
||
.acc .dot.tick.fixed:hover { box-shadow: none; }
|
||
.acc.off .aq { opacity: .7; }
|
||
|
||
/* a sign-in under way, waiting on the browser */
|
||
.signing { display: flex; align-items: flex-start; gap: 11px; padding: 11px 10px 11px 12px; font-size: 12.5px; background: var(--card-2); animation: fade-in .2s; }
|
||
.sheet .signing { margin-top: 8px; border: 1px solid var(--line); border-radius: 10px; }
|
||
.signing .tt { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; line-height: 1.35; }
|
||
.signing .n { font-weight: 500; }
|
||
.signing .s { color: var(--muted); font-size: 11.5px; overflow-wrap: anywhere; }
|
||
.signing > .text { margin: -3px 0; }
|
||
.signing .acts { display: flex; gap: 2px; margin: 2px 0 0 -4px; }
|
||
.signing .acts .link { color: var(--fg-2); }
|
||
.signing .devcode { display: flex; align-items: center; gap: 6px; margin: 6px 0 2px; }
|
||
.signing .devcode code { font: 600 17px/1.2 var(--code); letter-spacing: .12em; padding: 4px 9px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); user-select: all; }
|
||
/* the sign-in link, one line, selected whole with a click */
|
||
.signing .signlink { display: flex; align-items: center; gap: 4px; margin: 5px 0 1px; min-width: 0; }
|
||
.signing .signlink code { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 11px/1.3 var(--code); color: var(--fg-2); padding: 4px 7px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); user-select: all; -webkit-user-select: all; cursor: text; }
|
||
.signing .callback-form { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 6px; }
|
||
.signing .callback-form input { flex: 1; min-width: 120px; width: 100%; padding: 6px 8px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); color: var(--fg); font-size: 12px; }
|
||
.signing .why { color: var(--red); }
|
||
/* a plugin's ways to sign in: the question keeps the row, the choices
|
||
wrap beneath it at whatever length the plugin names them */
|
||
.signing.plugin-ask { flex-wrap: wrap; }
|
||
.signing.plugin-ask .choices { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 6px; }
|
||
.signing.plugin-ask .choices button { height: auto; min-height: 26px; max-width: 100%; padding: 4px 10px; white-space: normal; text-align: left; line-height: 1.3; overflow-wrap: anywhere; }
|
||
/* an import: what is pasted is sign-ins, so it is masked */
|
||
.signing.import textarea { margin-top: 6px; width: 100%; box-sizing: border-box; padding: 6px 8px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); color: var(--fg); font: 12px/1.45 var(--code); resize: vertical; outline: none; -webkit-text-security: disc; }
|
||
.signing.import textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
|
||
.signing.import .acts { align-items: center; gap: 8px; margin-top: 4px; }
|
||
.signing.import .fname { color: var(--muted); font-size: 11.5px; overflow-wrap: anywhere; }
|
||
.signing.import .why { color: var(--red); }
|
||
.signing.import .results { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
|
||
.signing.import .res { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; margin: 0; height: auto; padding: 0; border-radius: 0; background: none; color: var(--fg); font-size: 12px; font-variant-numeric: normal; }
|
||
.signing.import .res .u { font-weight: 450; overflow-wrap: anywhere; }
|
||
.signing.import .res .st { color: var(--muted); font-size: 11.5px; }
|
||
.signing.import .res.added .st, .signing.import .res.updated .st { color: var(--green); }
|
||
.signing.import .res.failed .st { color: var(--red); }
|
||
.signing.import .res .why { flex-basis: 100%; font-size: 11.5px; overflow-wrap: anywhere; }
|
||
.signing .spinner { width: 16px; height: 16px; flex: none; margin-top: 1px; border-radius: 50%; border: 1.75px solid var(--line); border-top-color: var(--fg); animation: spin .8s linear infinite; }
|
||
.signing .mark { width: 16px; height: 16px; flex: none; margin-top: 1px; border-radius: 50%; display: grid; place-items: center; background: var(--fg); color: var(--card); font-size: 11px; font-weight: 700; }
|
||
.fallback { display: grid; gap: 6px; }
|
||
.fallback .fbl { display: grid; gap: 2px; }
|
||
.fbrow { display: flex; align-items: center; gap: 8px; min-height: 28px; font-size: 12.5px; }
|
||
.fbrow .i { width: 14px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.fbrow .grow { flex: 1; }
|
||
.fallback .mchips:empty { display: none; }
|
||
.after-list { display: flex; align-items: center; gap: 8px; padding: 8px 4px 0; flex: none; }
|
||
/* the Providers page's add button stays at the view's foot over a long list */
|
||
#view-providers .after-list { position: sticky; bottom: -8px; z-index: 2; margin: 0 -12px -8px; padding: 14px 16px 12px; background: linear-gradient(to bottom, transparent, var(--bg) 12px); transition: opacity .18s ease, visibility 0s; }
|
||
/* stepping aside it fades, then goes; back, it is there at once, so the
|
||
focus can go to it as the sheet closes */
|
||
#view-providers .after-list.away { opacity: 0; visibility: hidden; transition: opacity .18s ease, visibility 0s .18s; }
|
||
#movable { margin: 0 0 10px; }
|
||
/* a built-in subscription a community plugin can run: an outlined amber
|
||
word, apart from the filled "sponsored" */
|
||
.badge.deprecated { background: transparent; color: var(--amber); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--amber) 45%, transparent); }
|
||
/* over the list: what is deprecated, why, and the way on */
|
||
.deprecation { display: flex; align-items: center; gap: 10px; padding: 10px 10px 10px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); animation: fade-in .2s; }
|
||
.deprecation .dep-dot { flex: none; align-self: flex-start; width: 7px; height: 7px; margin-top: 6px; border-radius: 50%; background: var(--amber); }
|
||
.deprecation .dep-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
||
.deprecation .dep-head { font-size: 12.5px; font-weight: 500; line-height: 1.45; color: var(--fg); overflow-wrap: anywhere; }
|
||
.deprecation .dep-why { margin: 0; font-size: 11.5px; line-height: 1.5; color: var(--muted); overflow-wrap: anywhere; }
|
||
.deprecation .dep-acts { flex: none; display: flex; align-items: center; gap: 4px; }
|
||
.deprecation .dep-acts .text:not(.action) { color: var(--muted); }
|
||
@media (max-width: 560px) {
|
||
.deprecation { flex-wrap: wrap; }
|
||
.deprecation .dep-acts { flex-basis: 100%; justify-content: flex-end; }
|
||
}
|
||
.move .dep-note { display: flex; align-items: flex-start; gap: 7px; padding: 7px 10px; border-radius: 8px; background: color-mix(in srgb, var(--amber-soft) 55%, transparent); font-size: 11.5px; line-height: 1.5; color: var(--fg-2); }
|
||
.move .dep-note .badge { flex: none; margin-top: 2px; }
|
||
/* and in the add sheet, under the subscriptions */
|
||
/* a deprecated subscription not signed in to: its plugin offered first */
|
||
#fileError { margin: 0 0 10px; }
|
||
#fileError .signing { border: 1px solid var(--line); border-radius: 10px; }
|
||
#fileError .signing .mark { background: var(--red); }
|
||
.excluded { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px 2px; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
|
||
.excluded .ic { width: 16px; height: 16px; margin-top: 1px; opacity: .7; }
|
||
.excluded b { font-weight: 500; color: var(--fg-2); }
|
||
|
||
/* the add sheet: presets as tiles, one key away */
|
||
.sheet { padding: 6px 0 8px; flex: none; }
|
||
.sheet .row-head { padding: 0 2px; gap: 6px; }
|
||
.sheet .find, #view-gateway .find { height: 24px; width: 160px; padding: 0 9px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); font-size: 12px; outline: none; transition: border-color .12s; }
|
||
.sheet .find:focus, #view-gateway .find:focus { border-color: var(--accent); }
|
||
.sheet .find::placeholder, #view-gateway .find::placeholder { color: var(--faint); }
|
||
.sheet .kind { display: flex; align-items: baseline; gap: 8px; padding: 22px 8px 6px; font-size: 12px; }
|
||
.sheet .kind b { font-size: 13px; font-weight: 600; color: var(--fg); }
|
||
.sheet .kind span { color: var(--faint); }
|
||
/* a removed account: its name, then Add it back and Sign out… side by
|
||
side, across the row (#694) */
|
||
.sheet .tile.removed { grid-column: 1 / -1; }
|
||
.sheet .tile.removed:hover { background: none; }
|
||
.sheet .tile.removed .acts { flex: none; display: flex; gap: 6px; }
|
||
.sheet .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1px 12px; }
|
||
.sheet .none { padding: 14px 2px; color: var(--muted); font-size: 12px; }
|
||
#gwModels .none { padding: 16px; color: var(--muted); font-size: 12px; text-align: center; }
|
||
#view-gateway .row-head .find { margin-right: 8px; }
|
||
/* a row of the add sheet: an icon and a name, no frame; a row already
|
||
added has a small green dot after its name rather than fading */
|
||
.tile {
|
||
display: flex; align-items: center; gap: 10px; height: 34px; padding: 0 8px;
|
||
border-radius: 8px; text-align: left; min-width: 0; transition: background .12s;
|
||
}
|
||
.tile:hover { background: var(--pill); }
|
||
.tile.on { background: var(--sel); }
|
||
.tile .ic { width: 18px; height: 18px; flex: none; }
|
||
.tile .nm { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; }
|
||
.tile .n { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.tile .nm .badge { flex: none; }
|
||
.tile .have { flex: none; width: 6px; height: 6px; border-radius: 3px; background: var(--green); }
|
||
.tile .cnt { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.sheet .custom-foot { display: flex; align-items: center; gap: 8px; margin-top: 14px; padding: 10px 2px 0; border-top: 1px solid var(--line-2); }
|
||
.sheet .custom-foot .custom { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 10px 0 6px; border-radius: 8px; color: var(--accent); font-size: 13px; }
|
||
.sheet .custom-foot .custom:hover, .sheet .custom-foot .custom.on { background: var(--accent-soft); }
|
||
.sheet .custom-foot .hint { font-size: 12px; color: var(--muted); }
|
||
/* the provider editor, in a dialog */
|
||
.editor { padding: 16px 18px 14px; display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 10px 14px; align-items: start; }
|
||
.editor .ehead { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; padding-bottom: 8px; margin-bottom: 2px; border-bottom: 1px solid var(--line-2); }
|
||
.editor .ehead .ic { width: 20px; height: 20px; }
|
||
.editor .icon-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
||
.editor .icon-pick .icon-now { width: 32px; height: 32px; border: 1px solid var(--line); border-radius: 8px; display: grid; place-items: center; }
|
||
.editor .icon-pick .icon-now .ic { width: 20px; height: 20px; }
|
||
.editor .icon-pick > input { flex-basis: 100%; }
|
||
.editor .icon-pick .icon-grid { flex-basis: 100%; display: grid; grid-template-columns: repeat(auto-fill, 34px); gap: 4px; padding: 6px; border: 1px solid var(--line); border-radius: 10px; max-height: 196px; overflow-y: auto; }
|
||
.editor .icon-pick .icon-grid button { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 7px; }
|
||
.editor .icon-pick .icon-grid button:hover { background: var(--card-2); }
|
||
.editor .icon-pick .icon-grid button.on { box-shadow: inset 0 0 0 1.5px var(--fg); }
|
||
.editor .icon-pick .icon-grid .ic { width: 18px; height: 18px; }
|
||
.editor .ehead b { font-weight: 600; }
|
||
.editor .ehead .note { font-size: 12px; color: var(--muted); }
|
||
.editor label { font-size: 12px; color: var(--fg-2); text-align: right; padding-top: 5px; }
|
||
.editor .hint { font-size: 11px; color: var(--fg-2); margin-top: 4px; }
|
||
/* a provider's own proxy (#237): the address beside the options, its room
|
||
kept while it is hidden so a pick never changes the dialog's height */
|
||
.editor .proxy-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||
.editor .proxy-row .proxy-mode { flex: none; }
|
||
.editor .proxy-row input.proxy-url { flex: 1 1 auto; width: auto; min-width: 0; }
|
||
.editor .proxy-row input.proxy-url.off { visibility: hidden; }
|
||
.editor input.concurrency[type] { width: 12em; max-width: 100%; }
|
||
.editor input[type="number"] { -moz-appearance: textfield; }
|
||
.editor input[type="number"]::-webkit-inner-spin-button, .editor input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
|
||
/* each of a subscription's accounts with a proxy of its own: its name
|
||
over the same row as the provider's, in a quiet card, no stripes */
|
||
.editor .acct-proxies { display: grid; gap: 8px; margin-top: 4px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
|
||
.editor .acct-proxy { display: grid; gap: 4px; min-width: 0; }
|
||
.editor .acct-proxy .who { font-size: 12px; font-weight: 500; color: var(--fg-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.editor .acct-proxies > .hint { margin-top: 0; }
|
||
/* what a balance token's URL wants instead, and a balance checked in the form */
|
||
.editor .bal-fix { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 6px; font-size: 12px; line-height: 1.45; color: var(--muted); }
|
||
.editor .bal-fix:empty { display: none; }
|
||
.editor .bal-fix.warn { color: var(--amber); }
|
||
.editor .bal-fix .text.action { height: 24px; font-size: 11.5px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.editor .pair.wrap { flex-wrap: wrap; }
|
||
.editor .bal-res { flex-basis: 100%; font-size: 12px; line-height: 1.45; color: var(--muted); overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.editor .bal-res:empty { display: none; }
|
||
.editor .bal-res.ok { color: var(--green); }
|
||
.editor .bal-res.bad { color: var(--red); }
|
||
.editor .bal-res.wait { color: var(--faint); }
|
||
.stepplan .state { flex: 1; min-width: 0; font-size: 12px; color: var(--muted); line-height: 1.4; }
|
||
.stepplan .steps { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: var(--muted); line-height: 1.5; }
|
||
.stepplan .steps .pair { margin-top: 2px; }
|
||
.stepplan .bookmarklet { display: inline-block; padding: 1px 8px; border: 1px solid var(--line); border-radius: 6px; color: var(--fg); background: var(--pill); text-decoration: none; cursor: grab; white-space: nowrap; }
|
||
.editor input[type="text"], .editor input[type="password"], .editor input[type="url"], .editor input[type="number"], .acc .kf input, .acc input.rename-in {
|
||
height: 27px; padding: 0 9px; border-radius: 7px;
|
||
border: 1px solid var(--line); background: var(--card);
|
||
font-size: 12.5px; outline: none; width: 100%; min-width: 0;
|
||
transition: border-color .12s, box-shadow .12s;
|
||
}
|
||
.editor input:focus, .editor .headers textarea.json:focus, .acc input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); outline: none; }
|
||
.editor input::placeholder, .acc input::placeholder { color: var(--faint); }
|
||
.editor .pair { display: flex; gap: 8px; align-items: center; }
|
||
.editor .pair input:first-child { flex: 1; }
|
||
.editor .side { display: flex; gap: 4px; align-items: center; flex: none; min-width: 52px; justify-content: flex-end; }
|
||
.editor .side .text { padding: 3px 6px; }
|
||
.editor .headers .pair .side .text { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border-radius: 6px; }
|
||
.editor .stack { display: flex; flex-direction: column; gap: 6px; }
|
||
.editor .move { align-items: flex-start; font-size: 12px; line-height: 1.5; padding-top: 4px; }
|
||
.editor .move .hint { margin-top: 0; }
|
||
.editor .move .move-why { font-size: 11.5px; line-height: 1.45; color: var(--red); overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.editor .move .move-why[hidden] { display: none; }
|
||
.editor .move > button { max-width: 100%; white-space: normal; text-align: left; height: auto; min-height: 27px; }
|
||
.editor .headers { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
|
||
.editor .headers .pair { width: 100%; }
|
||
.editor .headers .hadds { display: flex; flex-wrap: wrap; gap: 2px 12px; }
|
||
.editor .headers .pair input { flex: 1; min-width: 0; }
|
||
.editor .headers .pair input:first-child { flex: 4; }
|
||
.editor .headers .pair input:nth-child(2) { flex: 6; }
|
||
.editor .headers .pair .side { flex: none; }
|
||
.editor .headers .pair .side .text.on { color: var(--accent); }
|
||
.editor .headers .pair.col { flex-direction: column; align-items: stretch; }
|
||
.editor .headers .pair.col .hhead { display: flex; gap: 8px; align-items: center; width: 100%; }
|
||
.editor .headers .pair.col .hhead input { flex: 1; min-width: 0; }
|
||
.editor .headers .pair.col .side { flex: none; }
|
||
.editor .headers textarea.json { width: 100%; box-sizing: border-box; padding: 7px 9px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); color: var(--fg); outline: none; font-family: var(--code); font-size: 12px; line-height: 1.5; resize: vertical; tab-size: 2; white-space: pre; overflow: auto; transition: border-color .12s, box-shadow .12s; }
|
||
.editor .headers textarea.json.bad { border-color: var(--danger, #d66); }
|
||
.segs { position: relative; display: inline-flex; padding: 2px; border-radius: 7px; background: var(--pill); align-self: flex-start; }
|
||
.opt { position: relative; z-index: 1; white-space: nowrap; height: 22px; padding: 0 10px; border-radius: 5px; font-size: 12px; color: var(--muted); transition: color .18s var(--ease), transform .14s var(--ease); }
|
||
.opt.on { color: var(--fg); }
|
||
/* how often magpie checks for updates, while it doesn't by itself */
|
||
.update-every-row.off .segs { opacity: .55; }
|
||
.opt:hover:not(.on) { color: var(--fg-2); }
|
||
.thumb {
|
||
position: absolute; top: 2px; bottom: 2px; left: 0; width: 0; border-radius: 6px;
|
||
background: var(--card); box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 0 0 .5px rgba(0, 0, 0, .06);
|
||
transition: transform .28s var(--ease), width .28s var(--ease), opacity .15s;
|
||
pointer-events: none;
|
||
}
|
||
.segs .thumb { border-radius: 5px; }
|
||
/* a strip too wide for the window scrolls in itself: the regions, and
|
||
Connect's five APIs on a narrow one */
|
||
.segs.regions, .connect .segs { max-width: 100%; overflow-x: auto; }
|
||
/* no scrollbar-width here: Chromium (WebView2) then drops every
|
||
::-webkit-scrollbar rule and draws Windows' classic bar, arrows and all,
|
||
under the strip; the app's thin thumb instead, slimmer still */
|
||
:where(body:not(.mac)) :is(.segs.regions, .connect .segs)::-webkit-scrollbar { height: 6px; }
|
||
:where(body:not(.mac)) :is(.segs.regions, .connect .segs)::-webkit-scrollbar-thumb { border-width: 1px; }
|
||
.segs.regions .opt, .connect .segs .opt { flex: none; }
|
||
/* an installed list's order (#481): small, beside the list's heading */
|
||
.segs.sortby { align-self: center; flex: none; }
|
||
.segs.sortby .opt { height: 20px; padding: 0 8px; font-size: 11px; }
|
||
/* a provider's Routing and Stays, with "unsaved" beside a pick not saved yet */
|
||
.route-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
|
||
.route-pick > .hint { margin: 0; }
|
||
.thumb.still { transition: none; }
|
||
.link { font-size: 12px; color: var(--accent); padding: 3px 4px; white-space: nowrap; }
|
||
.link:hover { text-decoration: underline; text-underline-offset: 2px; }
|
||
.editor .more { grid-column: 1 / -1; }
|
||
.editor .more summary { font-size: 12px; color: var(--muted); list-style: none; display: inline-flex; align-items: center; gap: 4px; padding: 2px 0; margin-left: 86px; }
|
||
.editor .more summary::-webkit-details-marker { display: none; }
|
||
.editor .more summary::before { content: "▸"; font-size: 10px; color: var(--faint); }
|
||
.editor .more[open] summary::before { content: "▾"; }
|
||
.editor .more summary:hover { color: var(--fg); }
|
||
.editor .more .inner { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 10px 14px; align-items: start; padding-top: 8px; }
|
||
.editor .warnbox { grid-column: 1 / -1; font-size: 12px; line-height: 1.5; color: var(--fg); background: color-mix(in srgb, var(--amber) 12%, transparent); border: 1px solid color-mix(in srgb, var(--amber) 35%, transparent); border-radius: 8px; padding: 8px 10px; }
|
||
.editor .warnbox.soft { background: none; color: var(--amber); border: 0; padding: 0 0 0 86px; }
|
||
.editor.import .mchips .mchip { cursor: default; }
|
||
.editor .bar { grid-column: 1 / -1; display: flex; align-items: center; gap: 4px; padding-top: 10px; border-top: 1px solid var(--line-2); margin-top: 2px; }
|
||
.editor .bar .danger { margin-left: -7px; }
|
||
.editor .editor-error { grid-column: 1 / -1; font-size: 12px; line-height: 1.45; color: var(--red); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.editor .editor-error.warn { color: var(--amber); }
|
||
.busy { opacity: .55; pointer-events: none; }
|
||
|
||
/* agent chips: who is on this provider, click one to pick it a model */
|
||
.achips { display: flex; flex-wrap: wrap; gap: 5px; }
|
||
.achip {
|
||
display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px 0 6px; border-radius: 7px;
|
||
background: var(--card); border: 1px solid var(--line); font-size: 12px; color: var(--muted);
|
||
transition: background .12s, color .12s, border-color .12s;
|
||
}
|
||
.achip .ic { width: 15px; height: 15px; filter: grayscale(1); opacity: .55; transition: filter .12s, opacity .12s; }
|
||
.achip:hover { color: var(--fg); border-color: var(--muted); }
|
||
.achip:hover .ic, .achip.on .ic { filter: none; opacity: 1; }
|
||
.achip.on { color: var(--fg); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
|
||
.achip.open { border-color: var(--accent); }
|
||
.achip .m { font: 11px var(--code); color: var(--accent); }
|
||
|
||
/* endpoints, each with its own test result */
|
||
.eps { display: flex; flex-direction: column; gap: 3px; }
|
||
.ep { display: flex; align-items: center; gap: 8px; height: 24px; min-width: 0; }
|
||
.ep .pl { flex: none; width: 64px; font-size: 11.5px; color: var(--muted); }
|
||
.ep code { color: var(--fg-2); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; user-select: text; -webkit-user-select: text; cursor: text; }
|
||
.res { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 7px; border-radius: 5px; font-size: 11px; font-variant-numeric: tabular-nums; background: var(--pill); color: var(--muted); }
|
||
.res:empty { display: none; }
|
||
.res.wait { background: none; color: var(--faint); }
|
||
.res.ok { background: var(--green-soft); color: var(--green); }
|
||
.res.bad { background: var(--red-soft); color: var(--red); max-width: 60%; }
|
||
.res.bad span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.eps .text { align-self: flex-start; margin: 5px 0 0 72px; }
|
||
/* Detect: which APIs answer at the base URL typed */
|
||
.detect { display: flex; flex-direction: column; gap: 6px; }
|
||
.detect-row { display: flex; align-items: center; gap: 8px; }
|
||
.detect-row .text { flex: none; }
|
||
.detect-row .detect-model { flex: 1; min-width: 0; height: 27px; font-size: 12px; }
|
||
.detect-out[hidden] { display: none; }
|
||
.detect-out .ep .pl { width: 72px; }
|
||
.detect-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; padding-top: 2px; }
|
||
.eps .detect-acts .text { margin: 0; }
|
||
.detect-acts .pick-api.on { background: var(--pill); }
|
||
.detect-acts .hint { font-size: 11.5px; color: var(--faint); }
|
||
.detect-row .detect-each { flex: none; }
|
||
.add-models .detect-row input { flex: 1; min-width: 0; }
|
||
.add-models-list { max-height: 260px; overflow-y: auto; }
|
||
.add-models-list .hint.err { color: var(--red); }
|
||
.detect-grid { display: grid; gap: 3px 10px; align-items: center; font-size: 11.5px; padding: 4px 0 2px; }
|
||
.detect-grid .dg-head { color: var(--faint); font-size: 11px; }
|
||
.detect-grid .dg-model { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; }
|
||
.detect-grid .dg-cell { display: flex; align-items: center; gap: 4px; min-width: 0; color: var(--faint); }
|
||
.detect-grid .dg-cell > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.detect-grid .dg-cell svg { flex: none; }
|
||
.detect-grid .dg-cell.ok { color: var(--green); }
|
||
.detect-grid .dg-cell.bad svg { color: var(--red); }
|
||
|
||
/* model chips: click to expose, click again to hide */
|
||
.models { display: flex; flex-direction: column; gap: 6px; }
|
||
.mbulk { display: flex; align-items: center; gap: 6px; }
|
||
.mbulk > input { max-width: 260px; flex: 1; }
|
||
/* a long list scrolls on its own, not the editor with it past its ends */
|
||
.mchips { display: flex; flex-wrap: wrap; gap: 4px; max-height: min(132px, 28vh); overflow-y: auto; overscroll-behavior: contain; padding: 1px; }
|
||
.mchips::-webkit-scrollbar { width: 0; }
|
||
/* let out to its full height (#833): the editor's body scrolls instead */
|
||
.mchips.open { max-height: none; overflow-y: visible; }
|
||
/* its Expand the list / Collapse the list, the Agents page's Show more
|
||
in small: under the chips, the width of the box */
|
||
.mchips-fold { border-top: 0; padding: 4px 9px; font-size: 11.5px; border-radius: 8px; }
|
||
.mchips-fold[hidden] { display: none; }
|
||
/* In a short window the editor's body shows little more than the list, so
|
||
the pointer is nearly always over it; held at its ends, the wheel could
|
||
never take the body on to what lies below (悠悠哥 on Discord: a small
|
||
window's WorkBuddy editor stopped part way down its models). There a
|
||
list's ends pass the wheel on to the body, and the names' list is held
|
||
to a part of the window as the chips are. */
|
||
@media (max-height: 640px) {
|
||
.mchips { overscroll-behavior: auto; }
|
||
.mnames { max-height: min(240px, 40vh); }
|
||
}
|
||
.mchip {
|
||
display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 999px;
|
||
font-size: 11.5px; color: var(--muted); background: var(--card); border: 1px solid var(--line);
|
||
transition: background .12s, color .12s, border-color .12s;
|
||
}
|
||
.mchip:hover { color: var(--fg); border-color: var(--muted); }
|
||
.mchip.on { color: var(--accent); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 45%, transparent); font-weight: 500; }
|
||
.mchip.on::before { content: "✓"; font-size: 10px; }
|
||
.mchip.own.on::before { content: "+"; }
|
||
/* served with none picked: the vendor's list stands in for the picks. Drawn
|
||
apart from a pick (no tick, no accent): a click picks it alone (#681) */
|
||
.mchip.auto { border-style: dashed; border-color: var(--muted); }
|
||
/* an image model in the editor: listed, not picked */
|
||
.mchip.ro, .mchip.ro:hover { cursor: default; color: var(--muted); border-color: var(--line); }
|
||
.mchip.ro:active { transform: none; }
|
||
/* how a model answered Test models: a dot after its name */
|
||
.mchip .tdot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--faint); }
|
||
.mchip .tdot.ok { background: var(--green); }
|
||
.mchip .tdot.bad { background: var(--red); }
|
||
.mchip .tdot.wait { animation: tdot 1s ease-in-out infinite alternate; }
|
||
@keyframes tdot { to { opacity: .25; } }
|
||
.mchips .hint, .mfoot .hint { font-size: 11px; color: var(--faint); align-self: center; line-height: 27px; }
|
||
/* the foot of a long list: draws the models left out of it (#685) */
|
||
.mchips .mchips-rest { flex: none; height: 24px; padding: 0 9px; border-radius: 999px; font-size: 11.5px; box-shadow: none; }
|
||
.mfoot { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 27px; }
|
||
.mfoot .hint { white-space: nowrap; }
|
||
.mfoot > input { height: 27px; }
|
||
.mfoot .text.action { flex: none; }
|
||
.mfoot input { max-width: 200px; height: 27px !important; }
|
||
.mfoot .text { padding: 2px 7px; }
|
||
.mfoot .text.on { color: var(--fg); background: var(--card-2); }
|
||
.mfoot .text.action:disabled, .mfoot .text.action:disabled:hover { color: var(--faint); background: var(--card); border-color: var(--line); cursor: default; }
|
||
|
||
/* the models' own names and reasoning levels, one row each */
|
||
.mnames { display: grid; gap: 4px; max-height: 240px; overflow-y: auto; padding: 1px; }
|
||
.mnames[hidden] { display: none; }
|
||
.mnames > .hint { font-size: 11px; color: var(--faint); }
|
||
.mname { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); }
|
||
.mname .mwho { display: flex; align-items: center; gap: 8px; flex: 1 1 220px; min-width: 0; }
|
||
.mname .mwho input { flex: 1; min-width: 0; max-width: 220px; height: 25px; }
|
||
.mname .mwho code { font-size: 11px; color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; user-select: text; -webkit-user-select: text; cursor: text; }
|
||
.mname .mapi { flex: none; height: 24px; font-size: 11px; }
|
||
.mname .msame { display: flex; align-items: center; gap: 6px; flex: 0 1 230px; min-width: 0; font-size: 11.5px; color: var(--muted); }
|
||
.mname .msame span { flex: none; }
|
||
.mname .msame input { flex: 1; min-width: 0; height: 25px; font-size: 11.5px; }
|
||
.mname .mlevels { display: flex; flex-wrap: wrap; gap: 2px 10px; font-size: 11.5px; }
|
||
.editor .mname label.tick { gap: 4px; }
|
||
.mname .text { flex: none; padding: 2px 7px; font-size: 11.5px; }
|
||
|
||
/* ---------- settings ---------- */
|
||
#view-settings .row-head { margin: 4px 0 6px; padding: 0 2px; }
|
||
#view-settings .row-head + .list { margin-bottom: 8px; }
|
||
/* the warm-ups and check-in: a tab per service where a heading would be,
|
||
in the headings' small capitals, the one picked darker on a soft pill,
|
||
the picked one's card alone under them */
|
||
.warm-tabs { display: flex; align-items: center; gap: 2px; margin-left: -7px; }
|
||
.warm-tabs button { height: 22px; padding: 0 7px; border-radius: 6px; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); transition: color .12s, background-color .12s; }
|
||
.warm-tabs button:hover:not(.on) { color: var(--fg-2); }
|
||
.warm-tabs button.on { color: var(--fg); background: var(--pill); }
|
||
.warm-tabs button[hidden] { display: none; }
|
||
.warm-panes { margin-bottom: 8px; }
|
||
/* the page's parts (#471): a tab each at the top in the same look, a line
|
||
more when they don't fit across (a narrow window, a larger text size),
|
||
the part picked alone under them */
|
||
#view-settings .set-head { height: auto; min-height: 26px; flex: none; }
|
||
.set-tabs { flex-wrap: wrap; row-gap: 2px; min-width: 0; }
|
||
.set-tabs button { flex: none; white-space: nowrap; }
|
||
.set-page { flex: none; }
|
||
.set-page[hidden] { display: none; }
|
||
.set-page > .list:not(:last-child) { margin-bottom: 8px; }
|
||
.row.pref { min-height: 50px; padding: 8px 12px 8px 14px; gap: 14px; }
|
||
.row.pref .who { flex: 1 1 auto; }
|
||
.row.pref .sub { margin-top: 2px; color: var(--fg-2); }
|
||
/* Keep export consent readable, and give collector URLs their own line. */
|
||
#otelList .otel-section { padding: 10px 14px 6px; font-size: 11px; font-weight: 600; color: var(--muted); background: var(--pill); }
|
||
#otelList .otel-section:not(:first-child) { border-top: 1px solid var(--line-2); }
|
||
#otelList .row .sub { white-space: normal; overflow-wrap: anywhere; line-height: 1.5; }
|
||
#otelList .row { align-items: flex-start; padding-top: 12px; padding-bottom: 12px; }
|
||
#otelList .otel-stacked { flex-wrap: wrap; gap: 8px; }
|
||
#otelList .otel-stacked > .who { flex-basis: 100%; }
|
||
#otelList .otel-stacked > .val { width: 100%; max-width: none; margin-left: 0; }
|
||
#otelList input.words { width: 100%; }
|
||
#otelList .otel-stacked .segs { margin-left: 0; max-width: 100%; flex-wrap: wrap; }
|
||
#otelList .otel-env { padding: 12px 14px; border-top: 1px solid var(--line-2); font-size: 11.5px; color: var(--muted); }
|
||
|
||
.session-terminal-select { max-width: min(230px, 45%); height: 29px; color: var(--fg); }
|
||
.session-terminal-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||
.row.pref .segs { flex: none; margin-left: auto; }
|
||
.proxy-segs { display: flex; align-items: center; gap: 8px; margin-left: auto; min-width: 0; }
|
||
.proxy-segs input.proxy, input.words { width: 180px; min-width: 0; height: 27px; padding: 0 9px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); font-size: 12.5px; outline: none; transition: border-color .12s, box-shadow .12s; }
|
||
.proxy-segs input.proxy:focus, input.words:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
|
||
.proxy-segs input.proxy::placeholder, input.words::placeholder { color: var(--faint); }
|
||
input.words { width: 240px; max-width: 100%; }
|
||
/* the masking rules' add row: its words in full, then on a line of their
|
||
own a name, prefix or regex, the match taking the room left, Add */
|
||
.row.pref.rule-row { flex-wrap: wrap; row-gap: 8px; }
|
||
.row.pref.rule-row .who { flex: 1 1 100%; }
|
||
.row.pref.rule-row .sub { white-space: normal; }
|
||
/* an update that failed says why in full (the version row) */
|
||
.row .sub.wraps { white-space: normal; overflow-wrap: anywhere; }
|
||
.prefs .val.rule-add { flex: 1 1 100%; max-width: none; margin-left: 0; gap: 6px; }
|
||
input.words.rule-kind { flex: none; width: 110px; }
|
||
input.words.gateway-port { flex: none; width: 110px; font-variant-numeric: tabular-nums; }input.words.rule-match { flex: 1 1 auto; width: auto; min-width: 0; }
|
||
input.words.search-key, input.words.search-url { flex: 1 1 120px; width: auto; min-width: 0; }
|
||
/* a search API's key, shown: selectable, and broken anywhere rather than widening the row */
|
||
.search-api .sub.revealed { font-family: var(--code); overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.prefs .val.rule-add .segs { margin-left: 0; }
|
||
.row.pref .sub.err { color: var(--red); white-space: normal; }
|
||
.warm-at { display: flex; align-items: center; gap: 8px; margin-left: auto; flex: none; }
|
||
.warm-at input.at { width: auto; height: 27px; padding: 0 8px; border-radius: 7px; border: 1px solid var(--line); background: var(--card); color: var(--fg); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; outline: none; transition: border-color .12s, box-shadow .12s; }
|
||
.warm-at input.at:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
|
||
.warm-at input.at::-webkit-calendar-picker-indicator { opacity: .55; }
|
||
/* a usage alert's share or amount: a short number field, its unit beside it */
|
||
.warm-at input.at.num { width: 64px; text-align: right; }
|
||
.warm-at .unit { color: var(--muted); font-size: 12.5px; margin-left: -4px; }
|
||
.row.pref .sub .warn { color: var(--amber); }
|
||
.row.pref .sub.wraps { white-space: normal; }
|
||
/* the field's clock and picker in the page's own palette */
|
||
:root[data-theme="dark"] .warm-at input.at { color-scheme: dark; }
|
||
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .warm-at input.at { color-scheme: dark; } }
|
||
@media (max-width: 520px) { .proxy-segs { flex-wrap: wrap; justify-content: flex-end; } }
|
||
/* Settings → Plugins: what a plugin signs in to, or why it didn't load, said whole */
|
||
.row.pref.plugin-row .sub, .row.pref.plugin-add .sub { white-space: normal; }
|
||
.row.pref.plugin-row.off .name { color: var(--muted); }
|
||
.row.pref.plugin-add .val { flex-wrap: wrap; justify-content: flex-end; }
|
||
.prefs .val { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; min-width: 0; max-width: 60%; flex: none; }
|
||
.prefs .val code { font-size: 12px; color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; user-select: text; -webkit-user-select: text; padding: 0 6px; }
|
||
.prefs .val .text { padding: 3px 6px; }
|
||
.row.pref.lan-address-row { position: relative; height: 50px; transition: height .28s var(--ease); }
|
||
.row.pref.lan-address-row .who { position: absolute; top: 16px; left: 14px; }
|
||
.prefs .lan-address-row .val { max-width: 64%; }
|
||
.lan-address-controls { position: absolute; inset: 0; pointer-events: none; }
|
||
.lan-address-controls > * { position: absolute; pointer-events: auto; }
|
||
.row.pref .proto.pick.lan-interface { top: 13px; right: 40px; width: 240px; max-width: calc(100% - 40px); margin-left: 0; font: 12px var(--code); transition: top .28s var(--ease), background .12s, color .12s; }
|
||
.lan-interface .lan-url { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.lan-address-controls .lan-address-text { top: 16px; right: 40px; width: 240px; max-width: calc(100% - 40px); font: 12px var(--code); transition: top .28s var(--ease); }
|
||
.lan-address-controls .segs { top: 12px; right: 286px; margin-left: 0; transition: right .28s var(--ease); }
|
||
.lan-copy { top: 14px; right: 12px; display: inline-flex; transition: top .28s var(--ease); }
|
||
.row.pref.lan-container .sub { white-space: normal; }
|
||
.pop.proto-menu.lan-address-menu { width: min(320px, calc(100vw - 16px)); max-height: min(360px, 70vh); overflow-y: auto; }
|
||
.lan-address-menu .pm-name { font: 12px var(--code); }
|
||
@media (max-width: 600px) {
|
||
.row.pref.lan-address-row { height: 76px; }
|
||
.lan-address-controls .segs { right: 12px; }
|
||
.row.pref .proto.pick.lan-interface { top: 44px; }
|
||
.lan-address-controls .lan-address-text { top: 47px; }
|
||
.lan-copy { top: 45px; }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.row.pref.lan-address-row, .row.pref .proto.pick.lan-interface, .lan-address-controls .lan-address-text, .lan-address-controls .segs, .lan-copy { transition: none; }
|
||
}
|
||
/* the community row's way in: Discord's own colour, quiet until hovered */
|
||
.prefs .val .discord {
|
||
display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 11px 0 9px; border-radius: 999px;
|
||
font-size: 12px; font-weight: 560; white-space: nowrap; color: #5865f2;
|
||
background: color-mix(in srgb, #5865f2 11%, transparent);
|
||
box-shadow: inset 0 0 0 .5px color-mix(in srgb, #5865f2 35%, transparent);
|
||
transition: background .15s, color .15s, transform .12s var(--ease);
|
||
}
|
||
.prefs .val .discord:hover { background: #5865f2; color: #fff; }
|
||
.prefs .val .discord:active { transform: scale(.96); }
|
||
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .prefs .val .discord:not(:hover) { color: #8b95ff; } }
|
||
:root[data-theme="dark"] .prefs .val .discord:not(:hover) { color: #8b95ff; }
|
||
.prefs .val .github {
|
||
display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 11px 0 9px; border-radius: 999px; margin-left: 6px;
|
||
font-size: 12px; font-weight: 560; white-space: nowrap; color: var(--fg);
|
||
background: color-mix(in srgb, var(--fg) 7%, transparent);
|
||
box-shadow: inset 0 0 0 .5px color-mix(in srgb, var(--fg) 22%, transparent);
|
||
transition: background .15s, color .15s, transform .12s var(--ease);
|
||
}
|
||
.prefs .val .github:hover { background: var(--fg); color: var(--bg); }
|
||
.prefs .val .github:active { transform: scale(.96); }
|
||
|
||
|
||
/* ---------- motion ----------
|
||
One easing everywhere (iOS-ish: quick start, soft landing), short
|
||
durations, small distances. Pressing gives a little, pages settle in,
|
||
dialogs lift. */
|
||
:root { --ease: cubic-bezier(.2, .8, .2, 1); }
|
||
.text, .icon, .tile, .achip, .mchip, .use, .link {
|
||
transition-property: background, background-color, color, border-color, box-shadow, filter, opacity, transform;
|
||
transition-duration: .16s; transition-timing-function: var(--ease);
|
||
}
|
||
.text:active, .tile:active, .achip:active, .mchip:active, .use:active, .opt:active, .seg button:active { transform: scale(.96); }
|
||
.icon:active { transform: scale(.9); }
|
||
.row.provider { transition: background .16s var(--ease); }
|
||
.row.provider:active { background: var(--card-2); }
|
||
.chips .chip { transition: background .16s var(--ease), color .16s var(--ease), transform .14s var(--ease); }
|
||
.chips .chip:active { transform: scale(.96); }
|
||
.status { transition: opacity .2s var(--ease); }
|
||
.status.err, .status.warn { user-select: text; -webkit-user-select: text; cursor: text; }
|
||
|
||
/* the theme crossfades instead of snapping */
|
||
html.theming, html.theming *, html.theming *::before, html.theming *::after {
|
||
transition: background-color .35s var(--ease), background .35s var(--ease), color .35s var(--ease), border-color .35s var(--ease), box-shadow .35s var(--ease) !important;
|
||
}
|
||
|
||
/* ---------- modal ---------- */
|
||
.modal {
|
||
position: fixed; inset: 0; z-index: 20;
|
||
display: flex; align-items: center; justify-content: center; padding: 28px 24px;
|
||
background: rgba(0, 0, 0, .28);
|
||
-webkit-backdrop-filter: blur(8px) saturate(1.1); backdrop-filter: blur(8px) saturate(1.1);
|
||
}
|
||
/* opening and closing are animated from app.js (openModal, closeModal) */
|
||
.modal.out { pointer-events: none; }
|
||
.modal .dialog {
|
||
width: min(600px, 100%); min-width: 0; max-height: 100%; overflow-y: auto;
|
||
border-radius: 14px; background: var(--card);
|
||
box-shadow: 0 0 0 1px var(--line), 0 24px 60px rgba(0, 0, 0, .32), 0 2px 8px rgba(0, 0, 0, .12);
|
||
}
|
||
.modal .dialog.swap { animation: content-in .22s var(--ease); }
|
||
.modal .dialog::-webkit-scrollbar { width: 0; }
|
||
/* In a dialog the editor's head and buttons stay put and only the fields
|
||
between them scroll; both bars are the same height, their contents
|
||
centred in it. */
|
||
.modal .dialog { display: flex; flex-direction: column; }
|
||
.modal .editor.framed { display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 0; min-height: 0; overflow: hidden; }
|
||
.modal .editor.framed > .ebody {
|
||
flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
|
||
display: grid; grid-template-columns: inherit; gap: 10px 14px; align-items: start; padding: 14px 18px;
|
||
}
|
||
.modal .editor.framed > .ebody::-webkit-scrollbar { width: 0; }
|
||
.modal .editor.framed > .ehead, .modal .editor.framed > .bar { flex: none; min-height: 48px; margin: 0; padding: 0 18px; }
|
||
.modal .editor.framed > .ehead { border-bottom: 1px solid var(--line-2); }
|
||
.modal .editor.framed > .bar { border-top: 1px solid var(--line-2); }
|
||
.modal .editor.framed > .editor-error { flex: none; padding: 8px 18px; border-top: 1px solid var(--line-2); }
|
||
/* what's new after an update: each release's notes, one under another,
|
||
divided by a hairline, the text selectable */
|
||
.modal .editor.whatsnew > .ebody { gap: 0; }
|
||
.whatsnew .wn-rel, .whatsnew .wn-list { grid-column: 1 / -1; min-width: 0; }
|
||
.whatsnew .wn-rel + .wn-rel { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-2); }
|
||
.whatsnew .wn-ver { display: flex; align-items: center; gap: 8px; font-size: 13px; }
|
||
.whatsnew .wn-ver b { font-weight: 600; }
|
||
.whatsnew .wn-since { margin-left: 10px; font-size: 12px; color: var(--muted); }
|
||
.whatsnew .wn-notes { font-size: 12.5px; line-height: 1.55; color: var(--fg-2); overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
|
||
.whatsnew .wn-h { margin: 10px 0 2px; font-size: 12px; font-weight: 600; color: var(--fg); }
|
||
.whatsnew .wn-h1, .whatsnew .wn-h2 { font-size: 12.5px; }
|
||
.whatsnew .wn-notes ul { margin: 2px 0; padding-left: 18px; }
|
||
.whatsnew .wn-notes li + li { margin-top: 2px; }
|
||
.whatsnew .wn-notes p { margin: 4px 0; }
|
||
.whatsnew .wn-notes code { font: 11.5px/1.4 var(--code); padding: 0 4px; border-radius: 4px; background: var(--pill); }
|
||
.whatsnew .wn-link { color: var(--accent); text-decoration: none; }
|
||
.whatsnew .wn-link:hover { text-decoration: underline; }
|
||
.whatsnew .wn-msg { margin: 4px 0 6px; font-size: 12.5px; color: var(--fg-2); }
|
||
.whatsnew .wn-failed .wn-msg { color: var(--red); }
|
||
.whatsnew .wn-acts { display: flex; align-items: center; gap: 12px; font-size: 12.5px; }
|
||
/* Keep native window chrome outside the scrim and dialog. In particular, the
|
||
macOS traffic lights must never sit on top of modal content. */
|
||
body.window.mac .modal { top: calc(50px / var(--zoom, 1)); padding: 16px 24px 24px; }
|
||
body.window .modal { padding: 16px 24px 24px; }
|
||
body.panel .modal { padding: 16px 12px; }
|
||
@keyframes fade-in { from { opacity: 0; } }
|
||
@keyframes content-in { from { opacity: .5; transform: translateY(2px); } }
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
|
||
.skeleton { animation: none !important; }
|
||
}
|
||
|
||
/* A browser on a phone: keep the desktop and tray's layout independent.
|
||
Tabs scroll on their own row, content keeps the available height, and
|
||
form controls are large enough to use without zooming the page. */
|
||
@media (max-width: 760px), (pointer: coarse) and (max-width: 1024px) {
|
||
body.web { height: 100%; font-size: 14px; }
|
||
body.web .icon { width: 44px; height: 44px; }
|
||
body.web .update { min-height: 36px; }
|
||
body.web .view {
|
||
--view-left: max(12px, env(safe-area-inset-left));
|
||
--view-right: max(12px, env(safe-area-inset-right));
|
||
padding: 2px var(--view-right) 12px var(--view-left);
|
||
}
|
||
body.web .foot { padding-bottom: max(8px, env(safe-area-inset-bottom)); min-width: 0; }
|
||
body.web .foot .status { min-width: 0; overflow-wrap: anywhere; }
|
||
body.web .row-head { height: auto; min-height: 40px; flex-wrap: wrap; gap: 4px; }
|
||
body.web .text, body.web .field, body.web .segs .opt, body.web .copy { min-height: 44px; }
|
||
body.web .text { padding: 8px 10px; }
|
||
body.web .copy { min-width: 44px; }
|
||
body.web .fields { width: 100%; grid-template-columns: minmax(0, 1fr) minmax(0, 124px); }
|
||
body.web .row.agent { flex-wrap: wrap; }
|
||
body.web .row.agent > .fields { flex-basis: 100%; }
|
||
/* Extra controls must not keep the desktop's fixed grid width. The model
|
||
gets the full row; effort and squares wrap below it without clipping. */
|
||
body.web #agents .row.agent > .fields,
|
||
body.web #agents.extras .row.agent > .fields {
|
||
display: flex; flex-wrap: wrap; width: 100%; min-width: 0; margin-left: 0;
|
||
}
|
||
body.web #agents .fields > .field.main,
|
||
body.web #agents .fields > .field.solo { flex: 1 0 100%; }
|
||
body.web #agents .fields > .field.side { flex: 1 0 124px; }
|
||
body.web #agents .extras-cell { flex-wrap: wrap; max-width: 100%; }
|
||
body.web #agents .field.extra { width: 44px; min-width: 44px; }
|
||
body.web .row.pref { flex-wrap: wrap; gap: 8px; padding: 12px; }
|
||
body.web .row.pref > .who { flex-basis: 100%; }
|
||
body.web .row.pref .sub { white-space: normal; }
|
||
body.web .row.pref .segs { margin-left: 0; max-width: 100%; flex-wrap: wrap; }
|
||
body.web .proxy-segs { margin-left: 0; flex-wrap: wrap; justify-content: flex-start; }
|
||
body.web .usage-head { height: auto; min-height: 44px; flex-wrap: wrap; gap: 8px; }
|
||
body.web .usage-head > .segs { max-width: 100%; flex-wrap: wrap; }
|
||
body.web .usage-head > .grow, body.web .sess-tools > .grow { display: none; }
|
||
body.web .sess-filter { order: 1; flex: 1 1 100%; width: 100%; }
|
||
body.web .sess-pick { min-height: 44px; max-width: 100%; font-size: 14px; }
|
||
body.web .stats, body.web .stats.six { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||
body.web .kpi small { white-space: normal; overflow: visible; overflow-wrap: anywhere; }
|
||
body.web .row.stat { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 6px 8px; }
|
||
body.web .row.stat .who { grid-column: 2; grid-row: 1; }
|
||
body.web .row.stat .who .sub { white-space: normal; }
|
||
body.web .row.stat .cost { grid-column: 3; grid-row: 1; }
|
||
body.web .row.stat .num { grid-column: 2 / 4; grid-row: 2; min-width: 0; align-items: flex-start; }
|
||
body.web .row.stat .num small { max-width: 100%; white-space: normal; }
|
||
body.web .row.stat .share { grid-column: 2 / 4; grid-row: 3; margin: 0; }
|
||
body.web .connect { grid-template-columns: minmax(0, 1fr); gap: 6px; }
|
||
body.web .connect label { text-align: left; margin-top: 6px; }
|
||
body.web .connect .segs { flex-wrap: wrap; }
|
||
body.web .connect .val { height: auto; min-height: 44px; }
|
||
body.web input:not([type="range"]):not([type="checkbox"]):not([type="radio"]),
|
||
body.web textarea, body.web select { font-size: 16px; min-height: 44px; }
|
||
body.web .modal { padding: max(8px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left)); }
|
||
body.web .modal .editor.framed > .ebody, body.web .editor { grid-template-columns: minmax(0, 1fr); gap: 6px; padding: 12px; }
|
||
body.web .editor label { text-align: left; padding-top: 8px; }
|
||
body.web .editor .segs { max-width: 100%; flex-wrap: wrap; }
|
||
body.web .editor .proxy-row { flex-wrap: wrap; }
|
||
body.web .editor .proxy-row input.proxy-url { flex-basis: 100%; }
|
||
body.web .editor .bar { flex-wrap: wrap; }
|
||
body.web .pop { max-width: calc(100vw - 16px); max-height: calc(100% - 16px); }
|
||
body.web .pop .picker-body { min-height: 0; }
|
||
body.web .pop #list li { min-height: 44px; }
|
||
}
|
||
|
||
/* Import from other apps: a checklist per app */
|
||
.editor.importapps { grid-template-columns: minmax(0, 1fr); }
|
||
.editor.importapps .appnote { font-size: 12px; color: var(--muted); line-height: 1.5; }
|
||
.editor.importapps .applist { display: flex; flex-direction: column; gap: 14px; max-height: min(56vh, 460px); overflow-y: auto; margin: 0 -4px; padding: 0 4px; }
|
||
.editor.importapps .apptabs { display: flex; gap: 4px; padding: 3px; border-radius: 10px; background: var(--pill); overflow-x: auto; scrollbar-width: none; }
|
||
.editor.importapps .apptab { flex: 1 1 0; min-width: max-content; display: flex; align-items: center; justify-content: center; gap: 7px; padding: 6px 12px; border-radius: 7px; font-size: 12.5px; font-weight: 500; color: var(--muted); white-space: nowrap; }
|
||
.editor.importapps .apptab:hover { color: var(--fg); }
|
||
.editor.importapps .apptab.on { background: var(--card); color: var(--fg); box-shadow: 0 1px 2px rgba(0,0,0,.18); }
|
||
.editor.importapps .apptab.missing .applogo { filter: grayscale(1); opacity: .5; }
|
||
.editor.importapps .apptab .count { min-width: 16px; padding: 0 5px; border-radius: 8px; font-size: 10.5px; line-height: 16px; text-align: center; color: var(--fg-2); background: var(--line); }
|
||
.editor.importapps .apptab.missing .count { background: none; color: var(--faint); }
|
||
.editor.importapps .apphead > .applogo, .editor.importapps .apphead > b { display: none; }
|
||
.editor.importapps .apphead { display: flex; align-items: baseline; gap: 8px; padding-bottom: 4px; }
|
||
.editor.importapps .apphead b { font-weight: 600; font-size: 13px; flex: none; }
|
||
.editor.importapps .apphead { align-items: center; }
|
||
.editor.importapps .applogo { width: 18px; height: 18px; flex: none; border-radius: 4px; }
|
||
.editor.importapps .appall { flex: none; display: flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 400; color: var(--muted); text-align: left; cursor: pointer; padding-right: 6px; }
|
||
.editor.importapps .appall input { margin: 0; accent-color: var(--fg); }
|
||
.editor.importapps .apphead code { flex: 1; min-width: 0; font: 11px var(--code); color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.editor.importapps .appempty { font-size: 12px; color: var(--muted); padding: 2px 0 4px; }
|
||
.editor.importapps .approw { text-align: left; font-weight: 400; color: var(--fg); display: flex; align-items: flex-start; gap: 10px; padding: 8px 6px; border-radius: 8px; cursor: pointer; }
|
||
.editor.importapps .approw:hover:not(.dim) { background: var(--pill); }
|
||
.editor.importapps .approw.dim { cursor: default; opacity: .55; }
|
||
.editor.importapps .approw input { margin: 3px 0 0; accent-color: var(--fg); flex: none; }
|
||
.editor.importapps .approw .ic { width: 18px; height: 18px; flex: none; margin-top: 1px; }
|
||
.editor.importapps .approw .appwho { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
|
||
.editor.importapps .approw .name { display: flex; align-items: baseline; gap: 6px; font-size: 13px; }
|
||
.editor.importapps .approw .name .from { font-size: 11px; color: var(--muted); }
|
||
.editor.importapps .approw .sub { font-size: 11.5px; color: var(--muted); overflow-wrap: anywhere; }
|
||
.editor.importapps .approw .segs { margin-top: 3px; max-width: 100%; overflow-x: auto; }
|
||
.editor.importapps .approw .segs .opt { white-space: nowrap; flex: none; }
|
||
.editor.importapps .apptag { flex: none; font-size: 11px; color: var(--fg-2); background: var(--pill); border-radius: 5px; padding: 1px 6px; margin-top: 1px; }
|
||
.editor.importapps .bar .note { font-size: 12px; color: var(--muted); }
|
||
|
||
/* sync and backup, on the Settings page */
|
||
.prefs .sub.bad { color: var(--red); }
|
||
.prefs .sync-note .who .sub + .sub { margin-top: 2px; }
|
||
.editor.sync-form { grid-template-columns: 86px minmax(0, 1fr); }
|
||
.editor label.tick { display: flex; align-items: center; gap: 7px; text-align: left; padding-top: 0; color: var(--fg-2); cursor: pointer; }
|
||
.editor label.tick input { margin: 0; }
|
||
.editor .fname { flex: 1; min-width: 0; font-size: 12.5px; color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.editor.sync-form .done { grid-column: 1 / -1; font-size: 12.5px; color: var(--fg-2); user-select: text; -webkit-user-select: text; }
|
||
.editor.sync-form .bar { grid-column: 1 / -1; }
|
||
|
||
/* the usual context windows under the field, one click each (#120) */
|
||
.cxpicks { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
|
||
.cxpick {
|
||
height: 22px; padding: 0 9px; border-radius: 999px;
|
||
border: 1px solid var(--line); background: var(--card); color: var(--muted);
|
||
font-size: 11.5px; font-variant-numeric: tabular-nums; cursor: pointer;
|
||
transition: border-color .12s, background .12s, color .12s;
|
||
}
|
||
.cxpick:hover { border-color: var(--accent); color: var(--accent); }
|
||
.cxpick.on { color: var(--accent); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 45%, transparent); font-weight: 500; }
|
||
|
||
/* Account rows use the existing pointer sorter, without a visible handle. */
|
||
.accts > [data-account-id] { user-select: text; -webkit-user-select: text; }
|
||
.accts.reorderable > [data-account-id] { cursor: grab; touch-action: pan-y; }
|
||
.accts.reorderable > [data-account-id]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
||
.accts.sorting > [data-account-id] { animation: none; transition: transform .16s cubic-bezier(.22, 1, .36, 1); }
|
||
.accts.sorting > .dragging { position: relative; z-index: 2; background: var(--card-2); box-shadow: 0 0 0 1px var(--line); cursor: grabbing; transition: none; will-change: transform; }
|
||
.accts[aria-busy=true] > [data-account-id] { cursor: progress; }
|
||
/* the Usage page's cards, dragged by their logos: a grip by the logo on hover.
|
||
A grip's box holds both its columns of dots whole, 3px apart: at 5px wide
|
||
with 3.5px between them the right column was cut in half (Hu9956, #842) */
|
||
.subscription-head .us-handle { position: relative; width: 24px; height: 24px; margin: -4px -3px; }
|
||
.subscription-head .us-handle::before { content: ""; position: absolute; left: -8px; top: 50%; width: 6px; height: 11px; margin-top: -5.5px; background: radial-gradient(circle, var(--muted) .9px, transparent 1.2px) 0 0 / 3px 3.75px; opacity: 0; transition: opacity .15s; }
|
||
.subscription-card:is(:hover, .dragging) .us-handle::before, .us-handle:focus-visible::before { opacity: 1; }
|
||
.subscription-usage.sorting { user-select: none; -webkit-user-select: none; }
|
||
.subscription-usage.sorting > .subscription-card { transition: transform .22s cubic-bezier(.22, 1, .36, 1); }
|
||
.subscription-usage.sorting .us-handle { cursor: grabbing; }
|
||
.subscription-usage > .subscription-card.dragging { position: relative; z-index: 2; box-shadow: 0 8px 22px rgba(20, 22, 30, .14), 0 0 0 1px var(--line); transition: none; }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.accts.sorting > [data-account-id], #agents.sorting > .row, .subscription-usage.sorting > .subscription-card { transition: none; }
|
||
}
|
||
/* the show while the session files are indexed: the words on the left, a
|
||
field of dots that light up as the files land on the right, a hairline
|
||
along the foot. The hero holds its own layout (:has) whatever the class,
|
||
which another watch's stop may take off. */
|
||
.stats.indexing { display: block; background: var(--card); }
|
||
.sess-indexing { position: relative; display: grid; grid-template-columns: minmax(250px, 34%) 1fr; align-items: center; gap: 8px; min-height: 164px; padding: 0 0 0 26px; overflow: hidden; }
|
||
.si-words { position: relative; z-index: 1; display: grid; gap: 4px; min-width: 0; padding: 22px 0; }
|
||
.si-head { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--fg); }
|
||
.si-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.si-spin { width: 12px; height: 12px; border-radius: 50%; flex: none; background: conic-gradient(from 0deg, transparent 0 8%, var(--accent) 100%); -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 1.75px), #000 calc(100% - 1.5px)); mask: radial-gradient(farthest-side, transparent calc(100% - 1.75px), #000 calc(100% - 1.5px)); animation: si-spin .9s linear infinite; }
|
||
@keyframes si-spin { to { transform: rotate(1turn); } }
|
||
.sess-indexing.done .si-spin { animation: none; background: var(--accent); }
|
||
.si-pct { display: flex; align-items: baseline; gap: 2px; margin-top: 6px; font-variant-numeric: tabular-nums; line-height: 1; }
|
||
.si-pct b { font-size: 38px; font-weight: 600; letter-spacing: -.035em; color: var(--fg); }
|
||
.si-pct span { font-size: 15px; font-weight: 500; color: var(--muted); }
|
||
.sess-indexing:not(.known) .si-pct { display: none; }
|
||
.si-line { margin-top: 4px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.si-tip { font-size: 11.5px; color: var(--faint, var(--muted)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.si-tip.in { animation: si-tip .6s ease-out; }
|
||
@keyframes si-tip { from { opacity: 0; transform: translateY(3px); } }
|
||
.si-field { position: relative; align-self: stretch; min-width: 0;
|
||
-webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 94%, transparent);
|
||
mask-image: linear-gradient(90deg, transparent, #000 14%, #000 94%, transparent); }
|
||
.si-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||
.si-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
||
.si-bar i { position: absolute; inset: 0 auto 0 0; width: 22%; background: linear-gradient(90deg, transparent, var(--accent));
|
||
box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent);
|
||
animation: si-sweep 2.2s cubic-bezier(.5, 0, .3, 1) infinite; }
|
||
@keyframes si-sweep { from { transform: translateX(-100%); } to { transform: translateX(560%); } }
|
||
.sess-indexing.known .si-bar i { animation: none; transform: none; transition: width .5s ease-out; background: var(--accent); }
|
||
@container (max-width: 560px) {
|
||
.sess-indexing { display: block; padding: 0 20px; }
|
||
.si-field { position: absolute; inset: 0; opacity: .4; -webkit-mask-image: none; mask-image: none; }
|
||
}
|
||
/* Safari before 16 (macOS 12's, #220) has no container queries: the window's width instead */
|
||
@supports not (container-type: inline-size) {
|
||
@media (max-width: 620px) {
|
||
.sess-indexing { display: block; padding: 0 20px; }
|
||
.si-field { position: absolute; inset: 0; opacity: .4; -webkit-mask-image: none; mask-image: none; }
|
||
}
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.si-spin, .si-tip.in, .si-bar i { animation: none; }
|
||
.si-spin { background: conic-gradient(var(--accent) 0 70%, color-mix(in srgb, var(--accent) 20%, transparent) 0); }
|
||
.sess-indexing:not(.known) .si-bar i { width: 100%; opacity: .35; }
|
||
}
|
||
/* Safari before 16.2 (macOS 12's, #220) has no color-mix(): a declaration
|
||
with one is dropped, and where nothing else is under it the page would go
|
||
clear. The panel's paint (which tintPanel hands the system), and the
|
||
floating status, take a plain colour there instead. */
|
||
@supports not (color: color-mix(in srgb, red 50%, blue)) {
|
||
.led .src, .led .src.official { --badge-bg: var(--card); border-color: var(--line); }
|
||
body.panel { --panel-tint: var(--bg); }
|
||
.status.ok, .status.err, .status.warn { background: var(--bg); }
|
||
.status.lift { background: var(--card); }
|
||
}
|
||
/* ---- the panel's Usage tab: the window's Requests, made small ---------------- */
|
||
.panel-usage { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 2px 2px 6px; }
|
||
.pu-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 24px; }
|
||
.pu-bar .grow { flex: 1; }
|
||
.pu-bar .segs .opt { height: 22px; padding: 0 9px; font-size: 11.5px; }
|
||
.pu-bar .sess-pick { min-width: 0; max-width: 150px; }
|
||
.pu-bar .text { flex: none; font-size: 12px; }
|
||
.pu-bar .pu-again { width: 22px; height: 22px; flex: none; }
|
||
.pu-tot { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-radius: 11px; background: var(--card); box-shadow: var(--card-edge); }
|
||
.pu-tot .blk { min-width: 0; padding: 8px 10px 8px; }
|
||
.pu-tot .blk + .blk { border-left: 1px solid var(--line-2); }
|
||
.pu-tot .k { display: block; font-size: 10.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.pu-tot .v { display: block; margin-top: 1px; font-size: 16px; font-weight: 600; letter-spacing: -.01em; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
||
.pu-tot .v.cost { color: var(--green); }
|
||
.pu-tot .sub { display: block; margin-top: 1px; font-size: 10.5px; color: var(--muted); white-space: normal; overflow: visible; text-overflow: clip; }
|
||
.pu-tot .sub.bad { color: var(--red); }
|
||
.pu-card { padding: 8px 10px 6px; border-radius: 11px; background: var(--card); box-shadow: var(--card-edge); }
|
||
.pu-card .led-bar { margin-bottom: 4px; }
|
||
.pu-card .led-bar .segs .opt { height: 20px; padding: 0 8px; font-size: 11px; }
|
||
.pu-card .led-chart .plot { height: 124px; }
|
||
.pu-card .led-rank { margin-top: 4px; }
|
||
.pu-none { margin: 0; padding: 12px; border-radius: 11px; background: var(--card); box-shadow: var(--card-edge); font-size: 12px; line-height: 1.55; color: var(--muted); }
|
||
.pu-none b { display: block; color: var(--fg); font-weight: 550; }
|
||
.skeleton.pu-sk { height: 52px; border-radius: 11px; }
|
||
.panel-usage.pu-loading :is(.pu-tot, .pu-card) { opacity: .55; }
|
||
.panel-usage :is(.pu-tot, .pu-card) { transition: opacity .15s; }
|
||
@media (max-width: 400px) {
|
||
.pu-tot { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||
.pu-tot .blk:nth-child(3) { border-left: 0; }
|
||
.pu-tot .blk:nth-child(n + 3) { border-top: 1px solid var(--line-2); }
|
||
}
|
||
|
||
/* how often the Usage page reads its numbers again, and a way to read them now */
|
||
.usage-refresh { display: inline-flex; align-items: center; gap: 2px; margin-right: 10px; }
|
||
.usage-refresh .icon { width: 24px; height: 24px; }
|
||
.usage-refresh .icon.busy svg { animation: spin .8s linear infinite; }
|
||
.usage-refresh .sess-pick { height: 24px; }
|
||
.led-rank .rk .rk-b { overflow-wrap: anywhere; }
|
||
|
||
/* ---- an agent's model list ------------------------------------------------ */
|
||
/* the line under an agent's name: quiet words, a pill only on hover */
|
||
body.window .row.agent .who.with-models { flex-wrap: wrap; row-gap: 0; }
|
||
.ag-models-line { flex: 0 0 100%; min-width: 0; display: flex; }
|
||
.ag-models { min-width: 0; display: inline-flex; align-items: center; gap: 4px; height: 20px; margin: 1px 0 -2px -6px; padding: 0 6px; border: 0; border-radius: 6px; background: none; color: var(--muted); font: inherit; font-size: 11.5px; line-height: 1; white-space: nowrap; cursor: pointer; transition: background-color .15s, color .15s; }
|
||
.ag-models b { font-weight: 600; color: var(--fg-2); font-variant-numeric: tabular-nums; }
|
||
.ag-models .chev { display: inline-flex; color: var(--faint); transition: transform .2s var(--ease, ease); }
|
||
.ag-models:hover, .ag-models.open { background: var(--pill); color: var(--fg-2); }
|
||
.ag-models.open .chev { transform: rotate(90deg); }
|
||
.ag-models:focus-visible { outline: 1.5px solid var(--accent); outline-offset: 1px; }
|
||
|
||
.pop.am-pop { overflow: visible; max-height: 560px; padding: 14px 6px 8px; border-radius: 14px; background: var(--pop-bg); }
|
||
/* the arrow at the line it grows from */
|
||
.pop.am-pop::before { content: ""; position: absolute; left: calc(var(--ox, 24px) - 6px); top: -5px; width: 12px; height: 12px; background: var(--pop-bg); transform: rotate(45deg); border-radius: 2px 0 0 0; box-shadow: -.5px -.5px 0 color-mix(in srgb, var(--fg) 10%, transparent); }
|
||
.pop.am-pop.up::before { top: auto; bottom: -5px; border-radius: 0 0 2px 0; box-shadow: .5px .5px 0 color-mix(in srgb, var(--fg) 10%, transparent); }
|
||
.am-head { padding: 0 12px; }
|
||
.am-t { font-size: 14px; font-weight: 600; letter-spacing: -.01em; color: var(--fg); }
|
||
.am-d { margin-top: 3px; font-size: 12px; line-height: 1.45; color: var(--muted); }
|
||
.am-tools { display: flex; align-items: center; gap: 8px; margin: 12px 12px 6px; }
|
||
.am-search { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 9px; border-radius: 8px; background: var(--pill); color: var(--faint); }
|
||
.pop.am-pop .am-search input { flex: 1; min-width: 0; height: 28px; border: 0; outline: none; background: none; color: var(--fg); font: inherit; font-size: 12.5px; }
|
||
.am-search:focus-within { box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--accent) 55%, transparent); }
|
||
.am-seg { display: inline-flex; flex: none; padding: 2px; border-radius: 8px; background: var(--seg-track); }
|
||
.am-seg button { height: 24px; padding: 0 9px; border: 0; border-radius: 6px; background: none; color: var(--ctl-fg); font: inherit; font-size: 12px; cursor: pointer; transition: background-color .15s, color .15s; }
|
||
.am-seg button.on { background: var(--seg-thumb); color: var(--fg); box-shadow: var(--seg-edge); }
|
||
.am-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: 2px; }
|
||
/* the providers down the left (蓝猫 on Discord), the models of the one
|
||
picked beside them, each scrolling on its own */
|
||
.am-body { flex: 1 1 auto; min-height: 0; display: flex; gap: 6px; }
|
||
.am-body .am-list { min-width: 0; }
|
||
.am-rail { flex: none; width: 176px; overflow-y: auto; overscroll-behavior: contain; padding: 4px 6px 2px 2px; border-right: 1px solid var(--line-2); }
|
||
.am-ri { display: flex; align-items: center; gap: 8px; width: 100%; height: 30px; padding: 0 8px; border: 0; border-radius: 8px; background: none; color: var(--fg-2); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; transition: background-color .12s; }
|
||
.am-ri:hover { background: var(--pill); }
|
||
.am-ri.on { background: var(--accent-soft); color: var(--fg); }
|
||
.am-ri > .ic, .am-ri > svg { width: 14px; height: 14px; flex: none; color: var(--muted); }
|
||
.am-ri .rn { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.am-ri .c { flex: none; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.am-ri:focus-visible { outline: 1.5px solid var(--accent); outline-offset: -1.5px; }
|
||
.am-gh { display: flex; align-items: center; margin: 6px 2px 0; }
|
||
.am-fold { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border: 0; border-radius: 8px; background: none; color: var(--muted); font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
|
||
.am-fold > .ic, .am-fold > svg { width: 14px; height: 14px; flex: none; }
|
||
.am-fold .tw { display: inline-flex; width: 10px; color: var(--faint); }
|
||
.am-fold .tw svg { transition: transform .2s var(--ease, ease); }
|
||
.am-g.shut .am-fold .tw svg { transform: rotate(-90deg); }
|
||
.am-fold .gn { color: var(--fg-2); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.am-fold .c { font-variant-numeric: tabular-nums; }
|
||
.am-all { flex: none; height: 24px; margin-right: 6px; padding: 0 6px; border: 0; border-radius: 6px; background: none; color: var(--accent); font: inherit; font-size: 11.5px; cursor: pointer; opacity: 0; transition: opacity .15s, background-color .15s; }
|
||
.am-gh:hover .am-all { opacity: 1; }
|
||
.am-all:focus-visible { opacity: 1; }
|
||
.am-all:hover { background: var(--accent-soft); }
|
||
@media (hover: none) { .am-all { opacity: 1; } }
|
||
.am-mr { display: flex; align-items: center; gap: 10px; width: calc(100% - 4px); height: 32px; margin: 0 2px; padding: 0 12px; border: 0; border-radius: 8px; background: none; color: var(--fg); font: inherit; font-size: 13px; text-align: left; cursor: pointer; transition: background-color .12s; }
|
||
.am-mr:hover { background: var(--pill); }
|
||
/* under its group: the model's icon in the group icon's column, past the
|
||
twisty, so the rows read as the group's */
|
||
.am-rows .am-mr { padding-left: 28px; }
|
||
.am-mr:focus-visible { outline: 1.5px solid var(--accent); outline-offset: -1.5px; }
|
||
.am-mr .lg { flex: none; }
|
||
.am-mr .lg > svg { color: var(--muted); }
|
||
.am-mr.off .lg { opacity: .45; }
|
||
/* a routing group's providers, discs as in a picker's field, in one width of slot, so the
|
||
names still start in a column */
|
||
.am-g.routes .am-mr .lg { min-width: 56px; justify-content: flex-start; }
|
||
.am-mr .ic-stack .disc { width: 17px; height: 17px; }
|
||
.am-mr .ic-stack .disc > .ic { width: 11px !important; height: 11px !important; }
|
||
.am-mr .n { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color .15s; }
|
||
.am-mr .x { flex: none; font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
|
||
.am-mr .ck { flex: none; display: inline-flex; justify-content: center; width: 16px; color: var(--accent); }
|
||
.am-mr.off .n { color: var(--faint); }
|
||
.am-mr.lock { cursor: default; }
|
||
.am-mr.lock:hover { background: none; }
|
||
.am-mr.lock .ck { opacity: .45; }
|
||
.am-tag { margin-left: 6px; padding: 1px 6px; border-radius: 5px; background: var(--accent-soft); color: var(--accent); font-size: 10.5px; font-weight: 500; }
|
||
.am-none { padding: 18px 12px; color: var(--muted); font-size: 12.5px; text-align: center; }
|
||
.am-foot { display: flex; align-items: center; gap: 8px; margin: 8px 8px 0; padding: 10px 6px 2px; border-top: 1px solid var(--line-2); font-size: 11.5px; color: var(--muted); }
|
||
.am-foot .sp { flex: 1; }
|
||
.am-reset { border: 0; background: none; padding: 2px 4px; border-radius: 5px; color: var(--fg-2); font: inherit; font-size: 11.5px; cursor: pointer; }
|
||
.am-reset:hover:not(:disabled) { color: var(--accent); }
|
||
.am-reset:disabled { color: var(--faint); cursor: default; }
|
||
.am-dot { color: var(--faint); }
|
||
|
||
/* ---- an agent's switch onto magpie ---------------------------------------- */
|
||
/* the rows drawn again under the line said beneath each name had WebKit's
|
||
scroll anchoring move the list a few px before the page was held back
|
||
(claude-direct.test.cjs); the page holds the reader itself */
|
||
#view-agents { overflow-anchor: none; }
|
||
body.window .row.agent > .ag-conn { margin-left: 12px; align-self: center; cursor: pointer; }
|
||
.ag-conn-row { display: flex; align-items: center; gap: 8px; min-height: 28px; }
|
||
.ag-conn-row .ag-conn-said { flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.ag-conn-row .lib-switch { cursor: pointer; }
|
||
|
||
/* 「接入」 in the window: a row says whether the agent goes through magpie —
|
||
a line under its name, a link that opens it, its switch */
|
||
.ag-lead { margin: 0 2px 12px; font-size: 12.5px; color: var(--fg-2); }
|
||
.ag-lead b { font-weight: 600; color: var(--fg); }
|
||
.ag-lead.welcome { margin: 0 0 12px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
|
||
.ag-lead .ag-lead-h { display: block; font-size: 14px; margin-bottom: 4px; }
|
||
.ag-lead p { margin: 0; line-height: 1.55; color: var(--muted); }
|
||
.ag-lead .text.primary { margin-top: 12px; }
|
||
/* the first line keeps its place opened: a line of its own height, the
|
||
row not centring what it holds; no gap between its lines, which the
|
||
opened part couldn't fold away: it starts where the shut row ended */
|
||
body.window .row.agent.conn { flex-wrap: wrap; min-height: 56px; align-content: flex-start; row-gap: 0; }
|
||
body.window .row.agent.conn > .who { min-height: 42px; align-content: center; }
|
||
body.window .row + .row.agent.conn > .who { min-height: 41px; } /* the line above it is in the 56px */
|
||
.ag-st { flex: 0 0 100%; min-width: 0; display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 18px; color: var(--muted); }
|
||
.ag-st .ag-st-t { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.ag-st .ag-st-t b { font-weight: 600; color: var(--fg-2); }
|
||
.ag-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--faint); }
|
||
.ag-st.on .ag-dot { background: var(--green); }
|
||
.ag-st.wait .ag-dot, .ag-warn .ag-dot { background: var(--amber); }
|
||
.ag-st.wait .ag-st-t { color: var(--amber); }
|
||
.ag-st.bad .ag-dot { background: var(--red); }
|
||
.ag-st.bad .ag-st-t { color: var(--red); }
|
||
.ag-st .ag-fix { flex: none; }
|
||
.ag-link, .ag-quiet { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border: 0; border-radius: 6px; background: none; color: var(--fg-2); font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer; transition: background-color .15s, color .15s; }
|
||
.ag-link:hover, .ag-quiet:hover, .ag-link.open { background: var(--pill); color: var(--fg); }
|
||
.ag-link .chev, .ag-quiet .chev { display: inline-flex; color: var(--faint); transition: transform .2s ease; }
|
||
.ag-quiet.open .chev { transform: rotate(90deg); }
|
||
.ag-quiet.red { color: var(--red); }
|
||
.ag-quiet.red:hover { background: color-mix(in srgb, var(--red) 10%, transparent); color: var(--red); }
|
||
.ag-quiet.accent { color: var(--accent); }
|
||
.ag-link:focus-visible, .ag-quiet:focus-visible, .ag-add:focus-visible { outline: 1.5px solid var(--accent); outline-offset: 1px; }
|
||
.row.agent.conn > .ag-link { margin-left: auto; }
|
||
.row.agent.conn > .ag-show { margin-left: auto; align-self: center; }
|
||
.row.agent.conn > .ag-show + .ag-link { margin-left: 8px; }
|
||
.row.agent.conn > .fields + .ag-link { margin-left: 0; }
|
||
.row.agent.conn > .ag-conn { margin-left: 4px; align-self: center; cursor: pointer; }
|
||
.row.agent.conn > .ag-link + .ag-conn { margin-left: 4px; }
|
||
.row.agent.conn > .who + .ag-conn, .row.agent.conn > .who + .ag-add, .row.agent.conn > .who + .ag-cant { margin-left: auto; }
|
||
.row.agent.conn > .ag-conn:disabled { opacity: .4; cursor: default; }
|
||
/* the model it starts on, beside the switch: one width down the list, so
|
||
the pickers and the switches line up */
|
||
.row.agent.conn > .field.ag-start { flex: none; width: 196px; margin-left: 8px; align-self: center; justify-content: flex-start; }
|
||
.row.agent.conn > .who + .field.ag-start { margin-left: auto; }
|
||
.row.agent.conn > .field.ag-start .v { flex: 1; text-align: left; }
|
||
.row.agent.conn > .field.ag-start .chev { margin-left: auto; }
|
||
.row.agent.conn > .field.ag-start + .ag-conn { margin-left: 10px; }
|
||
.row.agent.conn > .field.launch { flex: none; margin-left: 8px; align-self: center; }
|
||
.row.agent.conn > .who + .field.launch { margin-left: auto; }
|
||
.row.agent.conn > .field.launch + .field.ag-start { margin-left: 0; }
|
||
.ag-add { flex: none; height: 24px; padding: 0 10px; border: 0; border-radius: 6px; background: var(--pill); color: var(--fg); font: inherit; font-size: 12px; font-weight: 500; cursor: pointer; }
|
||
.ag-add:hover { background: var(--pill-hover); }
|
||
.ag-cant { flex: none; font-size: 12px; color: var(--faint); }
|
||
.ag-conn-gap { flex: none; width: 32px; margin-left: 10px; }
|
||
.row.agent.conn.unplugged .ag-handle .ic { opacity: .7; }
|
||
/* opened: the settings as named lines on the row's quieter ground */
|
||
.ag-exp { flex: 0 0 calc(100% + 26px); margin: 7px -12px -7px -14px; padding: 4px 16px 14px 50px; border-top: 1px solid var(--line-2); background: var(--card-2); cursor: default; }
|
||
.ag-kv { display: flex; align-items: flex-start; gap: 16px; padding: 11px 0; border-top: 1px solid var(--line-2); }
|
||
.ag-kv:first-child { border-top: 0; }
|
||
.ag-k { width: 112px; flex: none; padding-top: 3px; font-size: 12px; color: var(--muted); }
|
||
.ag-v { flex: 1; min-width: 0; font-size: 12.5px; color: var(--fg-2); display: grid; gap: 4px; }
|
||
.ag-vl { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; min-height: 24px; }
|
||
.ag-vl > .fields { margin-left: 0; }
|
||
/* the opened row has the whole width under the name to lay its settings out
|
||
in, so they are a line of pills that wraps rather than the shut row's two
|
||
narrow columns: a name, a model and a logo do not go into 124px. #agents for
|
||
the extras width the shut row's own rule sets on the id. */
|
||
#agents .ag-exp .ag-vl > .fields { display: flex; flex-wrap: wrap; width: 100%; gap: 6px; }
|
||
#agents .ag-exp .ag-vl > .fields > .field { flex: 0 1 auto; min-width: 170px; }
|
||
#agents .ag-exp .ag-vl > .fields > .extras-cell { justify-content: flex-start; flex-wrap: wrap; }
|
||
.ag-code, .ag-diff code, .ag-path { font-family: var(--code); font-size: 11.5px; }
|
||
.ag-code { padding: 1px 5px; border-radius: 4px; background: var(--pill); color: var(--fg); }
|
||
.ag-warn { gap: 8px; font-size: 12px; }
|
||
.ag-hint { font-size: 12px; color: var(--muted); }
|
||
.ag-tier { width: 70px; flex: none; font-size: 12px; color: var(--fg-2); }
|
||
.ag-vl .field.ag-pick { width: 220px; justify-content: flex-start; }
|
||
.ag-vl .field.ag-eff { flex: none; }
|
||
.ag-vl .field.ag-pick .v { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
|
||
.ag-exp .extras-cell { justify-content: flex-start; }
|
||
.ag-chip { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: 6px; background: var(--card); box-shadow: inset 0 0 0 1px var(--line); font-size: 12px; color: var(--fg-2); }
|
||
.ag-chip .ic { width: 13px !important; height: 13px !important; }
|
||
.ag-chip .n { color: var(--muted); font-variant-numeric: tabular-nums; }
|
||
.ag-foot { display: flex; align-items: center; gap: 8px; margin-top: 2px; padding-top: 12px; border-top: 1px solid var(--line-2); font-size: 12px; color: var(--muted); }
|
||
.ag-files { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.ag-path { color: var(--fg-2); }
|
||
.ag-diff-box { margin-top: 10px; max-height: 320px; overflow: auto; }
|
||
.ag-diff-more { display: block; margin: 2px 0 6px 28px; padding: 2px 0; border: 0; background: none; font: inherit; font-size: 11.5px; color: var(--accent); cursor: pointer; }
|
||
/* a file's lines as disconnecting changes them */
|
||
.ag-diff { display: grid; gap: 10px; }
|
||
.ag-diff-file { border: 1px solid var(--line); border-radius: 8px; background: var(--card); overflow: hidden; }
|
||
.ag-diff-path { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--line-2); font-family: var(--code); font-size: 11.5px; color: var(--fg); }
|
||
.ag-diff-path:last-child { border-bottom: 0; }
|
||
.ag-diff-line { display: flex; align-items: baseline; gap: 8px; padding: 2px 10px; font-size: 11.5px; line-height: 1.6; }
|
||
.ag-diff-line:first-of-type { padding-top: 6px; }
|
||
.ag-diff-line:last-child { padding-bottom: 6px; }
|
||
.ag-diff-line .op { width: 10px; flex: none; text-align: center; font-family: var(--code); }
|
||
.ag-diff-line code { flex: 1; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--fg-2); }
|
||
.ag-diff-line.del .op, .ag-diff-line.del code { color: var(--red); }
|
||
.ag-diff-line .ind { text-decoration: none; }
|
||
.ag-diff-line.del code .t { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--red) 45%, transparent); }
|
||
.ag-diff-line.back .op { color: var(--green); }
|
||
.ag-tag { flex: none; padding: 0 6px; border-radius: 4px; background: var(--pill); font-family: inherit; font-size: 10.5px; line-height: 16px; color: var(--muted); }
|
||
.ag-tag.del { background: color-mix(in srgb, var(--red) 12%, transparent); color: var(--red); }
|
||
/* 短窗口只滚动正文,不压缩预览所在的行,以免与下方说明重叠。 */
|
||
.modal .editor.disconnect-ask > .ebody { grid-auto-rows: max-content; }
|
||
.disconnect-ask .ag-diff-wrap { grid-column: 1 / -1; max-height: min(46vh, 380px); overflow: auto; margin: 2px 0 10px; }
|
||
.ag-diff-loading { padding: 14px 0; font-size: 12px; color: var(--muted); }
|
||
.disconnect-ask .ag-note { grid-column: 1 / -1; margin: 0 0 10px; font-size: 12px; color: var(--muted); }
|
||
.ag-bar-note { font-size: 12px; color: var(--muted); }
|
||
@media (max-width: 600px) {
|
||
body.window .row.agent.conn { display: flex; }
|
||
/* the name beside its logo; the link and the switch wrap under it when short of room */
|
||
body.window .row.agent.conn > .who { width: auto; flex: 1 1 160px; min-width: 0; }
|
||
.ag-exp { padding-left: 16px; min-width: 0; }
|
||
.ag-kv { flex-direction: column; gap: 4px; min-width: 0; }
|
||
/* the pickers take the line, the effort and the squares wrap under them */
|
||
.ag-vl { width: 100%; min-width: 0; }
|
||
#agents .ag-vl > .fields { display: flex; flex-wrap: wrap; width: 100%; min-width: 0; }
|
||
.ag-vl > .fields > .field.main, .ag-vl > .fields > .field.solo { flex: 1 1 100%; min-width: 0; }
|
||
.ag-vl > .fields > .field.side { flex: 1 0 124px; }
|
||
.ag-vl > .fields > .extras-cell { flex-wrap: wrap; max-width: 100%; }
|
||
.ag-vl .field.ag-pick { flex: 1 1 160px; width: auto; min-width: 0; }
|
||
/* short of room, the model it starts on takes a line of its own under
|
||
the name, the link and the switch staying beside it */
|
||
.row.agent.conn > .field.ag-start, .row.agent.conn > .who + .field.ag-start { order: 1; flex: 1 1 100%; width: auto; margin: 9px 0 0 34px; }
|
||
.row.agent.conn > .ag-exp { order: 2; }
|
||
.ag-conn-gap { display: none; }
|
||
}
|
||
|
||
/* Checkboxes are drawn as the app's own, not the system's (ARNO on
|
||
Discord: the Sessions page's white boxes stood out in dark mode); a
|
||
page's own margins stay. */
|
||
input[type="checkbox"] {
|
||
appearance: none; -webkit-appearance: none;
|
||
width: 14px; height: 14px; flex: none;
|
||
display: inline-grid; place-content: center; vertical-align: middle;
|
||
border: 1px solid var(--faint); border-radius: 4px;
|
||
background: var(--card); color: var(--accent-fg);
|
||
}
|
||
input[type="checkbox"]:hover:not(:disabled) { border-color: var(--muted); }
|
||
input[type="checkbox"]:checked, input[type="checkbox"]:indeterminate { background: var(--accent); border-color: var(--accent); }
|
||
input[type="checkbox"]::before {
|
||
content: ""; width: 10px; height: 10px; background: currentColor; transform: scale(0);
|
||
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2 5.2l2 2L8 3' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
|
||
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2 5.2l2 2L8 3' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
|
||
}
|
||
input[type="checkbox"]:checked::before { transform: scale(1); }
|
||
input[type="checkbox"]:indeterminate::before { transform: scale(1); -webkit-mask: none; mask: none; width: 8px; height: 1.6px; border-radius: 1px; }
|
||
input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
||
input[type="checkbox"]:disabled { opacity: .45; }
|