@kylindc/ccxray 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/LICENSE +21 -0
- package/README.ja.md +144 -0
- package/README.md +145 -0
- package/README.zh-TW.md +144 -0
- package/package.json +46 -0
- package/public/app.js +99 -0
- package/public/cost-budget-ui.js +305 -0
- package/public/entry-rendering.js +535 -0
- package/public/index.html +119 -0
- package/public/intercept-ui.js +335 -0
- package/public/keyboard-nav.js +208 -0
- package/public/messages.js +750 -0
- package/public/miller-columns.js +1686 -0
- package/public/quota-ticker.js +67 -0
- package/public/style.css +431 -0
- package/public/system-prompt-ui.js +327 -0
- package/server/auth.js +34 -0
- package/server/bedrock-credentials.js +141 -0
- package/server/config.js +190 -0
- package/server/cost-budget.js +220 -0
- package/server/cost-worker.js +110 -0
- package/server/eventstream.js +148 -0
- package/server/forward.js +683 -0
- package/server/helpers.js +393 -0
- package/server/hub.js +418 -0
- package/server/index.js +551 -0
- package/server/pricing.js +133 -0
- package/server/restore.js +141 -0
- package/server/routes/api.js +123 -0
- package/server/routes/costs.js +124 -0
- package/server/routes/intercept.js +89 -0
- package/server/routes/sse.js +44 -0
- package/server/sigv4.js +104 -0
- package/server/sse-broadcast.js +71 -0
- package/server/storage/index.js +36 -0
- package/server/storage/interface.js +26 -0
- package/server/storage/local.js +79 -0
- package/server/storage/s3.js +91 -0
- package/server/store.js +108 -0
- package/server/system-prompt.js +150 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// ── Topbar Quota Ticker ───────────────────────────────────────────────
|
|
2
|
+
let quotaTickerInterval = null;
|
|
3
|
+
|
|
4
|
+
async function updateQuotaTicker() {
|
|
5
|
+
try {
|
|
6
|
+
const [block, monthly] = await Promise.all([
|
|
7
|
+
fetch('/_api/costs/current-block').then(r => r.json()).catch(() => ({ active: false })),
|
|
8
|
+
fetch('/_api/costs/monthly').then(r => r.json()).catch(() => ({ currentMonth: { costUSD: 0 } })),
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
// Progress bar
|
|
12
|
+
const barWrap = document.getElementById('qt-bar-wrap');
|
|
13
|
+
const barFill = document.getElementById('qt-bar-fill');
|
|
14
|
+
const barPct = document.getElementById('qt-bar-pct');
|
|
15
|
+
const barTime = document.getElementById('qt-bar-time');
|
|
16
|
+
if (block.active) {
|
|
17
|
+
const pct = block.percentUsed || 0;
|
|
18
|
+
const timePct = block.timePct || 0;
|
|
19
|
+
const color = pct < 60 ? 'var(--green)' : pct < 85 ? 'var(--yellow)' : 'var(--red)';
|
|
20
|
+
barFill.style.width = Math.min(pct, 100) + '%';
|
|
21
|
+
barFill.style.background = color;
|
|
22
|
+
const minR = block.minutesRemaining || 0;
|
|
23
|
+
const timeStr = minR > 60 ? Math.floor(minR/60) + 'h' + (minR%60) + 'm' : minR + 'min';
|
|
24
|
+
// Show pace warning if token% significantly exceeds time%
|
|
25
|
+
const paceRatio = timePct > 0 ? pct / timePct : 0;
|
|
26
|
+
const paceWarn = paceRatio > 1.3 ? ' ⚡' : '';
|
|
27
|
+
barPct.textContent = pct.toFixed(1) + '%' + paceWarn;
|
|
28
|
+
barTime.textContent = timeStr + ' left';
|
|
29
|
+
barWrap.style.display = 'flex';
|
|
30
|
+
} else {
|
|
31
|
+
barWrap.style.display = 'none';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ROI badge
|
|
35
|
+
const roiEl = document.getElementById('qt-roi');
|
|
36
|
+
const currentCost = monthly.currentMonth?.costUSD || 0;
|
|
37
|
+
const roi = (currentCost / 200).toFixed(1);
|
|
38
|
+
roiEl.textContent = 'ROI ' + roi + 'x';
|
|
39
|
+
roiEl.style.display = 'inline';
|
|
40
|
+
|
|
41
|
+
// Recommendation chip
|
|
42
|
+
const chipEl = document.getElementById('qt-chip');
|
|
43
|
+
if (block.active && block.burnRate) {
|
|
44
|
+
const br = block.burnRate.tokensPerMinute || 0;
|
|
45
|
+
const capacity = 220000 / 300; // tokens per min at full speed
|
|
46
|
+
const ratio = br / capacity;
|
|
47
|
+
if (ratio < 0.3) {
|
|
48
|
+
chipEl.textContent = '💡 Can parallelize';
|
|
49
|
+
chipEl.style.display = 'inline';
|
|
50
|
+
} else if (block.projection && block.projection.totalTokens > 220000 * 0.9) {
|
|
51
|
+
chipEl.textContent = '⚠️ Slow down';
|
|
52
|
+
chipEl.style.display = 'inline';
|
|
53
|
+
} else {
|
|
54
|
+
chipEl.style.display = 'none';
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
chipEl.style.display = 'none';
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// silent fail — ticker is ambient, not critical
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function startQuotaTicker() {
|
|
65
|
+
updateQuotaTicker();
|
|
66
|
+
quotaTickerInterval = setInterval(updateQuotaTicker, 30000);
|
|
67
|
+
}
|
package/public/style.css
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #0d1117; --surface: #161b22; --surface-hover: #1c2129; --surface-active: #1a2535; --border: #30363d;
|
|
3
|
+
--text: #e6edf3; --dim: #8b949e; --accent: #58a6ff;
|
|
4
|
+
--green: #3fb950; --yellow: #d29922; --red: #f85149;
|
|
5
|
+
--purple: #bc8cff; --orange: #f0883e;
|
|
6
|
+
/* Heatmap */
|
|
7
|
+
--heatmap-empty: #161b22;
|
|
8
|
+
--heatmap-0: #2a1508; --heatmap-1: #4d2510; --heatmap-2: #7a3a18;
|
|
9
|
+
--heatmap-3: #b05628; --heatmap-4: #d4784a; --heatmap-5: #f0a070;
|
|
10
|
+
/* Context bar segments */
|
|
11
|
+
--color-cache-read: #4dd0e1; --color-cache-write: #ff8a65; --color-input: #ce93d8;
|
|
12
|
+
/* Section categories */
|
|
13
|
+
--color-system: #1f6feb; --color-system-deep: #1158c7; --color-system-mid: #388bfd;
|
|
14
|
+
--color-system-light: #58a6ff; --color-system-pale: #79c0ff; --color-system-muted: #3d5a8a;
|
|
15
|
+
--color-system-soft: #5d80c8; --color-system-faint: #a5c8ff;
|
|
16
|
+
--color-tools: #2ea043; --color-mcp-tools: #3fb950; --color-messages: #e3b341;
|
|
17
|
+
/* Content types */
|
|
18
|
+
--color-thinking: #ce93d8; --color-tool-use: #ff8a65; --color-tool-result: #4dd0e1;
|
|
19
|
+
/* Diff */
|
|
20
|
+
--color-diff-add: #56d364; --color-diff-del: #f85149;
|
|
21
|
+
}
|
|
22
|
+
[data-theme="light"] {
|
|
23
|
+
--bg: #ffffff; --surface: #f6f8fa; --surface-hover: #eaeef2; --surface-active: #ddf4ff; --border: #d0d7de;
|
|
24
|
+
--text: #1f2328; --dim: #656d76; --accent: #0969da;
|
|
25
|
+
--green: #1a7f37; --yellow: #9a6700; --red: #d1242f;
|
|
26
|
+
--purple: #8250df; --orange: #bc4c00;
|
|
27
|
+
--heatmap-empty: #ebedf0;
|
|
28
|
+
--heatmap-0: #9be9a8; --heatmap-1: #6fdc8c; --heatmap-2: #40c463;
|
|
29
|
+
--heatmap-3: #30a14e; --heatmap-4: #216e39; --heatmap-5: #0e4429;
|
|
30
|
+
--color-cache-read: #0891b2; --color-cache-write: #c2410c; --color-input: #9333ea;
|
|
31
|
+
--color-system: #0969da; --color-system-deep: #0550ae; --color-system-mid: #0969da;
|
|
32
|
+
--color-system-light: #218bff; --color-system-pale: #54aeff; --color-system-muted: #3d5a8a;
|
|
33
|
+
--color-system-soft: #3b82f6; --color-system-faint: #85b8ff;
|
|
34
|
+
--color-tools: #1a7f37; --color-mcp-tools: #2da44e; --color-messages: #9a6700;
|
|
35
|
+
--color-thinking: #8250df; --color-tool-use: #bc4c00; --color-tool-result: #0891b2;
|
|
36
|
+
--color-diff-add: #1a7f37; --color-diff-del: #d1242f;
|
|
37
|
+
}
|
|
38
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
39
|
+
body {
|
|
40
|
+
font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', monospace;
|
|
41
|
+
font-size: 13px; background: var(--bg); color: var(--text);
|
|
42
|
+
height: 100vh; display: flex; flex-direction: column; overflow: hidden;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── Miller Columns Layout ── */
|
|
46
|
+
#app { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
|
|
47
|
+
#topbar { border-bottom: 1px solid var(--border); flex-shrink: 0; }
|
|
48
|
+
#topbar-row1 { display: flex; align-items: center; gap: 12px; padding: 6px 16px; }
|
|
49
|
+
#topbar-row1 h1 { font-size: 15px; color: var(--accent); display: flex; align-items: center; gap: 8px; white-space: nowrap; margin: 0; }
|
|
50
|
+
h1 .dot { width: 8px; height: 8px; background: var(--green); border-radius: 50%; animation: pulse 2s infinite; }
|
|
51
|
+
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
52
|
+
#topbar-tabs { display: flex; gap: 2px; margin-left: 4px; }
|
|
53
|
+
.topbar-tab { background: none; border: none; border-bottom: 2px solid transparent; color: var(--dim); padding: 4px 10px; font-size: 12px; font-family: inherit; cursor: pointer; white-space: nowrap; display: flex; align-items: center; transition: color 0.15s, border-color 0.15s; outline: none; }
|
|
54
|
+
.topbar-tab:hover { color: var(--text); }
|
|
55
|
+
.topbar-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
|
56
|
+
#status-cluster { margin-left: auto; display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--dim); flex-shrink: 0; }
|
|
57
|
+
#topbar-row1 #theme-toggle { background: none; border: 1px solid var(--border); color: var(--dim); padding: 3px 8px; font-size: 11px; border-radius: 3px; cursor: pointer; flex-shrink: 0; }
|
|
58
|
+
#topbar-row1 #theme-toggle:hover { background: var(--surface-hover); }
|
|
59
|
+
#topbar-row2 { display: flex; align-items: center; padding: 3px 16px 5px; font-size: 12px; border-top: 1px solid var(--border); min-height: 26px; }
|
|
60
|
+
#row2-dashboard, #row2-usage, #row2-sysprompt { display: flex; align-items: center; gap: 8px; width: 100%; }
|
|
61
|
+
#breadcrumb { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 120px; flex: 1; }
|
|
62
|
+
#breadcrumb .bc-seg { cursor: pointer; transition: color 0.1s; }
|
|
63
|
+
#breadcrumb .bc-seg:hover { color: var(--accent); }
|
|
64
|
+
#breadcrumb .bc-sep { color: var(--border); margin: 0 2px; cursor: default; }
|
|
65
|
+
#copy-link-btn { background: none; border: none; color: var(--dim); cursor: pointer; font-size: 12px; padding: 2px 4px; flex-shrink: 0; }
|
|
66
|
+
#copy-link-btn:hover { color: var(--text); }
|
|
67
|
+
#quota-ticker { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
|
|
68
|
+
#qt-bar-wrap { display: flex; align-items: center; gap: 5px; }
|
|
69
|
+
.qt-bar-track { width: 80px; height: 7px; background: var(--border); border-radius: 4px; overflow: hidden; }
|
|
70
|
+
#qt-bar-fill { height: 100%; width: 0%; background: var(--green); border-radius: 4px; transition: width 0.5s, background 0.5s; }
|
|
71
|
+
#qt-bar-pct, #qt-bar-time { font-size: 10px; color: var(--dim); }
|
|
72
|
+
#qt-roi { font-size: 10px; color: var(--green); cursor: pointer; padding: 2px 6px; border: 1px solid var(--green); border-radius: 10px; }
|
|
73
|
+
#qt-roi:hover { background: rgba(63,185,80,0.1); }
|
|
74
|
+
#qt-chip { font-size: 10px; color: var(--dim); }
|
|
75
|
+
#row2-usage span, #row2-sysprompt span { font-size: 11px; color: var(--dim); }
|
|
76
|
+
|
|
77
|
+
#columns { display: flex; flex: 1; overflow: hidden; }
|
|
78
|
+
.col { overflow-y: auto; overflow-x: hidden; border-right: 1px solid var(--border); flex-shrink: 0; min-width: 0; border-top: 2px solid transparent; transition: border-top-color 0.15s; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
|
|
79
|
+
.col::-webkit-scrollbar { width: 4px; }
|
|
80
|
+
.col::-webkit-scrollbar-track { background: transparent; }
|
|
81
|
+
.col::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
|
82
|
+
.col::-webkit-scrollbar-thumb:hover { background: var(--dim); }
|
|
83
|
+
.col.col-focused { border-top-color: var(--accent); }
|
|
84
|
+
.col:last-child { border-right: none; flex: 1; }
|
|
85
|
+
|
|
86
|
+
/* Focused mode: collapse all columns except detail */
|
|
87
|
+
#columns.focused #col-projects,
|
|
88
|
+
#columns.focused #col-sessions,
|
|
89
|
+
#columns.focused #col-turns,
|
|
90
|
+
#columns.focused #col-sections { display: none; }
|
|
91
|
+
#columns.focused #col-detail { flex: 1; }
|
|
92
|
+
|
|
93
|
+
/* Expand button in detail header */
|
|
94
|
+
.expand-btn { cursor: pointer; color: var(--dim); font-size: 14px; padding: 2px 4px; border-radius: 3px; transition: color 0.1s, background 0.1s; }
|
|
95
|
+
.expand-btn:hover { color: var(--text); background: var(--surface-hover); }
|
|
96
|
+
|
|
97
|
+
/* Timeline accordion in detail */
|
|
98
|
+
.tl-step { border-bottom: none; }
|
|
99
|
+
.tl-step-summary { cursor: pointer; padding: 4px 8px; transition: background 0.1s; }
|
|
100
|
+
.tl-step-summary:hover { background: var(--surface-hover); }
|
|
101
|
+
.tl-step-summary.active { background: var(--surface-active); box-shadow: inset 3px 0 0 0 var(--accent); }
|
|
102
|
+
.tool-call-error { background: rgba(248,81,73,0.12); border-left: 2px solid var(--red); }
|
|
103
|
+
.tl-step-detail { padding: 8px 12px; border-top: 1px solid var(--border); background: var(--bg); }
|
|
104
|
+
|
|
105
|
+
/* Timeline split pane in focused mode */
|
|
106
|
+
.tl-split { display: flex; flex: 1; overflow: hidden; }
|
|
107
|
+
.tl-split-list { width: 280px; min-width: 200px; max-width: 400px; flex-shrink: 0; overflow-y: auto; border-right: 1px solid var(--border); scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
|
|
108
|
+
.tl-split-detail { flex: 1; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
|
|
109
|
+
|
|
110
|
+
/* Token minimap — vertical color strip beside timeline */
|
|
111
|
+
.tl-with-minimap { display: flex; flex: 1; overflow: hidden; }
|
|
112
|
+
.tl-scroll-area { flex: 1; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; scroll-padding-block: 40px; }
|
|
113
|
+
.minimap { width: 36px; flex-shrink: 0; position: relative; border-right: 1px solid var(--border); background: var(--bg); overflow: hidden; cursor: pointer; }
|
|
114
|
+
.minimap-cache-bar { display: flex; height: 4px; width: 100%; flex-shrink: 0; }
|
|
115
|
+
.minimap-cache-bar > div { min-width: 1px; }
|
|
116
|
+
.minimap-blocks { width: 100%; opacity: 0.5; transition: opacity 0.25s ease; }
|
|
117
|
+
.minimap:hover .minimap-blocks { opacity: 1; }
|
|
118
|
+
.minimap-block { width: 100%; transition: opacity 0.15s; position: relative; }
|
|
119
|
+
.minimap-block.mm-active { opacity: 1 !important; filter: brightness(1.8); outline: 1px solid var(--text); z-index: 1; }
|
|
120
|
+
.minimap-block.mm-highlight { filter: brightness(2); z-index: 1; box-shadow: 0 0 0 1px var(--text); }
|
|
121
|
+
.minimap-empty { width: 100%; }
|
|
122
|
+
.minimap-usage { position: absolute; bottom: 2px; left: 0; right: 0; text-align: center; font-size: 9px; color: var(--dim); opacity: 0; transition: opacity 0.25s; pointer-events: none; }
|
|
123
|
+
.minimap:hover .minimap-usage { opacity: 1; }
|
|
124
|
+
.tl-step-summary.mm-hover { background: var(--surface-hover); outline: 1px solid var(--border); outline-offset: -1px; }
|
|
125
|
+
[data-theme="light"] .minimap-cache-bar > div { opacity: 0.8; }
|
|
126
|
+
#col-projects { width: 220px; }
|
|
127
|
+
#col-sessions { width: 220px; }
|
|
128
|
+
|
|
129
|
+
.project-item { padding: 7px 10px; cursor: pointer; border-left: 3px solid transparent; border-bottom: 1px solid var(--border); }
|
|
130
|
+
.project-item:hover { background: var(--surface-hover); }
|
|
131
|
+
.project-item.selected { border-left-color: var(--accent); background: var(--surface-active); }
|
|
132
|
+
.project-item .pi-name { font-size: 12px; color: var(--text); font-weight: bold; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
133
|
+
.project-item .pi-name.all { color: var(--dim); font-weight: normal; }
|
|
134
|
+
.project-item .pi-meta { font-size: 11px; color: var(--dim); margin-top: 2px; }
|
|
135
|
+
.project-item .pi-cost { color: var(--yellow); }
|
|
136
|
+
.project-item .pi-range { font-size: 10px; color: var(--dim); margin-top: 1px; }
|
|
137
|
+
#col-turns { width: 220px; position: relative; }
|
|
138
|
+
#col-sections { width: 220px; }
|
|
139
|
+
|
|
140
|
+
.col-empty { color: var(--dim); text-align: center; padding: 40px 12px; font-size: 12px; }
|
|
141
|
+
.col-title { padding: 10px 12px; font-size: 10px; font-weight: 600; color: var(--dim); letter-spacing: 0.08em; text-transform: uppercase; border-bottom: 2px solid var(--border); position: sticky; top: 0; background: var(--surface); z-index: 1; }
|
|
142
|
+
|
|
143
|
+
/* ── Status dots ── */
|
|
144
|
+
.sdot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 5px; flex-shrink: 0; vertical-align: middle; border: none; background: none; padding: 0; outline: none; cursor: default; }
|
|
145
|
+
.sdot-stream { background: var(--green); }
|
|
146
|
+
.sdot-idle { background: var(--yellow); }
|
|
147
|
+
.sdot-off { background: transparent; border: 1px solid var(--border); }
|
|
148
|
+
.sdot-armed { box-shadow: 0 0 0 3px rgba(210, 153, 34, 0.5); cursor: pointer; }
|
|
149
|
+
.sdot-armed:hover { box-shadow: 0 0 0 3px rgba(210, 153, 34, 0.9); }
|
|
150
|
+
.sdot-stream:not(.sdot-armed):hover, .sdot-idle:not(.sdot-armed):hover { box-shadow: 0 0 0 3px rgba(210, 153, 34, 0.25); cursor: pointer; }
|
|
151
|
+
|
|
152
|
+
/* ── Session items ── */
|
|
153
|
+
.session-item { padding: 8px 10px; cursor: pointer; border-left: 3px solid transparent; border-bottom: 1px solid var(--border); }
|
|
154
|
+
.session-item:hover { background: var(--surface-hover); }
|
|
155
|
+
.session-item.selected { border-left-color: var(--purple); background: var(--surface-active); }
|
|
156
|
+
.session-item .si-row1 { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3px; }
|
|
157
|
+
.session-item .sid { color: var(--purple); font-size: 12px; font-weight: bold; }
|
|
158
|
+
.session-item .si-row2 { font-size: 11px; color: var(--text); margin-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
|
|
159
|
+
.session-item .si-row3 { display: flex; justify-content: space-between; font-size: 11px; color: var(--dim); }
|
|
160
|
+
.session-item .si-cost { color: var(--yellow); }
|
|
161
|
+
.ctx-alert { font-size: 10px; font-weight: bold; }
|
|
162
|
+
.ctx-alert-yellow { color: var(--yellow); }
|
|
163
|
+
.ctx-alert-red { color: var(--red); }
|
|
164
|
+
.launch-btn { background: none; border: 1px solid var(--border); color: var(--green); width: 18px; height: 18px; border-radius: 50%; cursor: pointer; font-size: 10px; display: inline-flex; align-items: center; justify-content: center; padding: 0; flex-shrink: 0; }
|
|
165
|
+
.launch-btn:hover { background: var(--green); color: #000; border-color: var(--green); }
|
|
166
|
+
.pin-btn { background: none; border: none; color: var(--dim); cursor: pointer; font-size: 11px; padding: 0 2px; opacity: 0.3; transition: opacity 0.15s, color 0.15s; margin-left: auto; flex-shrink: 0; }
|
|
167
|
+
.pin-btn:hover { opacity: 1; color: var(--yellow); }
|
|
168
|
+
.pin-btn.pinned { opacity: 1; color: var(--yellow); }
|
|
169
|
+
|
|
170
|
+
/* ── Turn items ── */
|
|
171
|
+
.turn-item { padding: 7px 10px; cursor: pointer; border-left: 3px solid transparent; border-bottom: 1px solid var(--border); }
|
|
172
|
+
.turn-item:hover { background: var(--surface-hover); }
|
|
173
|
+
.turn-item.selected { border-left-color: var(--accent); background: var(--surface-hover); }
|
|
174
|
+
.turn-item .turn-line1 { display: flex; gap: 6px; align-items: center; font-size: 12px; }
|
|
175
|
+
.turn-item .turn-num { color: var(--dim); }
|
|
176
|
+
.turn-item .turn-model { color: var(--purple); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
177
|
+
.turn-item .turn-line2 { display: flex; gap: 6px; font-size: 11px; color: var(--dim); margin-top: 3px; flex-wrap: wrap; }
|
|
178
|
+
.turn-item .status-ok { color: var(--green); }
|
|
179
|
+
.turn-item .status-err { color: var(--red); }
|
|
180
|
+
.turn-item .turn-cost { color: var(--yellow); }
|
|
181
|
+
.turn-item .turn-line3 { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 2px; }
|
|
182
|
+
.tool-chip { font-size: 9px; color: var(--dim); background: var(--bg2, var(--surface-hover)); border-radius: 3px; padding: 0 3px; }
|
|
183
|
+
.turn-item .turn-title { font-size: 11px; color: var(--text); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
184
|
+
.compact-badge { font-size: 9px; color: var(--red); border: 1px solid var(--red); border-radius: 2px; padding: 0 3px; margin-left: 4px; opacity: 0.85; flex-shrink: 0; }
|
|
185
|
+
.turn-sub { opacity: 0.7; border-left-color: transparent !important; }
|
|
186
|
+
.turn-sub:hover { opacity: 1; }
|
|
187
|
+
.turn-sub.selected { opacity: 1; border-left-color: var(--orange) !important; }
|
|
188
|
+
.sub-indent { color: var(--dim); margin-right: 2px; user-select: none; }
|
|
189
|
+
.tool-chip.chip-agent { color: var(--orange); }
|
|
190
|
+
.si-tools { font-size: 10px; color: var(--dim); margin: 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
191
|
+
.col-sticky-header { position: sticky; top: 0; z-index: 2; background: var(--surface); }
|
|
192
|
+
#scroll-toggle { user-select: none; }
|
|
193
|
+
#scroll-toggle .scroll-on, #scroll-toggle .scroll-off { padding: 1px 4px; border-radius: 3px; color: var(--dim); }
|
|
194
|
+
#scroll-toggle .scroll-on.active { color: var(--green); background: rgba(63,185,80,0.15); }
|
|
195
|
+
#scroll-toggle .scroll-off.active { color: var(--red); background: rgba(248,81,73,0.15); }
|
|
196
|
+
#session-tool-bar { padding: 4px 10px; font-size: 10px; color: var(--dim); border-bottom: 1px solid var(--border); display: flex; flex-wrap: nowrap; gap: 4px; align-items: center; overflow: hidden; white-space: nowrap; }
|
|
197
|
+
.turn-ctx-bar { margin-top: 3px; }
|
|
198
|
+
.turn-ctx-bar-bg { height: 3px; border-radius: 1.5px; background: var(--border); overflow: hidden; display: flex; }
|
|
199
|
+
.turn-ctx-pct { font-size: 9px; color: var(--dim); margin-top: 1px; text-align: right; line-height: 1; }
|
|
200
|
+
#ctx-legend { padding: 3px 10px 4px; border-bottom: 1px solid var(--border); display: flex; gap: 8px; align-items: center; font-size: 9px; color: var(--dim); }
|
|
201
|
+
.ctx-legend-dot { display: inline-block; width: 7px; height: 7px; border-radius: 1px; margin-right: 2px; vertical-align: middle; }
|
|
202
|
+
#session-sparkline { padding: 6px 10px; border-bottom: 1px solid var(--border); display: none; }
|
|
203
|
+
#session-sparkline svg { width: 100%; height: 56px; }
|
|
204
|
+
|
|
205
|
+
/* ── Scorecard hover card ── */
|
|
206
|
+
.scorecard-tooltip { position: absolute; right: 100%; top: 0; margin-right: 4px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px; font-size: 10px; z-index: 10; width: 180px; box-shadow: 0 4px 12px rgba(0,0,0,0.4); pointer-events: none; }
|
|
207
|
+
.scorecard-tooltip .sc-row { display: flex; justify-content: space-between; margin-bottom: 3px; }
|
|
208
|
+
.scorecard-tooltip .sc-label { color: var(--dim); }
|
|
209
|
+
.scorecard-tooltip .sc-value { color: var(--text); font-weight: bold; }
|
|
210
|
+
.scorecard-tooltip .sc-bar { height: 4px; border-radius: 2px; background: var(--border); margin-bottom: 4px; }
|
|
211
|
+
.scorecard-tooltip .sc-bar-fill { height: 100%; border-radius: 2px; }
|
|
212
|
+
|
|
213
|
+
/* ── Sections column ── */
|
|
214
|
+
.col-header { padding: 10px 12px; border-bottom: 2px solid var(--border); background: var(--surface); position: sticky; top: 0; z-index: 1; }
|
|
215
|
+
.col-header .ch-line1 { font-size: 12px; margin-bottom: 4px; }
|
|
216
|
+
.col-header .ch-line2 { font-size: 11px; color: var(--dim); }
|
|
217
|
+
.section-item { padding: 8px 12px; cursor: pointer; border-left: 3px solid transparent; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 6px; }
|
|
218
|
+
.section-item:hover { background: var(--surface-hover); }
|
|
219
|
+
.section-item.selected { border-left-color: var(--accent); background: var(--surface-hover); }
|
|
220
|
+
.section-item .si-name { font-size: 12px; flex: 1; }
|
|
221
|
+
.section-item .si-badge { font-size: 11px; color: var(--dim); background: var(--border); padding: 1px 5px; border-radius: 3px; white-space: nowrap; }
|
|
222
|
+
.section-item .si-arrow { color: var(--dim); font-size: 11px; flex-shrink: 0; }
|
|
223
|
+
.section-group-title { padding: 6px 12px 2px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--dim); border-top: 1px solid var(--border); }
|
|
224
|
+
.section-group-title:first-child { border-top: none; }
|
|
225
|
+
|
|
226
|
+
/* ── Detail column ── */
|
|
227
|
+
#col-detail { display: flex; flex-direction: column; overflow: hidden; transition: opacity 0.15s ease; }
|
|
228
|
+
.new-turn-pill {
|
|
229
|
+
position: sticky;
|
|
230
|
+
bottom: 12px;
|
|
231
|
+
align-self: center;
|
|
232
|
+
margin: 0 auto;
|
|
233
|
+
display: block;
|
|
234
|
+
width: fit-content;
|
|
235
|
+
background: var(--accent);
|
|
236
|
+
color: var(--bg);
|
|
237
|
+
padding: 3px 12px;
|
|
238
|
+
border-radius: 12px;
|
|
239
|
+
font-size: 11px;
|
|
240
|
+
cursor: pointer;
|
|
241
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
242
|
+
z-index: 10;
|
|
243
|
+
animation: slideUp 0.3s ease;
|
|
244
|
+
}
|
|
245
|
+
@keyframes slideUp {
|
|
246
|
+
from { transform: translateX(-50%) translateY(10px); opacity: 0; }
|
|
247
|
+
to { transform: translateX(-50%) translateY(0); opacity: 1; }
|
|
248
|
+
}
|
|
249
|
+
.ctx-sticky { position: sticky; top: 0; background: var(--surface); border-bottom: 2px solid var(--border); padding: 10px 12px; z-index: 2; flex-shrink: 0; }
|
|
250
|
+
.ctx-sticky-title { font-size: 11px; color: var(--dim); margin-bottom: 6px; }
|
|
251
|
+
.detail-scroll { flex: 1; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
|
|
252
|
+
.detail-scroll::-webkit-scrollbar { width: 4px; }
|
|
253
|
+
.detail-scroll::-webkit-scrollbar-track { background: transparent; }
|
|
254
|
+
.detail-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
|
255
|
+
.detail-scroll::-webkit-scrollbar-thumb:hover { background: var(--dim); }
|
|
256
|
+
.detail-content { padding: 12px; }
|
|
257
|
+
|
|
258
|
+
/* ── Shared content styles ── */
|
|
259
|
+
.section { border-bottom: 1px solid var(--border); }
|
|
260
|
+
.section:last-child { border-bottom: none; }
|
|
261
|
+
.section-header { padding: 8px 14px; cursor: pointer; color: var(--accent); font-size: 12px; user-select: none; display: flex; align-items: center; gap: 6px; }
|
|
262
|
+
.section-header:hover { background: var(--surface-hover); }
|
|
263
|
+
.section-header .arrow { color: var(--dim); font-size: 10px; transition: transform 0.15s; }
|
|
264
|
+
.section-header.open .arrow { transform: rotate(90deg); }
|
|
265
|
+
.section-header .badge { background: var(--border); color: var(--dim); padding: 1px 6px; border-radius: 4px; font-size: 11px; }
|
|
266
|
+
.section-content { display: none; padding: 8px 14px; overflow: auto; }
|
|
267
|
+
.section-content.open { display: block; }
|
|
268
|
+
pre { white-space: pre-wrap; word-break: break-all; font-size: 12px; line-height: 1.5; }
|
|
269
|
+
.msg { margin-bottom: 8px; padding: 8px; border-radius: 4px; border: 1px solid var(--border); }
|
|
270
|
+
.msg-role { font-size: 11px; font-weight: bold; margin-bottom: 4px; }
|
|
271
|
+
.msg-role.user { color: var(--accent); }
|
|
272
|
+
.msg-role.assistant { color: var(--green); }
|
|
273
|
+
.tool-grid { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
274
|
+
.tool-tag { background: var(--border); padding: 2px 8px; border-radius: 4px; font-size: 11px; color: var(--dim); }
|
|
275
|
+
.content-block { margin-bottom: 6px; padding: 6px 8px; background: var(--bg); border-radius: 4px; }
|
|
276
|
+
.content-block .type { font-size: 11px; color: var(--yellow); margin-bottom: 2px; }
|
|
277
|
+
.msg-list-row { display: flex; align-items: baseline; gap: 4px; font-size: 11px; line-height: 1.4; }
|
|
278
|
+
.msg-list-idx { flex-shrink: 0; color: var(--dim); }
|
|
279
|
+
.msg-list-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
|
|
280
|
+
.msg-list-tok { flex-shrink: 0; font-size: 10px; color: var(--dim); margin-left: auto; }
|
|
281
|
+
.msg-thinking-line { font-size: 10px; color: var(--purple); opacity: 0.75; margin-top: 3px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.5; }
|
|
282
|
+
.section-item.has-thinking { flex-direction: column; align-items: stretch; }
|
|
283
|
+
.msg-badge { font-size: 9px; font-weight: bold; padding: 0 4px; border-radius: 3px; flex-shrink: 0; letter-spacing: 0.03em; }
|
|
284
|
+
.msg-badge-human { background: var(--accent); color: var(--bg); }
|
|
285
|
+
.msg-badge-tool_results { background: var(--border); color: var(--dim); }
|
|
286
|
+
.msg-badge-system { background: var(--yellow); color: var(--bg); }
|
|
287
|
+
.msg-badge-call { background: var(--green); color: var(--bg); }
|
|
288
|
+
.msg-badge-think { background: var(--purple); color: var(--bg); }
|
|
289
|
+
|
|
290
|
+
/* ── Sysprompt Diff UI ── */
|
|
291
|
+
.sysprompt-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: var(--accent); cursor: pointer; padding: 2px 5px; border: 1px solid var(--accent); border-radius: 3px; margin-bottom: 4px; }
|
|
292
|
+
.sysprompt-badge:hover { background: rgba(77,208,225,0.1); }
|
|
293
|
+
.version-banner { background: var(--surface-hover); border-bottom: 1px solid var(--accent); padding: 6px 12px; font-size: 11px; color: var(--text); display: flex; align-items: center; gap: 8px; }
|
|
294
|
+
.version-banner .vb-dot { color: var(--accent); }
|
|
295
|
+
.version-banner .vb-ver { color: var(--purple); font-weight: bold; }
|
|
296
|
+
.version-banner .vb-delta { color: var(--green); }
|
|
297
|
+
.version-banner .vb-view { color: var(--accent); cursor: pointer; text-decoration: underline; }
|
|
298
|
+
.version-banner .vb-close { margin-left: auto; cursor: pointer; color: var(--dim); }
|
|
299
|
+
|
|
300
|
+
/* ── Intercept UI ── */
|
|
301
|
+
.held-badge { font-size: 9px; font-weight: bold; color: #fff; background: var(--red); padding: 0 5px; border-radius: 3px; margin-left: auto; flex-shrink: 0; cursor: pointer; animation: held-pulse 1.5s ease-in-out infinite; }
|
|
302
|
+
@keyframes held-pulse { 50% { opacity: 0.7; } }
|
|
303
|
+
#topbar-held { font-size: 10px; color: var(--bg); background: var(--yellow); cursor: pointer; padding: 1px 8px; border-radius: 10px; font-weight: 600; display: none; animation: held-pulse 1.5s ease-in-out infinite; }
|
|
304
|
+
#topbar-held:hover { opacity: 0.85; }
|
|
305
|
+
|
|
306
|
+
.intercept-overlay { position: absolute; inset: 0; z-index: 100; background: var(--surface); display: flex; flex-direction: column; border-left: 2px solid var(--yellow); }
|
|
307
|
+
.intercept-header { padding: 10px 14px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 8px; }
|
|
308
|
+
.intercept-header .ih-title { font-size: 12px; color: var(--yellow); font-weight: bold; flex: 1; }
|
|
309
|
+
.intercept-header .ih-session { font-size: 11px; color: var(--dim); }
|
|
310
|
+
.intercept-tabs { display: flex; border-bottom: 1px solid var(--border); padding: 0 10px; }
|
|
311
|
+
.intercept-tab { padding: 6px 12px; font-size: 11px; color: var(--dim); cursor: pointer; border-bottom: 2px solid transparent; }
|
|
312
|
+
.intercept-tab:hover { color: var(--text); }
|
|
313
|
+
.intercept-tab.active { color: var(--yellow); border-bottom-color: var(--yellow); }
|
|
314
|
+
.intercept-editor { flex: 1; overflow: auto; padding: 10px 14px; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
|
|
315
|
+
.intercept-editor::-webkit-scrollbar { width: 4px; }
|
|
316
|
+
.intercept-editor::-webkit-scrollbar-track { background: transparent; }
|
|
317
|
+
.intercept-editor::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
|
318
|
+
.intercept-editor textarea { width: 100%; min-height: 120px; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 8px; font-family: inherit; font-size: 12px; resize: vertical; }
|
|
319
|
+
.intercept-editor textarea:focus { outline: none; border-color: var(--yellow); }
|
|
320
|
+
.intercept-editor select { background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 4px 8px; font-family: inherit; font-size: 12px; }
|
|
321
|
+
.intercept-summary { padding: 6px 14px; font-size: 11px; color: var(--dim); border-top: 1px solid var(--border); }
|
|
322
|
+
.intercept-countdown { height: 4px; background: var(--bg); flex-shrink: 0; }
|
|
323
|
+
.intercept-countdown-bar { height: 100%; transition: width 1s linear, background-color 0.5s; border-radius: 2px; }
|
|
324
|
+
.intercept-actions { padding: 10px 14px; border-top: 1px solid var(--border); display: flex; gap: 8px; justify-content: flex-end; }
|
|
325
|
+
.intercept-actions button { padding: 5px 16px; border-radius: 4px; cursor: pointer; font-family: inherit; font-size: 12px; border: 1px solid var(--border); }
|
|
326
|
+
.intercept-actions .btn-reject { background: transparent; color: var(--red); border-color: var(--red); }
|
|
327
|
+
.intercept-actions .btn-reject:hover { background: rgba(248, 81, 73, 0.15); }
|
|
328
|
+
.intercept-actions .btn-approve { background: var(--green); color: #000; border-color: var(--green); font-weight: bold; }
|
|
329
|
+
.intercept-actions .btn-approve:hover { opacity: 0.9; }
|
|
330
|
+
.ie-msg { padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px; margin-bottom: 6px; cursor: pointer; }
|
|
331
|
+
.ie-msg:hover { background: var(--surface-hover); }
|
|
332
|
+
.ie-msg .ie-msg-role { font-size: 11px; font-weight: bold; margin-bottom: 2px; }
|
|
333
|
+
.ie-msg .ie-msg-role.user { color: var(--accent); }
|
|
334
|
+
.ie-msg .ie-msg-role.assistant { color: var(--green); }
|
|
335
|
+
.ie-msg .ie-msg-preview { font-size: 11px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
336
|
+
.ie-msg.expanded textarea { margin-top: 6px; }
|
|
337
|
+
.ie-tool-item { display: flex; align-items: center; gap: 6px; padding: 4px 0; font-size: 12px; }
|
|
338
|
+
.ie-tool-item label { cursor: pointer; flex: 1; }
|
|
339
|
+
.ie-tool-item input[type=checkbox] { accent-color: var(--yellow); }
|
|
340
|
+
|
|
341
|
+
/* ── Fullscreen Page Shell ── */
|
|
342
|
+
.fullscreen-page { display: none; flex: 1; background: var(--bg); flex-direction: column; overflow: hidden; }
|
|
343
|
+
.fullscreen-page.open { display: flex; }
|
|
344
|
+
.fullscreen-page > .fp-header { display: none; }
|
|
345
|
+
.fp-back, .fp-close { background: none; border: none; color: var(--dim); cursor: pointer; font-size: 14px; padding: 4px 8px; flex-shrink: 0; }
|
|
346
|
+
.fp-back:hover, .fp-close:hover { color: var(--text); }
|
|
347
|
+
.fp-close { margin-left: auto; }
|
|
348
|
+
.fp-title { font-size: 14px; font-weight: 600; color: var(--text); }
|
|
349
|
+
.fp-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
|
|
350
|
+
.fp-actions + .fp-close { margin-left: 0; }
|
|
351
|
+
.fp-toolbar { padding: 8px 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
352
|
+
.fp-content { flex: 1; overflow-y: auto; padding: 20px; }
|
|
353
|
+
|
|
354
|
+
/* ── Fullscreen Page: Cost-specific responsive ── */
|
|
355
|
+
.cost-layout { display: flex; gap: 16px; align-items: flex-start; max-width: 960px; margin: 0 auto; }
|
|
356
|
+
.cost-left { flex: 1; min-width: 280px; max-width: 360px; display: flex; flex-direction: column; gap: 12px; }
|
|
357
|
+
.cost-right { flex: 2; min-width: 320px; }
|
|
358
|
+
.cost-card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 14px; }
|
|
359
|
+
.cost-card-label { font-size: 10px; color: var(--dim); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
360
|
+
|
|
361
|
+
/* ── Fullscreen Page: Changelog-specific ── */
|
|
362
|
+
.sp-changelog-body { display: flex; flex: 1; overflow: hidden; }
|
|
363
|
+
.sp-version-list { width: 240px; flex-shrink: 0; border-right: 1px solid var(--border); overflow-y: auto; padding: 8px 0; }
|
|
364
|
+
.sp-version-list-title { font-size: 10px; color: var(--dim); text-transform: uppercase; letter-spacing: 0.05em; padding: 4px 12px 8px; }
|
|
365
|
+
.sp-version-item { padding: 6px 12px; font-size: 11px; color: var(--dim); cursor: pointer; display: grid; grid-template-columns: 36px 1fr auto auto; gap: 4px; align-items: center; border-left: 3px solid transparent; white-space: nowrap; }
|
|
366
|
+
.sp-version-item:hover { background: var(--surface-hover); color: var(--text); }
|
|
367
|
+
.sp-version-item.active { border-left-color: var(--accent); color: var(--text); background: var(--surface-active); }
|
|
368
|
+
.sp-content-area { flex: 1; overflow-y: auto; padding: 12px 16px; }
|
|
369
|
+
.sp-status-bar { padding: 6px 16px; font-size: 10px; color: var(--dim); border-top: 1px solid var(--border); flex-shrink: 0; }
|
|
370
|
+
|
|
371
|
+
@media (max-width: 1023px) {
|
|
372
|
+
.cost-layout { flex-direction: column; }
|
|
373
|
+
.cost-left { max-width: none; flex-direction: row; gap: 12px; flex-wrap: wrap; }
|
|
374
|
+
.cost-left > * { flex: 1; min-width: 240px; }
|
|
375
|
+
.cost-right { min-width: 0; }
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/* ── iPad (768–1024px): narrower version list ── */
|
|
379
|
+
@media (max-width: 1024px) and (min-width: 768px) {
|
|
380
|
+
.sp-version-list { width: 160px; }
|
|
381
|
+
.sp-version-item { grid-template-columns: 36px 1fr; }
|
|
382
|
+
.sp-version-item .sp-size-col,
|
|
383
|
+
.sp-version-item .sp-delta-col { display: none; }
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/* ── iPhone (<768px): push/pop navigation ── */
|
|
387
|
+
@media (max-width: 767px) {
|
|
388
|
+
.sp-changelog-body { flex-direction: column; position: relative; }
|
|
389
|
+
.sp-version-list { width: 100%; border-right: none; border-bottom: 1px solid var(--border); }
|
|
390
|
+
.sp-version-item { grid-template-columns: 36px 1fr auto auto; }
|
|
391
|
+
.sp-content-area { width: 100%; display: none; }
|
|
392
|
+
.sp-changelog-body.sp-mobile-detail .sp-version-list { display: none; }
|
|
393
|
+
.sp-changelog-body.sp-mobile-detail .sp-content-area { display: block; flex: 1; }
|
|
394
|
+
}
|
|
395
|
+
@media (max-width: 599px) {
|
|
396
|
+
.fp-content { padding: 12px; }
|
|
397
|
+
.cost-left { flex-direction: column; }
|
|
398
|
+
.cost-left > * { min-width: 0; }
|
|
399
|
+
.cost-card { border: none; border-radius: 0; border-bottom: 1px solid var(--border); }
|
|
400
|
+
.cost-right .cost-card { overflow-x: auto; }
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* ── Toast Notifications ── */
|
|
404
|
+
#toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 200; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
|
|
405
|
+
.toast { pointer-events: auto; background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--yellow); color: var(--text); padding: 10px 14px; border-radius: 4px; font-size: 12px; max-width: 400px; cursor: pointer; animation: toast-in 0.3s ease-out; line-height: 1.5; }
|
|
406
|
+
.toast.fade-out { animation: toast-out 0.3s ease-in forwards; }
|
|
407
|
+
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
408
|
+
@keyframes toast-out { from { opacity: 1; } to { opacity: 0; transform: translateY(10px); } }
|
|
409
|
+
|
|
410
|
+
/* ── Detail Panel: Tool-Specific Rendering ── */
|
|
411
|
+
.detail-tool-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border); margin-bottom: 8px; }
|
|
412
|
+
.detail-tool-title { font-size: 13px; font-weight: bold; display: flex; align-items: center; gap: 6px; }
|
|
413
|
+
.detail-meta { padding: 4px 0; font-size: 12px; color: var(--dim); }
|
|
414
|
+
.detail-meta code { color: var(--accent); background: var(--bg); padding: 1px 4px; border-radius: 2px; font-size: 11px; }
|
|
415
|
+
.detail-meta-line { font-size: 11px; color: var(--dim); margin-top: 2px; }
|
|
416
|
+
.detail-tag { font-size: 9px; background: var(--border); color: var(--dim); padding: 1px 4px; border-radius: 2px; }
|
|
417
|
+
.detail-cmd-block { background: var(--bg); border: 1px solid var(--border); padding: 8px; border-radius: 4px; }
|
|
418
|
+
.detail-collapse-bar { text-align: center; padding: 6px; margin: 4px 0; background: var(--surface); border: 1px dashed var(--border); border-radius: 4px; color: var(--dim); font-size: 11px; cursor: pointer; }
|
|
419
|
+
.detail-collapse-bar:hover { background: var(--surface-hover); color: var(--accent); }
|
|
420
|
+
.detail-diff { border: 1px solid var(--border); border-radius: 4px; overflow: hidden; margin-bottom: 6px; }
|
|
421
|
+
.detail-diff-section { padding: 4px 0; }
|
|
422
|
+
.detail-diff-label { font-size: 10px; color: var(--dim); padding: 2px 8px; font-weight: 600; letter-spacing: 0.05em; }
|
|
423
|
+
.detail-diff-old { background: rgba(248, 81, 73, 0.06); border-bottom: 1px solid var(--border); }
|
|
424
|
+
.detail-diff-new { background: rgba(63, 185, 80, 0.06); }
|
|
425
|
+
.diff-line-del { color: var(--red); }
|
|
426
|
+
.diff-line-add { color: var(--green); }
|
|
427
|
+
.detail-thinking .think-para { margin-bottom: 12px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; font-size: 12px; }
|
|
428
|
+
.detail-copy-btn { background: none; border: 1px solid var(--border); border-radius: 3px; color: var(--dim); cursor: pointer; padding: 2px 6px; font-size: 11px; flex-shrink: 0; }
|
|
429
|
+
.detail-copy-btn:hover { color: var(--text); background: var(--surface); }
|
|
430
|
+
.detail-input-details summary { cursor: pointer; font-size: 11px; color: var(--yellow); margin-bottom: 2px; }
|
|
431
|
+
.detail-input-details { margin-bottom: 6px; padding: 6px 8px; background: var(--bg); border-radius: 4px; }
|