Files
optimclaw/src/channels/web/static/style.css
T
757d24bd90 feat(web): add follow-up suggestion chips and ghost text (#1156)
* feat(web): add follow-up suggestion chips and ghost text to chat UI

The LLM now always generates 1-3 follow-up command suggestions via
<suggestions> tags in its response. These are extracted server-side,
broadcast as SSE events, and rendered as clickable chips above the
chat input. The first suggestion also appears as ghost text in the
input field (Tab to accept). Includes debug logging for LLM responses
in the agentic loop and removes noisy NEAR AI status logging.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: resolve deferred review items from PR #1156 [skip-regression-check]

- Remove literal backslashes from raw string prompt (reasoning.rs)
- Make WASM channels skip Suggestions status (no-op instead of empty callback)
- Add !e.shiftKey guard to Tab-to-accept ghost text handler
- Cap extracted suggestions at 3 and trim whitespace-only entries
- Extract suggestions in approval-resume path (prevents tag leaking)
- Remove stale .has-ghost class during showSuggestionChips reset

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-14 18:57:24 +00:00

4081 lines
72 KiB
CSS

/* IronClaw Web Gateway */
:root {
--bg: #09090b;
--bg-secondary: #0f0f11;
--bg-tertiary: #1a1a1e;
--border: rgba(255, 255, 255, 0.08);
--text: #fafafa;
--text-secondary: #a1a1aa;
--accent: #34d399;
--accent-hover: #2fc48d;
--accent-soft: rgba(52, 211, 153, 0.15);
--success: #34d399;
--warning: #F5A623;
--danger: #E64C4C;
--code-bg: #111113;
--radius: 8px;
--radius-lg: 12px;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
--font-mono: 'IBM Plex Mono', 'SF Mono', 'Fira Code', Consolas, monospace;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg);
color: var(--text);
height: 100vh;
height: 100dvh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* Auth Screen */
#auth-screen {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
height: 100dvh;
}
.auth-card-login {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 16px;
padding: 40px 36px 32px;
width: 100%;
max-width: 400px;
display: flex;
flex-direction: column;
gap: 24px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}
.auth-brand {
text-align: center;
}
.auth-brand h1 {
font-size: 28px;
font-weight: 700;
color: var(--text);
margin-bottom: 4px;
}
.auth-tagline {
font-size: 14px;
color: var(--text-secondary);
}
#auth-screen .auth-form {
display: flex;
flex-direction: column;
gap: 8px;
}
#auth-screen .auth-form label {
font-size: 13px;
font-weight: 500;
color: var(--text-secondary);
}
#auth-screen input {
padding: 10px 12px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 14px;
width: 100%;
}
#auth-screen input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.3);
}
#auth-screen button {
padding: 10px 16px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 14px;
font-weight: 600;
margin-top: 4px;
transition: background 0.2s, transform 0.2s;
}
#auth-screen button:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
#auth-screen button:active {
transform: scale(0.98);
}
#auth-error {
color: var(--danger);
font-size: 13px;
min-height: 20px;
text-align: center;
}
.auth-hint {
font-size: 12px;
color: var(--text-secondary);
text-align: center;
line-height: 1.4;
}
/* Main App */
#app {
display: none;
flex-direction: column;
height: 100vh;
height: 100dvh;
}
/* Tab Bar */
.tab-bar {
display: flex;
background: rgba(9, 9, 11, 0.75);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
will-change: backdrop-filter;
border-bottom: 1px solid var(--border);
padding: 0 16px;
gap: 0;
flex-shrink: 0;
}
.tab-bar button:not(.status-logs-btn):not(.restart-btn) {
padding: 10px 20px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-secondary);
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: color 0.2s, border-color 0.2s;
}
.tab-bar button:not(.status-logs-btn):not(.restart-btn):hover {
color: var(--text);
}
.tab-bar button:not(.status-logs-btn):not(.restart-btn).active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.tab-bar .spacer {
flex: 1;
}
.tab-bar .status-logs-btn {
padding: 4px 10px;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-secondary);
cursor: pointer;
font-size: 11px;
align-self: center;
margin-right: 8px;
transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.tab-bar .status-logs-btn:hover {
color: var(--text);
border-color: var(--text-secondary);
}
.tab-bar .status-logs-btn.active {
color: var(--accent);
border-color: var(--accent);
background: rgba(52, 211, 153, 0.1);
}
.tab-bar .status {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--text-secondary);
position: relative;
cursor: pointer;
}
.tab-bar .status .dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--success);
}
.tab-bar .status .dot.disconnected {
background: var(--danger);
}
/* TEE Shield */
.tee-shield {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--success);
padding: 4px 10px;
border-radius: 12px;
background: rgba(52, 211, 153, 0.1);
border: 1px solid rgba(52, 211, 153, 0.25);
cursor: pointer;
position: relative;
margin-right: 8px;
transition: background 0.2s;
}
.tee-shield:hover {
background: rgba(52, 211, 153, 0.18);
}
.tee-shield svg {
flex-shrink: 0;
}
#tee-shield-label {
font-weight: 500;
white-space: nowrap;
}
/* Restart Button */
.tab-bar .restart-btn {
display: flex;
align-items: center;
gap: 0.375rem;
margin: 0.375rem;
padding: 0.25rem 0.75rem;
border-radius: 0.5rem;
font-size: 0.8rem;
border: 1px solid #00d894;
color: #00d894;
background-color: transparent;
cursor: pointer;
transition: color 150ms, background-color 150ms, border-color 150ms;
}
.tab-bar .restart-btn:hover:not(:disabled) {
background-color: rgba(0, 216, 148, 0.1);
}
.tab-bar .restart-btn:disabled {
border-color: #333;
color: #666;
cursor: not-allowed;
}
.tab-bar .restart-btn:disabled:hover {
background-color: transparent;
}
.tab-bar .restart-btn svg {
flex-shrink: 0;
width: 13px;
height: 13px;
}
.tab-bar .restart-btn svg.spinning {
animation: spin-icon 1s linear infinite;
}
@keyframes spin-icon {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Restart Loader Overlay */
.restart-loader {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.restart-loader-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
z-index: -1;
}
.restart-loader-content {
position: relative;
z-index: 10000;
background-color: #1a1a1a;
border: 1px solid #333;
border-radius: 0.75rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
width: 100%;
max-width: 28rem;
margin: 0 1rem;
overflow: hidden;
padding: 1.25rem;
}
.restart-spinner {
display: none;
}
.restart-loader-text {
padding: 0;
}
.restart-title {
color: #e0e0e0;
font-size: 0.85rem;
margin-bottom: 1rem;
margin-top: 0;
}
.restart-subtitle {
display: none;
}
/* Restart Modal (Confirmation) */
.restart-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.restart-modal-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
}
.restart-modal-content {
position: relative;
z-index: 10000;
background-color: #1a1a1a;
border: 1px solid #333;
border-radius: 0.75rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
width: 100%;
max-width: 28rem;
margin: 0 1rem;
overflow: hidden;
}
.restart-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.25rem;
border-bottom: 1px solid #2a2a2a;
}
.restart-modal-header h2 {
color: #e0e0e0;
font-size: 0.95rem;
margin: 0;
}
.restart-modal-close {
color: #888;
padding: 0.25rem;
border-radius: 0.25rem;
background-color: transparent;
border: none;
cursor: pointer;
transition: color 150ms, background-color 150ms;
display: flex;
align-items: center;
justify-content: center;
}
.restart-modal-close:hover {
color: #ccc;
background-color: #2a2a2a;
}
.restart-modal-body {
padding: 1.25rem;
}
.restart-modal-description {
color: #aaa;
font-size: 0.85rem;
margin: 0;
}
.restart-modal-warning {
margin-top: 1rem;
background-color: #1e1400;
border: 1px solid #3a2a00;
border-radius: 0.5rem;
padding: 0.75rem 1rem;
}
.restart-modal-warning p {
color: #facc15;
font-size: 0.8rem;
margin: 0;
}
.restart-modal-footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 0.75rem;
padding: 1rem 1.25rem;
border-top: 1px solid #2a2a2a;
}
.restart-modal-btn {
padding: 0.5rem 1rem;
border-radius: 0.5rem;
font-size: 0.85rem;
border: none;
cursor: pointer;
transition: background-color 150ms;
}
.restart-modal-btn.cancel {
color: #ccc;
background-color: transparent;
}
.restart-modal-btn.cancel:hover {
background-color: #2a2a2a;
}
.restart-modal-btn.confirm {
background-color: #00D894;
color: #111;
}
.restart-modal-btn.confirm:hover {
background-color: #00be82;
}
/* Progress Bar for Restart */
.restart-progress-bar {
width: 100%;
height: 0.375rem;
background-color: #2a2a2a;
border-radius: 9999px;
overflow: hidden;
}
.restart-progress-fill {
height: 100%;
border-radius: 9999px;
background-color: #00D894;
width: 40%;
animation: indeterminate 1.5s ease-in-out infinite;
}
@keyframes indeterminate {
0% {
margin-left: 0;
width: 40%;
}
50% {
margin-left: 60%;
width: 40%;
}
100% {
margin-left: 0;
width: 40%;
}
}
.restart-modal-info {
color: #666;
font-size: 0.8rem;
margin-top: 1.25rem;
margin-bottom: 0;
}
.restart-modal-info a {
color: #00D894;
text-decoration: none;
}
.restart-modal-info a:hover {
text-decoration: underline;
}
.tee-popover {
display: none;
position: absolute;
top: 100%;
right: 0;
margin-top: 8px;
background: rgba(15, 15, 17, 0.9);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
min-width: 340px;
max-width: 420px;
z-index: 100;
box-shadow: var(--shadow);
}
.tee-popover.visible {
display: block;
}
.tee-popover-title {
font-size: 13px;
font-weight: 600;
color: var(--text);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 6px;
}
.tee-popover-title svg {
color: var(--success);
}
.tee-field {
margin-bottom: 10px;
}
.tee-field:last-child {
margin-bottom: 0;
}
.tee-field-label {
font-size: 11px;
font-weight: 500;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 3px;
}
.tee-field-value {
font-size: 12px;
font-family: var(--font-mono);
color: var(--text);
word-break: break-all;
background: var(--bg);
padding: 4px 8px;
border-radius: var(--radius);
border: 1px solid var(--border);
}
.tee-popover-actions {
margin-top: 12px;
display: flex;
gap: 8px;
}
.tee-btn-copy {
padding: 4px 10px;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-secondary);
cursor: pointer;
font-size: 11px;
transition: color 0.2s, border-color 0.2s;
}
.tee-btn-copy:hover {
color: var(--text);
border-color: var(--text-secondary);
}
.tee-popover-loading {
font-size: 12px;
color: var(--text-secondary);
padding: 8px 0;
}
/* Tab Panels */
.tab-panel {
display: none;
flex: 1;
overflow: hidden;
}
.tab-panel.active {
display: flex;
flex-direction: column;
}
/* Chat Tab */
.chat-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
}
.message {
max-width: 72%;
padding: 10px 14px;
border-radius: var(--radius);
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
position: relative;
}
.message.user {
align-self: flex-end;
background: var(--accent-soft);
color: var(--accent);
border-bottom-right-radius: 2px;
white-space: pre-wrap;
}
.message.assistant {
align-self: flex-start;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-bottom-left-radius: 2px;
padding: 14px 18px;
font-size: 15px;
line-height: 1.6;
}
.message.has-copy {
padding-right: 52px;
}
.message-content {
min-width: 0;
}
.message-copy-btn {
position: absolute;
top: 8px;
right: 8px;
z-index: 2;
border: 1px solid var(--border);
background: var(--bg-primary);
color: var(--text-secondary);
border-radius: 8px;
font-size: 11px;
padding: 2px 8px;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease;
}
.message.user:hover .message-copy-btn,
.message.assistant:hover .message-copy-btn,
.message.user:focus-within .message-copy-btn,
.message.assistant:focus-within .message-copy-btn {
opacity: 1;
pointer-events: auto;
}
.message-copy-btn:focus-visible {
opacity: 1;
pointer-events: auto;
outline: 2px solid var(--accent);
outline-offset: 1px;
}
.message-copy-btn:hover {
background: var(--bg-secondary);
color: var(--text-primary);
}
@media (hover: none) {
.message.user .message-copy-btn,
.message.assistant .message-copy-btn {
opacity: 1;
pointer-events: auto;
}
}
.message.system {
align-self: center;
background: var(--bg-tertiary);
color: var(--text-secondary);
font-size: 12px;
padding: 6px 12px;
}
.message code {
background: var(--code-bg);
padding: 1px 4px;
border-radius: 3px;
font-size: 13px;
}
.message pre {
background: var(--code-bg);
padding: 8px 12px;
border-radius: var(--radius);
overflow-x: auto;
margin: 6px 0;
}
.message pre code {
background: none;
padding: 0;
}
.message p { margin: 0 0 10px 0; }
.message p:last-child { margin-bottom: 0; }
.message ul, .message ol { margin: 4px 0; padding-left: 20px; }
.message li { margin: 4px 0; }
.message blockquote {
margin: 6px 0;
padding: 4px 12px;
border-left: 3px solid var(--border);
color: var(--text-secondary);
}
.message h1, .message h2, .message h3,
.message h4, .message h5, .message h6 {
margin: 8px 0 4px 0;
line-height: 1.3;
}
.message h1 { font-size: 1.3em; }
.message h2 { font-size: 1.2em; }
.message h3 { font-size: 1.1em; }
.message a { color: var(--accent); }
.message hr { border: none; border-top: 1px solid var(--border); margin: 8px 0; }
.message table { border-collapse: collapse; margin: 6px 0; }
.message th, .message td {
border: 1px solid var(--border);
padding: 4px 8px;
font-size: 13px;
}
.message th { background: var(--bg-tertiary); }
/* Status bar */
.scroll-load-spinner {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px;
color: var(--text-secondary);
font-size: 12px;
}
.scroll-load-spinner .spinner {
width: 12px;
height: 12px;
border: 2px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.6s linear infinite;
}
/* === Tool Activity Cards === */
.activity-group {
align-self: flex-start;
max-width: 80%;
padding: 4px 0 4px 12px;
border-left: 2px solid var(--border);
margin: 4px 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.activity-group.collapsed {
border-left-color: transparent;
padding-left: 0;
}
/* Thinking indicator */
.activity-thinking {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
font-size: 13px;
color: var(--text-secondary);
}
.activity-thinking-dots {
display: flex;
gap: 3px;
}
.activity-thinking-dot {
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--text-secondary);
animation: thinkingPulse 1.4s ease-in-out infinite;
}
.activity-thinking-dot:nth-child(2) { animation-delay: 0.2s; }
.activity-thinking-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes thinkingPulse {
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
40% { opacity: 1; transform: scale(1); }
}
.activity-thinking-text {
font-style: italic;
}
/* Tool card */
.activity-tool-card {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
transition: border-color 0.2s;
}
.activity-tool-card[data-status="running"] {
border-color: rgba(52, 211, 153, 0.3);
}
.activity-tool-card[data-status="fail"] {
border-color: rgba(230, 76, 76, 0.3);
}
.activity-tool-card[data-status="fail"] .activity-tool-name {
color: var(--danger);
}
.activity-tool-header {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
cursor: pointer;
user-select: none;
transition: background 0.15s;
}
.activity-tool-header:hover {
background: var(--bg-tertiary);
}
.activity-tool-icon {
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
flex-shrink: 0;
}
.activity-tool-icon .spinner {
width: 12px;
height: 12px;
border: 2px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.6s linear infinite;
}
.activity-icon-success {
color: var(--success);
font-size: 14px;
font-weight: 700;
line-height: 1;
}
.activity-icon-fail {
color: var(--danger);
font-size: 14px;
font-weight: 700;
line-height: 1;
}
.activity-tool-name {
font-size: 13px;
font-family: var(--font-mono);
font-weight: 500;
color: var(--text);
flex: 1;
}
.activity-tool-duration {
font-size: 11px;
font-family: var(--font-mono);
color: var(--text-secondary);
min-width: 36px;
text-align: right;
}
.activity-tool-chevron {
font-size: 10px;
color: var(--text-secondary);
transition: transform 0.15s ease;
width: 12px;
text-align: center;
}
.activity-tool-chevron.expanded {
transform: rotate(90deg);
}
.activity-tool-body {
border-top: 1px solid var(--border);
}
.activity-tool-output {
margin: 0;
padding: 8px 10px;
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.4;
color: var(--text-secondary);
background: var(--code-bg);
max-height: 200px;
overflow-y: auto;
white-space: pre-wrap;
word-break: break-all;
}
/* Collapsed summary */
.activity-summary {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
cursor: pointer;
user-select: none;
font-size: 13px;
color: var(--text-secondary);
border-radius: var(--radius);
transition: background 0.15s;
}
.activity-summary:hover {
background: var(--bg-tertiary);
}
.activity-summary-chevron {
font-size: 10px;
transition: transform 0.15s ease;
width: 12px;
text-align: center;
}
.activity-summary-chevron.expanded {
transform: rotate(90deg);
}
.activity-summary-text {
font-weight: 500;
}
.activity-summary-duration {
font-family: var(--font-mono);
font-size: 11px;
opacity: 0.7;
}
.activity-cards-container {
display: flex;
flex-direction: column;
gap: 2px;
padding-left: 12px;
border-left: 2px solid var(--border);
margin-top: 2px;
}
@media (max-width: 768px) {
.activity-group {
max-width: 95%;
}
}
/* Approval card (inline in chat) */
.approval-card {
align-self: flex-start;
max-width: 80%;
background: var(--bg-secondary);
border: 1px solid var(--warning);
border-radius: var(--radius-lg);
padding: 14px;
display: flex;
flex-direction: column;
gap: 8px;
transition: border-color 0.2s;
}
.approval-header {
font-size: 12px;
font-weight: 600;
color: var(--warning);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.approval-tool-name {
font-size: 14px;
font-weight: 600;
color: var(--text);
font-family: var(--font-mono);
}
.approval-description {
font-size: 13px;
color: var(--text-secondary);
line-height: 1.4;
}
.approval-params-toggle {
background: none;
border: none;
color: var(--accent);
cursor: pointer;
font-size: 12px;
padding: 0;
text-align: left;
}
.approval-params-toggle:hover {
text-decoration: underline;
}
.approval-params {
background: var(--code-bg);
padding: 8px 12px;
border-radius: var(--radius);
font-size: 12px;
font-family: var(--font-mono);
line-height: 1.4;
overflow-x: auto;
color: var(--text-secondary);
margin: 0;
white-space: pre-wrap;
word-break: break-all;
}
.approval-card .approval-actions {
display: flex;
gap: 8px;
align-items: center;
}
.approval-card .approval-actions button {
padding: 6px 14px;
border: 1px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
background: var(--bg-secondary);
color: var(--text);
}
.approval-card .approval-actions button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.approval-card .approval-actions button.approve {
background: var(--success);
border-color: var(--success);
color: #09090b;
font-weight: 600;
}
.approval-card .approval-actions button.always {
background: var(--accent);
border-color: var(--accent);
color: #09090b;
font-weight: 600;
}
.approval-card .approval-actions button.deny {
background: var(--danger);
border-color: var(--danger);
color: #fff;
}
.approval-resolved {
font-size: 12px;
font-weight: 500;
color: var(--text-secondary);
font-style: italic;
}
/* Tool calls summary (persisted between user/assistant messages) */
.tool-calls-summary {
background: var(--bg-secondary);
border-left: 3px solid var(--warning);
padding: 6px 12px;
margin: 4px 0;
font-size: 0.85em;
border-radius: 4px;
}
.tool-calls-header {
color: var(--text-secondary);
font-weight: 500;
user-select: none;
}
.tool-calls-header::before {
content: '\25B6';
display: inline-block;
margin-right: 6px;
font-size: 0.7em;
transition: transform 0.15s;
}
.tool-calls-header.expanded::before {
transform: rotate(90deg);
}
.tool-calls-list {
margin-top: 6px;
display: none;
}
.tool-calls-list.expanded {
display: block;
}
.tool-call-item {
padding: 3px 0;
border-bottom: 1px solid var(--border);
}
.tool-call-item:last-child {
border-bottom: none;
}
.tool-call-name {
font-weight: 500;
color: var(--text-primary);
}
.tool-call-preview {
color: var(--text-secondary);
font-size: 0.9em;
max-height: 60px;
overflow: hidden;
white-space: pre-wrap;
word-break: break-word;
}
.tool-call-error-text {
color: var(--danger);
font-size: 0.9em;
}
.tool-error .tool-call-name {
color: var(--danger);
}
/* Auth prompt */
.auth-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
z-index: 1001;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
}
.auth-card {
align-self: flex-start;
max-width: 80%;
background: var(--bg-secondary);
border: 1px solid var(--accent);
border-radius: var(--radius-lg);
padding: 12px 16px;
margin: 8px 0;
display: flex;
flex-direction: column;
gap: 8px;
transition: border-color 0.2s;
}
.auth-overlay .auth-card {
width: 460px;
max-width: min(460px, 90vw);
margin: 0;
align-self: auto;
background: var(--bg);
border-color: rgba(52, 211, 153, 0.35);
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.35);
}
.auth-card .auth-header {
font-weight: 600;
color: var(--accent);
font-size: 13px;
}
.auth-card .auth-instructions {
font-size: 13px;
color: var(--text);
line-height: 1.4;
}
.auth-card .auth-links {
display: flex;
gap: 8px;
align-items: center;
}
.auth-card .auth-links a {
color: var(--accent);
font-size: 13px;
text-decoration: underline;
}
.auth-card .auth-token-input {
display: flex;
gap: 8px;
align-items: center;
}
.auth-card .auth-token-input input {
flex: 1;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg);
color: var(--text);
font-size: 13px;
font-family: var(--font-mono);
}
.auth-card .auth-token-input input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.auth-card .auth-actions {
display: flex;
gap: 8px;
align-items: center;
}
.auth-card .auth-actions button {
padding: 6px 14px;
border: 1px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
background: var(--bg-secondary);
color: var(--text);
}
.auth-card .auth-actions button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.auth-card .auth-actions button.auth-submit {
background: var(--accent);
border-color: var(--accent);
color: #09090b;
font-weight: 600;
}
.auth-card .auth-actions button.auth-cancel {
background: var(--bg-secondary);
border-color: var(--border);
}
.auth-card .auth-actions button.auth-oauth {
background: var(--success);
border-color: var(--success);
color: #09090b;
font-weight: 600;
}
.auth-card .auth-error {
color: var(--danger);
font-size: 12px;
}
/* Chat input */
.chat-input {
display: flex;
flex-wrap: wrap;
padding: 12px 16px max(12px, env(safe-area-inset-bottom)) 16px;
gap: 8px;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
flex-shrink: 0;
min-height: 56px;
}
.chat-input-wrapper {
position: relative;
flex: 1;
display: flex;
}
.chat-input-wrapper textarea {
width: 100%;
padding: 8px 12px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 14px;
font-family: inherit;
resize: none;
min-height: 40px;
max-height: 120px;
}
.ghost-text {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 8px 12px;
font-size: 14px;
font-family: inherit;
color: var(--text-secondary);
opacity: 0.5;
pointer-events: none;
white-space: pre-wrap;
overflow: hidden;
display: none;
z-index: 1;
}
/* Hide native placeholder when ghost text is visible */
.chat-input-wrapper.has-ghost textarea::placeholder {
color: transparent;
}
.chat-input-wrapper textarea:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.chat-input-wrapper textarea:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.suggestion-chips {
display: none;
flex-wrap: wrap;
gap: 8px;
padding: 8px 16px;
border-top: 1px solid var(--border);
}
.suggestion-chip {
padding: 6px 14px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 16px;
color: var(--text-secondary);
font-size: 13px;
font-family: inherit;
cursor: pointer;
transition: all 0.15s ease;
white-space: nowrap;
}
.suggestion-chip:hover {
background: var(--accent);
color: #09090b;
border-color: var(--accent);
}
.chat-input button {
padding: 8px 20px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 14px;
font-weight: 600;
align-self: flex-end;
transition: background 0.2s, transform 0.2s;
}
.chat-input button:hover:not(:disabled) {
background: var(--accent-hover);
transform: translateY(-1px);
}
.chat-input button:active {
transform: scale(0.98);
}
.chat-input button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
/* Keyboard accessibility focus rings */
.chat-input-wrapper textarea:focus-visible,
.chat-input button:focus-visible,
.tab-bar button:focus-visible,
.tree-row:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Memory Tab */
.memory-container {
flex: 1;
display: flex;
overflow: hidden;
}
.memory-sidebar {
width: 280px;
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
background: var(--bg-secondary);
}
.memory-sidebar .search-box {
padding: 12px;
border-bottom: 1px solid var(--border);
}
.memory-sidebar input {
width: 100%;
padding: 6px 10px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
}
.memory-sidebar input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.memory-tree {
flex: 1;
overflow-y: auto;
padding: 8px 0;
}
/* Tree view */
.tree-row {
display: flex;
align-items: center;
padding: 3px 8px;
cursor: pointer;
font-size: 13px;
color: var(--text-secondary);
gap: 4px;
min-height: 26px;
}
.tree-row:hover {
background: var(--bg-tertiary);
color: var(--text);
}
.expand-arrow {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
font-size: 8px;
color: var(--text-secondary);
transition: transform 0.15s ease;
flex-shrink: 0;
cursor: pointer;
}
.expand-arrow.expanded {
transform: rotate(90deg);
}
.expand-arrow-spacer {
display: inline-block;
width: 16px;
flex-shrink: 0;
}
.tree-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tree-label.dir {
color: var(--text);
font-weight: 500;
}
.tree-label.file {
color: var(--text-secondary);
}
.tree-row:hover .tree-label.file {
color: var(--accent);
}
.tree-children {
/* Rendered inline, indentation handled by padding-left on tree-row */
}
/* Legacy tree-item (search results) */
.tree-item {
padding: 4px 12px 4px 16px;
cursor: pointer;
font-size: 13px;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 6px;
}
.tree-item:hover {
background: var(--bg-tertiary);
color: var(--text);
}
.tree-item.active {
background: var(--bg-tertiary);
color: var(--accent);
}
.tree-item .icon {
font-size: 12px;
width: 16px;
text-align: center;
}
.memory-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.memory-breadcrumb {
padding: 8px 16px;
font-size: 13px;
color: var(--text-secondary);
border-bottom: 1px solid var(--border);
background: var(--bg-secondary);
display: flex;
align-items: center;
gap: 8px;
}
.memory-breadcrumb a {
color: var(--accent);
text-decoration: none;
cursor: pointer;
}
.memory-breadcrumb a:hover {
text-decoration: underline;
}
.memory-viewer {
flex: 1;
overflow-y: auto;
padding: 16px;
font-size: 14px;
line-height: 1.6;
white-space: pre-wrap;
font-family: var(--font-mono);
}
.memory-viewer .empty {
color: var(--text-secondary);
font-style: italic;
}
.search-results {
padding: 8px 0;
}
.search-result {
padding: 8px 12px;
border-bottom: 1px solid var(--border);
cursor: pointer;
}
.search-result:hover {
background: var(--bg-tertiary);
}
.search-result .path {
font-size: 12px;
color: var(--accent);
margin-bottom: 4px;
}
.search-result .snippet {
font-size: 13px;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Jobs Tab */
.jobs-container {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.jobs-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
margin-bottom: 20px;
}
.summary-card {
padding: 16px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
text-align: center;
transition: border-color 0.2s, transform 0.2s;
}
.summary-card:hover {
border-color: rgba(255, 255, 255, 0.15);
}
.summary-card .count {
font-size: 28px;
font-weight: 600;
color: var(--text);
}
.summary-card .label {
font-size: 12px;
color: var(--text-secondary);
margin-top: 4px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.summary-card.active .count { color: var(--accent); }
.summary-card.completed .count { color: var(--success); }
.summary-card.failed .count { color: var(--danger); }
.summary-card.stuck .count { color: var(--warning); }
.jobs-table {
width: 100%;
border-collapse: collapse;
}
.jobs-table th,
.jobs-table td {
padding: 10px 12px;
text-align: left;
border-bottom: 1px solid var(--border);
font-size: 13px;
}
.jobs-table th {
color: var(--text-secondary);
font-weight: 500;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.5px;
}
.jobs-table tr:hover td {
background: rgba(255, 255, 255, 0.03);
}
.badge {
display: inline-block;
padding: 3px 10px;
border-radius: 9999px;
font-size: 11px;
font-weight: 500;
}
.badge.pending { background: var(--bg-tertiary); color: var(--text-secondary); }
.badge.in_progress { background: rgba(52, 211, 153, 0.15); color: var(--accent); }
.badge.completed { background: rgba(52, 211, 153, 0.15); color: var(--success); }
.badge.failed { background: rgba(230, 76, 76, 0.15); color: var(--danger); }
.badge.stuck { background: rgba(245, 166, 35, 0.15); color: var(--warning); }
.badge.cancelled { background: var(--bg-tertiary); color: var(--text-secondary); }
.badge.interrupted { background: rgba(245, 166, 35, 0.15); color: var(--warning); }
.badge.source-sandbox { background: rgba(136, 132, 216, 0.15); color: #b4b0e8; }
.badge.source-direct { background: var(--bg-tertiary); color: var(--text-secondary); }
.btn-cancel {
padding: 4px 10px;
background: none;
border: 1px solid var(--danger);
border-radius: var(--radius);
color: var(--danger);
cursor: pointer;
font-size: 12px;
}
.btn-cancel:hover {
background: rgba(230, 76, 76, 0.15);
}
.btn-restart {
padding: 4px 10px;
background: none;
border: 1px solid var(--accent);
border-radius: var(--radius);
color: var(--accent);
cursor: pointer;
font-size: 12px;
}
.btn-restart:hover {
background: rgba(52, 211, 153, 0.15);
}
.btn-browse {
padding: 4px 10px;
background: none;
border: 1px solid var(--success);
border-radius: var(--radius);
color: var(--success);
cursor: pointer;
font-size: 12px;
text-decoration: none;
}
.btn-browse:hover {
background: rgba(52, 211, 153, 0.15);
}
/* Job started card in chat */
.job-card {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
margin: 8px 0;
background: var(--bg-tertiary);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
border-left: 3px solid var(--accent);
transition: border-color 0.2s, transform 0.2s;
}
.job-card:hover {
border-color: rgba(255, 255, 255, 0.15);
}
.job-card-icon {
font-size: 20px;
}
.job-card-info {
flex: 1;
}
.job-card-title {
font-weight: 600;
font-size: 14px;
}
.job-card-id {
font-size: 12px;
color: var(--text-secondary);
font-family: var(--font-mono);
}
.job-card-view, .job-card-browse {
padding: 4px 12px;
border-radius: var(--radius);
font-size: 12px;
cursor: pointer;
text-decoration: none;
}
.job-card-view {
background: none;
border: 1px solid var(--accent);
color: var(--accent);
}
.job-card-view:hover {
background: rgba(52, 211, 153, 0.15);
}
.job-card-browse {
background: none;
border: 1px solid var(--success);
color: var(--success);
}
.job-card-browse:hover {
background: rgba(52, 211, 153, 0.15);
}
/* Clickable job rows */
.job-row {
cursor: pointer;
}
/* Job Detail View */
.job-detail-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.job-detail-header h2 {
font-size: 18px;
font-weight: 600;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.btn-back {
padding: 6px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
cursor: pointer;
font-size: 13px;
flex-shrink: 0;
}
.btn-back:hover {
background: var(--bg-tertiary);
}
.job-detail-tabs {
display: flex;
gap: 0;
border-bottom: 1px solid var(--border);
margin-bottom: 16px;
}
.job-detail-tabs button {
padding: 8px 16px;
background: none;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-secondary);
cursor: pointer;
font-size: 13px;
}
.job-detail-tabs button:hover {
color: var(--text);
}
.job-detail-tabs button.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.job-detail-content {
flex: 1;
overflow-y: auto;
}
/* Metadata grid */
.job-meta-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 12px;
margin-bottom: 20px;
}
.meta-item {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 10px 12px;
}
.meta-label {
font-size: 11px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 4px;
}
.meta-value {
font-size: 14px;
color: var(--text);
word-break: break-all;
}
/* Job description */
.job-description {
margin-bottom: 20px;
}
.job-description h3 {
font-size: 14px;
font-weight: 600;
margin-bottom: 8px;
color: var(--text);
}
.job-description-body {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 12px 16px;
font-size: 14px;
line-height: 1.6;
}
/* State transitions timeline */
.job-timeline-section {
margin-bottom: 20px;
}
.job-timeline-section h3 {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text);
}
.timeline {
position: relative;
padding-left: 20px;
border-left: 2px solid var(--border);
}
.timeline-entry {
position: relative;
padding: 8px 0 8px 16px;
}
.timeline-dot {
position: absolute;
left: -27px;
top: 14px;
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--accent);
border: 2px solid var(--bg);
}
.timeline-info {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
font-size: 13px;
}
.timeline-time {
color: var(--text-secondary);
font-size: 12px;
margin-left: 8px;
}
.timeline-reason {
width: 100%;
font-size: 12px;
color: var(--text-secondary);
margin-top: 2px;
}
/* Action cards */
.action-card {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
margin-bottom: 8px;
border-left: 3px solid var(--success);
}
.action-card.failure {
border-left-color: var(--danger);
}
.action-header {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
cursor: pointer;
font-size: 13px;
}
.action-header:hover {
background: var(--bg-tertiary);
}
.action-tool {
font-weight: 600;
color: var(--text);
font-family: var(--font-mono);
}
.action-seq {
color: var(--text-secondary);
font-size: 11px;
}
.action-duration {
color: var(--text-secondary);
font-size: 12px;
}
.action-time {
color: var(--text-secondary);
font-size: 12px;
margin-left: auto;
}
.action-toggle {
color: var(--text-secondary);
font-size: 10px;
flex-shrink: 0;
}
.action-detail {
padding: 0 12px 12px;
}
.action-section {
margin-top: 8px;
}
.action-section strong {
font-size: 12px;
color: var(--text-secondary);
display: block;
margin-bottom: 4px;
}
.action-json {
background: var(--code-bg);
padding: 8px 12px;
border-radius: var(--radius);
font-size: 12px;
font-family: var(--font-mono);
line-height: 1.4;
overflow-x: auto;
color: var(--text-secondary);
margin: 0;
white-space: pre-wrap;
word-break: break-all;
max-height: 300px;
overflow-y: auto;
}
.action-error {
background: rgba(230, 76, 76, 0.1);
padding: 8px 12px;
border-radius: var(--radius);
font-size: 12px;
font-family: var(--font-mono);
line-height: 1.4;
color: var(--danger);
margin: 0;
white-space: pre-wrap;
word-break: break-all;
}
/* Conversation messages */
.conv-message {
padding: 10px 14px;
border-radius: var(--radius);
margin-bottom: 8px;
font-size: 14px;
line-height: 1.5;
}
.conv-role {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 4px;
}
.conv-body {
word-wrap: break-word;
}
.conv-system {
background: var(--bg-tertiary);
border: 1px solid var(--border);
}
.conv-system .conv-role { color: var(--text-secondary); }
.conv-system .conv-body { color: var(--text-secondary); font-size: 13px; }
.conv-user {
background: rgba(52, 211, 153, 0.08);
border: 1px solid rgba(52, 211, 153, 0.2);
}
.conv-user .conv-role { color: var(--accent); }
.conv-assistant {
background: var(--bg-secondary);
border: 1px solid var(--border);
}
.conv-assistant .conv-role { color: var(--success); }
.conv-tool {
background: var(--bg-secondary);
border: 1px solid var(--border);
font-family: var(--font-mono);
font-size: 13px;
}
.conv-tool .conv-role { color: var(--warning); }
.conv-tool .conv-body { white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; }
.conv-tc-id {
font-size: 11px;
color: var(--text-secondary);
margin-bottom: 4px;
font-family: var(--font-mono);
}
.conv-tool-calls {
margin-top: 8px;
border-top: 1px solid var(--border);
padding-top: 8px;
}
.conv-tc-entry {
margin-bottom: 6px;
}
.conv-tc-name {
font-size: 12px;
font-weight: 600;
color: var(--accent);
font-family: var(--font-mono);
}
.conv-tc-args {
background: var(--code-bg);
padding: 6px 10px;
border-radius: var(--radius);
font-size: 11px;
font-family: var(--font-mono);
line-height: 1.4;
margin: 4px 0 0;
color: var(--text-secondary);
white-space: pre-wrap;
word-break: break-all;
max-height: 150px;
overflow-y: auto;
}
/* Job files browser */
.job-files {
display: flex;
height: calc(100vh - 280px);
height: calc(100dvh - 280px);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
}
.job-files-sidebar {
width: 240px;
border-right: 1px solid var(--border);
background: var(--bg-secondary);
overflow-y: auto;
}
.job-files-tree {
padding: 8px 0;
}
.job-files-viewer {
flex: 1;
overflow: auto;
padding: 12px 16px;
}
.job-files-path {
font-size: 12px;
color: var(--accent);
margin-bottom: 8px;
font-family: var(--font-mono);
}
.job-files-content {
font-size: 13px;
font-family: var(--font-mono);
line-height: 1.5;
white-space: pre-wrap;
word-break: break-all;
color: var(--text);
margin: 0;
}
.empty-state {
text-align: center;
padding: 40px;
color: var(--text-secondary);
}
/* Routines Tab */
.routines-container {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.routines-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
margin-bottom: 20px;
}
.routines-table {
width: 100%;
border-collapse: collapse;
}
.routines-table th,
.routines-table td {
padding: 10px 12px;
text-align: left;
border-bottom: 1px solid var(--border);
font-size: 13px;
}
.routines-table th {
color: var(--text-secondary);
font-weight: 500;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.5px;
}
.routines-table tr:hover td {
background: rgba(255, 255, 255, 0.03);
}
.routine-row {
cursor: pointer;
}
.routine-detail {
padding: 16px 0;
}
.badge.enabled { background: rgba(52, 211, 153, 0.15); color: var(--success); }
.badge.disabled { background: var(--bg-tertiary); color: var(--text-secondary); }
.badge.failing { background: rgba(230, 76, 76, 0.15); color: var(--danger); }
.btn-trigger {
padding: 4px 10px;
background: none;
border: 1px solid var(--accent);
border-radius: var(--radius);
color: var(--accent);
cursor: pointer;
font-size: 12px;
}
.btn-trigger:hover {
background: rgba(52, 211, 153, 0.15);
}
.btn-toggle {
padding: 4px 10px;
background: none;
border: 1px solid var(--warning);
border-radius: var(--radius);
color: var(--warning);
cursor: pointer;
font-size: 12px;
}
.btn-toggle:hover {
background: rgba(245, 166, 35, 0.15);
}
/* Logs Tab */
.logs-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.logs-toolbar {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.logs-toolbar select,
.logs-toolbar input {
padding: 5px 8px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 12px;
}
.logs-toolbar select {
min-width: 100px;
}
.logs-toolbar input {
flex: 1;
max-width: 240px;
}
.logs-toolbar select:focus,
.logs-toolbar input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.logs-checkbox {
font-size: 12px;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 4px;
white-space: nowrap;
}
.logs-toolbar button {
padding: 5px 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
cursor: pointer;
font-size: 12px;
}
.logs-toolbar button:hover {
background: var(--border);
}
.logs-output {
flex: 1;
overflow-y: auto;
padding: 4px 0;
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.5;
background: var(--bg);
}
.log-entry {
display: flex;
gap: 8px;
padding: 1px 12px;
white-space: nowrap;
cursor: pointer;
}
.log-entry:hover {
background: var(--bg-tertiary);
}
.log-ts {
color: var(--text-secondary);
flex-shrink: 0;
width: 80px;
}
.log-level {
flex-shrink: 0;
width: 44px;
font-weight: 600;
}
.log-target {
color: var(--text-secondary);
flex-shrink: 0;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
}
.log-msg {
color: var(--text);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.log-entry.expanded {
white-space: normal;
}
.log-entry.expanded .log-msg {
white-space: pre-wrap;
word-break: break-all;
overflow: visible;
text-overflow: unset;
}
/* Log level coloring */
.log-entry.level-ERROR .log-level { color: var(--danger); }
.log-entry.level-ERROR .log-msg { color: var(--danger); }
.log-entry.level-WARN .log-level { color: var(--warning); }
.log-entry.level-WARN .log-msg { color: var(--warning); }
.log-entry.level-INFO .log-level { color: var(--text); }
.log-entry.level-DEBUG .log-level { color: var(--text-secondary); }
.log-entry.level-DEBUG .log-msg { color: var(--text-secondary); }
/* Extensions Tab */
.extensions-container {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.extensions-section {
margin-bottom: 24px;
}
.extensions-section h3 {
font-size: 15px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text);
}
.extensions-section h4 {
font-size: 13px;
font-weight: 600;
margin: 16px 0 8px;
color: var(--text-secondary);
}
.extensions-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 12px;
}
.ext-card {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 14px;
display: flex;
flex-direction: column;
gap: 8px;
transition: border-color 0.2s, transform 0.2s;
}
.ext-card:hover {
border-color: rgba(255, 255, 255, 0.15);
}
.ext-header {
display: flex;
align-items: center;
gap: 8px;
}
.ext-name {
font-weight: 600;
font-size: 14px;
color: var(--text);
}
.ext-kind {
font-size: 10px;
padding: 2px 6px;
border-radius: 8px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.ext-kind.kind-mcp_server {
background: rgba(52, 211, 153, 0.15);
color: var(--accent);
}
.ext-kind.kind-wasm_tool {
background: rgba(52, 211, 153, 0.15);
color: var(--success);
}
.ext-kind.kind-wasm_channel {
background: rgba(245, 166, 35, 0.15);
color: var(--warning);
}
.ext-version {
font-size: 11px;
color: var(--text-muted);
font-family: var(--font-mono);
}
.ext-auth-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.ext-auth-dot.authed {
background: var(--success);
}
.ext-auth-dot.unauthed {
background: var(--danger);
}
.ext-desc {
font-size: 13px;
color: var(--text-secondary);
line-height: 1.4;
}
.ext-url {
font-size: 12px;
color: var(--text-secondary);
font-family: var(--font-mono);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ext-tools {
font-size: 12px;
color: var(--text-secondary);
}
.ext-actions {
display: flex;
gap: 6px;
align-items: center;
margin-top: 4px;
}
.ext-active-label {
font-size: 12px;
color: var(--success);
font-weight: 500;
}
/* WASM channel setup stepper */
.ext-stepper {
display: flex;
align-items: center;
gap: 0;
margin: 8px 0 4px;
}
.stepper-step {
display: flex;
align-items: center;
gap: 4px;
}
.stepper-circle {
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
}
.stepper-label {
font-size: 11px;
white-space: nowrap;
}
.stepper-step.completed .stepper-circle {
background: var(--success);
color: #000;
}
.stepper-step.completed .stepper-label {
color: var(--success);
}
.stepper-step.failed .stepper-circle {
background: var(--danger);
color: #fff;
}
.stepper-step.failed .stepper-label {
color: var(--danger);
}
.stepper-step.in-progress .stepper-circle {
background: var(--warning);
color: #000;
animation: pulse-glow 1.5s ease-in-out infinite;
}
.stepper-step.in-progress .stepper-label {
color: var(--warning);
}
@keyframes pulse-glow {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.stepper-step.pending .stepper-circle {
background: var(--bg-tertiary);
border: 1px solid var(--border);
color: var(--text-secondary);
}
.stepper-step.pending .stepper-label {
color: var(--text-secondary);
}
.ext-pairing-label {
font-size: 12px;
color: var(--warning);
font-weight: 500;
}
.stepper-connector {
width: 20px;
height: 2px;
background: var(--border);
margin: 0 4px;
flex-shrink: 0;
}
.stepper-connector.completed {
background: var(--success);
}
.ext-error {
font-size: 11px;
color: var(--danger);
background: rgba(230, 76, 76, 0.1);
border: 1px solid rgba(230, 76, 76, 0.2);
border-radius: var(--radius);
padding: 6px 8px;
margin-top: 6px;
}
.ext-note {
font-size: 11px;
color: var(--text-secondary);
background: rgba(255, 255, 255, 0.04);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 6px 8px;
margin-top: 6px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.btn-ext {
padding: 4px 10px;
border-radius: var(--radius);
cursor: pointer;
font-size: 12px;
border: 1px solid var(--border);
background: var(--bg-tertiary);
color: var(--text);
}
.btn-ext:hover {
background: var(--border);
}
.btn-ext.activate {
border-color: var(--accent);
color: var(--accent);
}
.btn-ext.activate:hover {
background: rgba(52, 211, 153, 0.15);
}
.btn-ext.remove {
border-color: var(--danger);
color: var(--danger);
}
.btn-ext.remove:hover {
background: rgba(230, 76, 76, 0.15);
}
.btn-ext.install {
border-color: var(--success);
color: var(--success);
}
.btn-ext.install:hover {
background: rgba(52, 211, 153, 0.15);
}
.btn-ext.install:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.ext-available {
border-style: dashed;
}
.ext-keywords {
font-size: 11px;
color: var(--text-secondary);
opacity: 0.7;
}
.btn-ext.configure {
border-color: var(--accent);
color: var(--accent);
}
.btn-ext.configure:hover {
background: rgba(136, 132, 216, 0.15);
}
/* Pairing requests */
.ext-pairing {
margin-top: 8px;
border-top: 1px solid var(--border);
padding-top: 8px;
}
.pairing-heading {
font-size: 11px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
}
.pairing-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 4px;
}
.pairing-code {
font-family: var(--font-mono);
font-size: 13px;
font-weight: 600;
color: var(--accent);
background: var(--bg-tertiary);
padding: 2px 6px;
border-radius: 3px;
}
.pairing-sender {
font-size: 12px;
color: var(--text-secondary);
flex: 1;
}
/* Configure modal */
.configure-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.configure-modal {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
width: 460px;
max-width: 90vw;
max-height: 80vh;
overflow-y: auto;
}
.configure-modal h3 {
margin: 0 0 16px 0;
font-size: 16px;
color: var(--text-primary);
}
.configure-form {
display: flex;
flex-direction: column;
gap: 16px;
}
.configure-field label {
display: block;
font-size: 13px;
color: var(--text-secondary);
margin-bottom: 6px;
}
.configure-input-row {
display: flex;
align-items: center;
gap: 8px;
}
.configure-input-row input {
flex: 1;
padding: 8px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text-primary);
font-size: 13px;
font-family: inherit;
}
.configure-input-row input:focus {
outline: none;
border-color: var(--accent);
}
.field-optional {
color: var(--text-secondary);
font-style: italic;
}
.field-provided {
font-size: 11px;
padding: 2px 8px;
background: rgba(63, 185, 80, 0.15);
color: var(--success);
border-radius: 4px;
white-space: nowrap;
}
.field-autogen {
font-size: 11px;
color: var(--text-secondary);
white-space: nowrap;
}
.configure-actions {
display: flex;
gap: 8px;
margin-top: 20px;
justify-content: flex-end;
}
.tools-table {
width: 100%;
border-collapse: collapse;
}
.tools-table th,
.tools-table td {
padding: 8px 12px;
text-align: left;
border-bottom: 1px solid var(--border);
font-size: 13px;
}
.tools-table th {
color: var(--text-secondary);
font-weight: 500;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.5px;
}
.tools-table tr:hover td {
background: rgba(255, 255, 255, 0.03);
}
/* --- Activity tab (unified sandbox job events) --- */
.activity-terminal {
flex: 1;
overflow-y: auto;
padding: 12px;
font-family: var(--font-mono);
font-size: 13px;
line-height: 1.6;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
margin-bottom: 8px;
max-height: calc(100vh - 320px);
}
.activity-event {
padding: 4px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.activity-event-message .activity-role {
color: var(--accent);
font-weight: 600;
margin-right: 8px;
}
.activity-event-message .activity-content {
white-space: pre-wrap;
word-break: break-word;
}
.activity-event-status .activity-status {
color: var(--text-secondary);
font-style: italic;
}
.activity-event-result.activity-final {
padding: 8px 0;
font-weight: 600;
}
.activity-result-status {
color: var(--success);
}
.activity-result-status[data-success="false"] {
color: var(--danger);
}
.activity-session-id {
color: var(--text-secondary);
font-size: 11px;
font-weight: 400;
}
.activity-tool-block {
margin: 4px 0;
border: 1px solid var(--border);
border-radius: 4px;
overflow: hidden;
}
.activity-tool-block summary {
padding: 6px 10px;
cursor: pointer;
background: var(--bg-secondary);
font-size: 12px;
color: var(--text-secondary);
}
.activity-tool-block summary:hover {
color: var(--text);
}
.activity-tool-icon {
margin-right: 4px;
}
.activity-tool-result .activity-tool-icon {
color: var(--success);
}
.activity-tool-error .activity-tool-icon {
color: var(--danger);
}
.activity-tool-error summary {
color: var(--danger);
}
.activity-tool-input,
.activity-tool-output {
padding: 8px 10px;
margin: 0;
font-size: 12px;
overflow-x: auto;
max-height: 200px;
overflow-y: auto;
background: var(--bg);
}
.activity-input-bar {
display: flex;
gap: 8px;
padding: 8px 0;
}
.activity-input-bar input {
flex: 1;
padding: 8px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
}
.activity-input-bar input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.activity-input-bar button {
padding: 8px 16px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
font-weight: 600;
transition: background 0.2s, transform 0.2s;
}
.activity-input-bar button:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
.activity-input-bar button:active {
transform: scale(0.98);
}
#activity-done-btn {
background: var(--bg-secondary);
border: 1px solid var(--border);
color: var(--text-secondary);
}
#activity-done-btn:hover {
color: var(--text);
border-color: var(--text-secondary);
background: var(--bg-secondary);
}
/* --- Copy button on code blocks --- */
.code-block-wrapper {
position: relative;
}
.copy-btn {
position: absolute;
top: 6px;
right: 6px;
padding: 2px 8px;
background: var(--bg-tertiary);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-secondary);
font-size: 11px;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s;
}
.code-block-wrapper:hover .copy-btn {
opacity: 1;
}
.copy-btn:hover {
color: var(--text);
background: var(--border);
}
/* --- Toast notifications --- */
#toasts {
position: fixed;
top: 16px;
right: 16px;
z-index: 10000;
display: flex;
flex-direction: column;
gap: 8px;
pointer-events: none;
}
.toast {
padding: 10px 16px;
border-radius: var(--radius);
font-size: 13px;
color: #fff;
pointer-events: auto;
transform: translateX(120%);
transition: transform 0.25s ease;
max-width: 360px;
word-break: break-word;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.toast.visible {
transform: translateX(0);
}
.toast-info {
background: var(--accent);
}
.toast-success {
background: var(--success);
}
.toast-error {
background: var(--danger);
}
/* --- Memory search highlighting --- */
mark {
background: rgba(52, 211, 153, 0.3);
color: inherit;
border-radius: 2px;
padding: 0 1px;
}
/* --- Thread sidebar --- */
#tab-chat {
flex-direction: row;
}
.thread-sidebar {
width: 240px;
background: var(--bg-secondary);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
flex-shrink: 0;
transition: width 0.2s ease;
overflow: hidden;
padding: 6px;
gap: 2px;
}
.thread-sidebar.collapsed {
width: 36px;
}
.thread-sidebar.collapsed .thread-sidebar-header span,
.thread-sidebar.collapsed .thread-new-btn,
.thread-sidebar.collapsed .thread-list,
.thread-sidebar.collapsed .assistant-item,
.thread-sidebar.collapsed .threads-section-header {
display: none;
}
.thread-sidebar-header {
display: flex;
align-items: center;
padding: 10px 10px;
font-size: 13px;
font-weight: 600;
gap: 8px;
}
.thread-sidebar-header span {
flex: 1;
}
.thread-new-btn {
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--accent);
cursor: pointer;
font-size: 16px;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
line-height: 1;
}
.thread-new-btn:hover {
background: rgba(52, 211, 153, 0.15);
}
.assistant-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
cursor: pointer;
font-size: 13px;
font-weight: 600;
color: var(--text);
background: var(--bg-tertiary);
border-radius: var(--radius);
margin-bottom: 2px;
}
.assistant-item:hover {
background: rgba(255, 255, 255, 0.06);
}
.assistant-item.active {
background: rgba(52, 211, 153, 0.1);
color: var(--accent);
border-left: 2px solid var(--accent);
}
.assistant-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.assistant-meta {
font-size: 11px;
font-weight: 400;
color: var(--text-secondary);
}
.threads-section-header {
padding: 10px 10px 4px;
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-secondary);
}
.thread-toggle-btn {
background: none;
border: none;
color: var(--text-secondary);
cursor: pointer;
font-size: 14px;
padding: 2px;
}
.thread-toggle-btn:hover {
color: var(--text);
}
.thread-list {
flex: 1;
overflow-y: auto;
}
.thread-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
cursor: pointer;
font-size: 13px;
color: var(--text-secondary);
border-radius: var(--radius);
}
.thread-item:hover {
background: var(--bg-tertiary);
color: var(--text);
}
.thread-item.active {
background: var(--bg-tertiary);
color: var(--accent);
border-left: 2px solid var(--accent);
}
.thread-label {
font-family: var(--font-mono);
font-size: 12px;
}
.thread-meta {
font-size: 11px;
color: var(--text-secondary);
flex-shrink: 0;
}
.thread-badge {
display: inline-block;
font-size: 9px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 1px 5px;
border-radius: 3px;
background: rgba(255, 255, 255, 0.08);
color: var(--text-secondary);
margin-right: 6px;
flex-shrink: 0;
}
.thread-badge-routine { background: rgba(52, 211, 153, 0.15); color: var(--accent); }
.thread-badge-heartbeat { background: rgba(245, 166, 35, 0.15); color: var(--warning); }
.thread-badge-telegram { background: rgba(0, 136, 204, 0.15); color: #0088cc; }
.thread-badge-signal { background: rgba(59, 118, 240, 0.15); color: #3b76f0; }
.thread-badge-slack { background: rgba(74, 21, 75, 0.15); color: #e01e5a; }
.thread-unread {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 16px;
height: 16px;
font-size: 10px;
font-weight: 700;
background: var(--accent);
color: var(--bg);
border-radius: 8px;
padding: 0 4px;
margin-left: auto;
flex-shrink: 0;
}
/* --- Memory editing --- */
#memory-breadcrumb-path {
flex: 1;
}
.memory-edit-btn {
padding: 3px 10px;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-secondary);
cursor: pointer;
font-size: 12px;
flex-shrink: 0;
}
.memory-edit-btn:hover {
color: var(--accent);
border-color: var(--accent);
}
.memory-editor {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
overflow: hidden;
}
.memory-editor textarea {
flex: 1;
padding: 12px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-family: var(--font-mono);
font-size: 13px;
line-height: 1.5;
resize: none;
}
.memory-editor textarea:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.memory-editor-actions {
display: flex;
gap: 8px;
}
.btn-save {
padding: 6px 16px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
font-weight: 600;
transition: background 0.2s, transform 0.2s;
}
.btn-save:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
.btn-save:active {
transform: scale(0.98);
}
.btn-cancel-edit {
padding: 6px 16px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
cursor: pointer;
font-size: 13px;
}
.btn-cancel-edit:hover {
background: var(--bg-tertiary);
}
/* Memory rendered markdown */
.memory-viewer.rendered {
white-space: normal;
font-family: inherit;
}
.memory-rendered {
font-size: 14px;
line-height: 1.6;
}
.memory-rendered h1, .memory-rendered h2, .memory-rendered h3 {
margin: 12px 0 6px 0;
}
.memory-rendered p { margin: 0 0 8px 0; }
.memory-rendered p:last-child { margin-bottom: 0; }
.memory-rendered ul, .memory-rendered ol { margin: 4px 0; padding-left: 20px; }
.memory-rendered li { margin: 2px 0; }
.memory-rendered code {
background: var(--code-bg);
padding: 1px 4px;
border-radius: 3px;
font-size: 13px;
}
.memory-rendered pre {
background: var(--code-bg);
padding: 8px 12px;
border-radius: var(--radius);
overflow-x: auto;
margin: 6px 0;
}
.memory-rendered pre code { background: none; padding: 0; }
.memory-rendered a { color: var(--accent); }
.memory-rendered blockquote {
margin: 6px 0;
padding: 4px 12px;
border-left: 3px solid var(--border);
color: var(--text-secondary);
}
/* --- Gateway status popover --- */
.gateway-popover {
display: none;
position: absolute;
top: 100%;
right: 0;
margin-top: 8px;
background: rgba(15, 15, 17, 0.9);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 12px;
min-width: 220px;
box-shadow: var(--shadow);
z-index: 100;
}
.gateway-popover.visible {
display: block;
}
.gw-section-label {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted, var(--text-secondary));
margin-bottom: 4px;
font-weight: 600;
}
.gw-divider {
border-top: 1px solid var(--border);
margin: 8px 0;
}
.gw-stat {
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 3px 0;
color: var(--text-secondary);
}
.gw-stat span:last-child {
color: var(--text);
font-weight: 500;
}
.gw-model-row {
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 3px 0 0 0;
}
.gw-model-name {
color: var(--text);
font-weight: 500;
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 140px;
}
.gw-model-cost {
color: var(--accent, var(--text));
font-weight: 500;
font-size: 11px;
}
.gw-token-detail {
display: flex;
gap: 12px;
font-size: 10px;
color: var(--text-secondary);
padding: 1px 0 4px 0;
}
/* --- Extension install form --- */
.ext-install-form {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.ext-install-form input {
padding: 6px 10px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
}
.ext-install-form input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.ext-install-form button {
padding: 6px 16px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
font-weight: 600;
transition: background 0.2s, transform 0.2s;
}
.ext-install-form button:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
.ext-install-form button:active {
transform: scale(0.98);
}
/* --- Skills tab --- */
.skill-search-box {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 12px;
}
.skill-search-box input {
flex: 1;
padding: 8px 12px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
}
.skill-search-box input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
.skill-search-box button {
padding: 8px 20px;
background: var(--accent);
color: #09090b;
border: none;
border-radius: var(--radius);
cursor: pointer;
font-size: 13px;
font-weight: 600;
transition: background 0.2s, transform 0.2s;
}
.skill-search-box button:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
.skill-trust {
font-size: 10px;
padding: 2px 6px;
border-radius: 8px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.skill-trust.trust-trusted {
background: rgba(52, 211, 153, 0.15);
color: var(--success);
}
.skill-trust.trust-installed {
background: rgba(96, 165, 250, 0.15);
color: #60a5fa;
}
.skill-version {
font-size: 11px;
color: var(--text-secondary);
font-family: var(--font-mono);
}
@keyframes skillFadeIn {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
.skill-search-result {
animation: skillFadeIn 0.3s ease-out both;
}
/* --- Activity toolbar --- */
.activity-toolbar {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 0;
}
.activity-toolbar select {
padding: 5px 8px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text);
font-size: 12px;
}
.activity-toolbar select:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.1);
}
/* --- Mobile responsive --- */
@media (max-width: 768px) {
/* Tab bar: horizontal scroll */
.tab-bar {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding: 0 8px;
}
.tab-bar button:not(.status-logs-btn) {
padding: 8px 12px;
font-size: 13px;
white-space: nowrap;
}
/* Chat messages: wider */
.message {
max-width: 95%;
}
/* Thread sidebar: hidden behind toggle */
.thread-sidebar {
width: 36px;
}
.thread-sidebar .thread-sidebar-header span,
.thread-sidebar .thread-new-btn,
.thread-sidebar .thread-list,
.thread-sidebar .assistant-item,
.thread-sidebar .threads-section-header {
display: none;
}
.thread-sidebar.expanded-mobile {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 240px;
z-index: 50;
}
.thread-sidebar.expanded-mobile .thread-sidebar-header span,
.thread-sidebar.expanded-mobile .thread-new-btn,
.thread-sidebar.expanded-mobile .thread-list,
.thread-sidebar.expanded-mobile .assistant-item,
.thread-sidebar.expanded-mobile .threads-section-header {
display: flex;
}
/* Memory: vertical stack */
.memory-container {
flex-direction: column;
}
.memory-sidebar {
width: 100%;
max-height: 200px;
border-right: none;
border-bottom: 1px solid var(--border);
}
/* Job detail sub-tabs: wrap */
.job-detail-tabs {
flex-wrap: wrap;
}
.job-detail-header {
flex-wrap: wrap;
}
.job-detail-header h2 {
min-width: 100%;
order: -1;
}
/* Job files: vertical */
.job-files {
flex-direction: column;
height: auto;
}
.job-files-sidebar {
width: 100%;
max-height: 180px;
border-right: none;
border-bottom: 1px solid var(--border);
}
/* Extension install form */
.ext-install-form {
flex-direction: column;
align-items: stretch;
}
.ext-install-form input {
width: 100%;
}
/* Chat input: ensure visibility on mobile */
.chat-input {
min-height: 52px;
}
.chat-input-wrapper textarea {
min-height: 36px;
max-height: 100px;
}
.chat-input button {
padding: 6px 16px;
font-size: 14px;
}
}
/* Slash command autocomplete dropdown */
.slash-autocomplete {
position: relative;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
border-bottom: none;
max-height: 220px;
overflow-y: auto;
z-index: 50;
}
.slash-ac-item {
display: flex;
align-items: baseline;
gap: 10px;
padding: 7px 16px;
cursor: pointer;
transition: background 0.1s;
}
.slash-ac-item:hover,
.slash-ac-item.selected {
background: var(--bg-tertiary);
}
.slash-ac-cmd {
font-family: var(--font-mono);
font-size: 13px;
color: var(--accent);
white-space: nowrap;
min-width: 130px;
}
.slash-ac-desc {
font-size: 12px;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Image Upload */
.chat-input .attach-btn {
background: none;
border: none;
cursor: pointer;
font-size: 1.2em;
padding: 8px;
align-self: flex-end;
color: var(--text-secondary);
transition: color 0.2s;
min-height: 40px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 400;
}
.chat-input .attach-btn:hover {
background: none;
color: var(--text);
transform: none;
}
.image-preview-strip {
display: flex;
flex-direction: row;
gap: 8px;
padding: 4px;
overflow-x: auto;
min-height: 0;
width: 100%;
}
.image-preview-strip:empty {
display: none;
}
.image-preview-container {
position: relative;
display: inline-block;
flex-shrink: 0;
}
.image-preview {
width: 60px;
height: 60px;
border-radius: 6px;
object-fit: cover;
display: block;
}
.image-preview-remove {
position: absolute;
top: -6px;
right: -6px;
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--danger);
color: #fff;
border: none;
font-size: 12px;
line-height: 18px;
text-align: center;
cursor: pointer;
padding: 0;
}
.image-preview-remove:hover {
background: #c33;
}
/* Generated Image */
.generated-image-card {
max-width: 512px;
margin: 8px 0;
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border);
}
.generated-image {
max-width: 100%;
display: block;
}
/* Language Switcher */
.language-switcher {
position: relative;
display: flex;
align-items: center;
}
.language-btn {
background: transparent;
border: none;
color: var(--text-secondary);
cursor: pointer;
padding: 8px;
font-size: 16px;
border-radius: var(--radius);
transition: all 0.2s;
}
.language-btn:hover {
color: var(--text);
background: var(--bg-tertiary);
}
.language-menu {
position: absolute;
top: 100%;
right: 0;
margin-top: 4px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 4px;
min-width: 120px;
z-index: 1000;
box-shadow: var(--shadow);
}
.language-option {
padding: 8px 12px;
cursor: pointer;
border-radius: var(--radius);
color: var(--text);
font-size: 13px;
transition: all 0.2s;
}
.language-option:hover {
background: var(--bg-tertiary);
}
.language-option.active {
background: var(--accent);
color: var(--bg);
}
.generated-image-path {
font-size: 12px;
color: var(--text-secondary);
padding: 4px 8px;
background: var(--bg-secondary);
}