pssah4_vault-operator/styles.css
Sebastian Hanke 83037efc4a fix(review-bot): resolve 3.2.4 scan block and popout-compat warnings
The Obsidian review bot failed release 3.2.4 on one error and several
warnings that local ESLint did not surface (older eslint-plugin-obsidianmd).

- Blocker (no-unsupported-api): ButtonComponent.setDestructive() is the
  1.13+ API, but minAppVersion is 1.8.7. Extract the runtime feature-
  detection that PromptModal already used into applyDestructiveStyle()
  (src/ui/buttonStyle.ts) so neither setDestructive nor the legacy
  setWarning is referenced statically. Both call sites use it now.
- Popout-window compat: bare setTimeout/clearTimeout -> window.* in
  SandboxBridge, WebFetchTool, regexSafetyProbe, EditReviewPanel.
- no-unsafe-* in FirstRunWizardModal: route the untyped _generated/
  imports through the existing castGenerated<T>() helper.
- Floating promises in AutocompleteHandler: fireAndForget() adapter
  keeps onSelect synchronous and logs rejections instead of dropping them.
- CSS partial-support: drop text-decoration-thickness/-color longhands
  in styles.css; the line-through strike stays.

sandbox-worker.ts and relayWorkerCode.ts keep bare timers on purpose
(Node child_process / Cloudflare Worker, no window) -- the bot does not
flag them.

Verification: tsc clean, full suite green (4811 passed, 1 expected fail),
build + deploy ok, 0 errors in bot scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 06:49:32 +02:00

8754 lines
220 KiB
CSS

/* Obsidian Agent - Styles (Kilo Code Pattern) */
/* Sidebar min-width: prevent buttons from being cut off (FEATURE-1907) */
.workspace-leaf-content[data-type="obsilo-agent-sidebar"] {
min-width: 320px;
}
/* ── Sandbox iframe (Self-Development Phase 3) ──────────────────────── */
.agent-sandbox-iframe {
display: none;
position: absolute;
width: 0;
height: 0;
border: 0;
}
/* Sidebar Container */
.obsidian-agent-sidebar {
display: flex;
flex-direction: column;
height: 100%;
padding: 0;
/* Allow text selection in chat (override Obsidian's default sidebar behavior) */
user-select: text;
-webkit-user-select: text;
}
/* Header */
.agent-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.agent-title {
display: flex;
align-items: center;
gap: 6px;
font-size: 15.5px;
font-weight: 700;
font-family: Consolas, monospace;
color: var(--text-normal);
}
/* Sidebar header wordmark: monospace text in the form "/ Vault Operator". */
.agent-title-wordmark {
display: inline-block;
font-family: Consolas, "SF Mono", Menlo, Monaco, "Courier New", monospace;
font-size: 15px;
font-weight: 600;
letter-spacing: 0.01em;
color: var(--text-normal);
}
/* Vault Health Badge (FEATURE-1901 / BUG-025 2026-04-19):
* The badge is now a header-button styled like its neighbours. Colour comes
* from the severity-* class and drives the lucide heart-pulse icon via
* currentColor. Hidden via the shared `agent-u-hidden` utility when no
* findings exist. */
.health-badge {
cursor: pointer;
}
.health-badge .toolbar-icon {
color: currentColor;
}
.health-badge:hover {
opacity: 0.85;
}
/* Vault Health Repair Modal (FEATURE-1901, FIX-15) */
.vault-health-modal {
max-width: 600px;
}
.vault-health-top-tabs {
display: flex;
gap: 6px;
margin-bottom: 12px;
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 8px;
}
.vault-health-top-tab {
background: transparent;
border: none;
padding: 6px 12px;
cursor: pointer;
color: var(--text-muted);
font-weight: 500;
}
.vault-health-top-tab.is-active {
color: var(--text-normal);
border-bottom: 2px solid var(--interactive-accent);
}
.vault-health-knowledge-review-toolbar {
display: flex;
gap: 6px;
margin: 8px 0 12px 0;
}
/* IMP-19-01-01: Auto-fix CTA above the severity filter pills.
Plain text + button; no background, no border. */
.vault-health-autofix-banner {
display: flex;
flex-direction: column;
gap: 4px;
margin: 8px 0 12px 0;
}
.vault-health-autofix-label {
display: flex;
align-items: baseline;
gap: 6px;
font-weight: 600;
}
.vault-health-autofix-desc {
color: var(--text-muted);
font-size: 13px;
}
.vault-health-autofix-btn {
align-self: flex-start;
margin-top: 6px;
}
/* IMP-19-01-02: sticky apply-bar at the top of the Findings tab.
Stays visible while the user scrolls through long finding lists. */
.vault-health-apply-sticky {
position: sticky;
top: 0;
z-index: 10;
margin: 8px 0 12px 0;
padding: 6px 0;
background: var(--background-primary);
border-bottom: 1px solid var(--background-modifier-border);
}
.vault-health-apply-sticky-btn {
width: 100%;
}
.resolve-conflict-modal .resolve-conflict-actions,
.resolve-conflict-modal .resolve-conflict-confirm,
.batch-resolve-modal .batch-resolve-actions,
.batch-resolve-modal .batch-resolve-filter-row {
display: flex;
gap: 8px;
margin-top: 12px;
align-items: center;
}
.batch-resolve-modal .batch-resolve-filter-label {
margin-right: 12px;
}
.batch-resolve-modal .batch-resolve-counter,
.batch-resolve-modal .batch-resolve-preview {
margin: 8px 0;
color: var(--text-muted);
font-size: 13px;
}
.vault-health-severity {
display: inline-block;
min-width: 54px;
padding: 1px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
margin-right: 6px;
}
.vault-health-severity.severity-high {
background: var(--color-red);
color: var(--text-on-accent);
}
.vault-health-severity.severity-medium {
background: var(--color-orange);
color: var(--text-on-accent);
}
.vault-health-severity.severity-low {
background: var(--text-faint);
color: var(--background-primary);
}
/* Collapsible sections */
.vault-health-section {
margin: 8px 0;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
}
.vault-health-section-header {
padding: 8px 12px;
font-size: 13px;
cursor: pointer;
user-select: none;
}
.vault-health-section-header:hover {
background: var(--background-modifier-hover);
}
.vault-health-section-content {
padding: 4px 12px 12px;
}
.vault-health-tag-info {
color: var(--text-muted);
font-size: 11px;
font-style: italic;
}
/* Individual finding rows */
.vault-health-finding-row {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 0;
font-size: 13px;
}
.vault-health-finding-row input[type="checkbox"] {
flex-shrink: 0;
}
.vault-health-note-link {
color: var(--text-accent);
cursor: pointer;
border-bottom: 1px dotted currentColor;
}
.vault-health-note-link:hover {
color: var(--text-accent-hover);
}
.vault-health-path-count {
color: var(--text-muted);
font-size: 11px;
}
.vault-health-fix-preview {
padding: 2px 0 6px 28px;
font-size: 12px;
color: var(--text-muted);
}
.vault-health-finding-actions {
display: inline-flex;
gap: 2px;
margin-left: auto;
flex-shrink: 0;
}
.vault-health-icon-btn {
background: none;
border: 1px solid transparent;
padding: 4px 6px;
cursor: pointer;
color: var(--text-muted);
border-radius: 4px;
opacity: 0.6;
transition: opacity 0.15s ease, border-color 0.15s ease;
}
.vault-health-finding-row:hover .vault-health-icon-btn {
opacity: 1;
}
.vault-health-icon-btn-visible {
opacity: 0.6;
}
.vault-health-icon-btn:hover {
opacity: 1;
color: var(--interactive-accent);
border-color: var(--interactive-accent);
background: var(--background-modifier-hover);
}
.vault-health-reset-btn {
font-size: 12px;
color: var(--text-muted);
}
.vault-health-search-row {
margin-bottom: 8px;
}
.vault-health-search-input {
width: 100%;
padding: 6px 10px;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-primary);
font-size: 13px;
}
.vault-health-dismissed-list {
max-height: 300px;
overflow-y: auto;
}
.vault-health-empty {
color: var(--text-muted);
font-size: 12px;
font-style: italic;
}
/* Buttons + results */
.vault-health-btn-row {
display: flex;
gap: 8px;
margin-top: 16px;
justify-content: flex-end;
}
.vault-health-progress {
color: var(--text-muted);
font-style: italic;
}
.vault-health-results {
list-style: none;
padding: 0;
margin: 12px 0;
}
.vault-health-results li {
padding: 3px 0;
font-size: 13px;
}
.vault-health-remaining {
font-size: 12px;
color: var(--text-muted);
margin-top: 8px;
}
.vault-health-error {
color: var(--color-red);
font-size: 12px;
}
.health-badge.severity-high {
color: var(--color-red);
}
.health-badge.severity-medium {
color: var(--color-orange);
}
.health-badge.severity-low {
color: var(--text-muted);
}
.agent-meta {
font-size: 12px;
color: var(--text-muted);
}
/* Chat Wrapper (contains messages + history panel overlay) */
.chat-wrapper {
flex: 1;
position: relative;
overflow: hidden;
min-height: 0;
}
/* Chat Messages (compact layout: padding/gap merged from former duplicate
"Compact chat" section so the selector appears only once) */
.chat-messages {
height: 100%;
overflow-y: auto;
padding: 10px 12px;
padding-bottom: 140px; /* Safety margin: Input-Container ist ~120px hoch */
display: flex;
flex-direction: column;
gap: 6px;
}
.message {
display: flex;
flex-direction: column;
gap: 4px;
}
.message-content {
padding: 7px 10px;
border-radius: 8px;
max-width: 100%;
line-height: 1.45;
font-size: 13px;
user-select: text;
cursor: text;
transition: opacity 150ms ease-out;
}
/* v2.10.4: text selection in chat consolidated into one ruleset.
The view container already declares `user-select: text` (line 24);
the chat-specific selectors only need to keep that on through the
message subtree. Specificity is high enough to win over Obsidian's
default `.sidebar-view * { user-select: none }` without !important.
User feedback 2026-06-24: inline chat bubbles need the same rule.
When the panel mounts as a CM6 block widget the surrounding
`.cm-content` propagates the editor's `user-select: text` to the
widget, but Obsidian themes occasionally reset it on nested
markdown-rendered children. Re-declaring it on the inline-panel
bubble + descendants restores copy-from-response. */
.obsidian-agent-sidebar .message,
.obsidian-agent-sidebar .message-content,
.obsidian-agent-sidebar .user-message .message-content,
.obsidian-agent-sidebar .user-message .message-content *,
.obsidian-agent-sidebar .assistant-message .message-content,
.obsidian-agent-sidebar .assistant-message .message-content *,
.agent-inline-panel__body,
.agent-inline-panel__body *,
.agent-inline-panel__bubble,
.agent-inline-panel__bubble * {
user-select: text;
-webkit-user-select: text;
cursor: auto;
}
.message-content h1 {
margin-top: 0;
margin-bottom: 14px;
font-size: 20px;
font-weight: 700;
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 6px;
}
.message-content h2 {
margin-top: 18px;
margin-bottom: 10px;
font-size: 17px;
font-weight: 600;
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 4px;
}
.message-content h3 {
margin-top: 16px;
margin-bottom: 12px;
font-size: 16px;
font-weight: 600;
}
.message-content h4 {
margin-top: 16px;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
}
/* Tables */
.message-content table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
font-size: 13px;
}
.message-content th,
.message-content td {
border: 1px solid var(--background-modifier-border);
padding: 6px 10px;
text-align: left;
vertical-align: top;
}
.message-content th {
background: var(--background-secondary);
font-weight: 600;
}
.message-content tr:nth-child(even) {
background: var(--background-secondary-alt);
}
/* Callouts — smaller/subtler in chat context */
.message-content .callout {
margin: 10px 0 4px;
padding: 6px 10px;
font-size: 12px;
border-radius: 6px;
background: var(--background-secondary);
border-left: 3px solid var(--text-faint);
}
.message-content .callout .callout-title {
font-size: 12px;
font-weight: 600;
margin-bottom: 4px;
}
.message-content .callout .callout-icon {
width: 14px;
height: 14px;
}
.message-content p {
margin-bottom: 8px;
}
.message-content ul,
.message-content ol {
margin-left: 0;
padding-left: 16px;
margin-bottom: 8px;
}
.message-content li {
margin-bottom: 4px;
}
.user-message .message-content {
/* Light blue tint that mirrors the Chrome DevTools "selected line"
highlight: ~20% of the Obsidian accent over the chat background.
Picks up whatever --interactive-accent resolves to so users with
a custom accent in Appearance settings get their colour
automatically. */
background: color-mix(in srgb, var(--interactive-accent) 20%, var(--background-primary));
color: var(--text-normal);
align-self: flex-end;
max-width: 85%;
border-radius: 12px 12px 4px 12px;
padding: 6px 11px;
font-size: 13px;
cursor: text;
}
/* FEAT-24-08 / ADR-114 Steering-Hook: distinct visual for mid-run
corrections so the user can spot them in the chat history and tell
apart queued vs delivered vs discarded. */
.chat-message-steering {
align-items: flex-end;
}
.chat-message-steering .steering-marker {
display: flex;
align-items: center;
gap: 4px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.4px;
color: var(--text-muted);
align-self: flex-end;
padding-right: 4px;
}
.chat-message-steering .steering-marker-icon {
display: inline-flex;
align-items: center;
--icon-size: 12px;
}
.chat-message-steering .steering-marker-icon svg {
width: 12px;
height: 12px;
}
.chat-message-steering .message-content {
border-left: 3px solid var(--interactive-accent-hover, var(--interactive-accent));
background: var(--background-modifier-form-field, var(--background-secondary));
color: var(--text-normal);
border-radius: 12px 12px 4px 12px;
}
.chat-message-steering .steering-footer {
display: flex;
align-items: center;
gap: 4px;
font-size: 11px;
color: var(--text-muted);
align-self: flex-end;
padding-right: 4px;
}
.chat-message-steering .steering-footer-icon {
display: inline-flex;
align-items: center;
}
.chat-message-steering .steering-footer-icon svg {
width: 12px;
height: 12px;
}
.chat-message-steering.steering-pending .steering-footer {
color: var(--text-muted);
font-style: italic;
}
.chat-message-steering.steering-delivered .steering-footer {
color: var(--text-success, var(--color-green));
}
.chat-message-steering.steering-discarded .message-content {
opacity: 0.6;
border-left-color: var(--text-error, var(--color-red));
}
.chat-message-steering.steering-discarded .steering-footer {
color: var(--text-error, var(--color-red));
}
.assistant-message .message-content {
background: transparent;
border: none;
color: var(--text-normal);
padding: 2px 0 4px;
font-size: 13px;
cursor: text;
}
.message-section {
margin-top: 12px;
}
.message-cta {
margin-top: 16px;
margin-bottom: 0;
font-size: 13px;
color: var(--text-muted);
}
/* Tool Cards */
.tool-message {
background: var(--background-secondary-alt);
border-left: 3px solid var(--interactive-accent);
}
.tool-card {
padding: 12px;
}
.tool-name {
font-weight: 600;
margin-bottom: 4px;
}
.tool-target {
font-size: 12px;
color: var(--text-muted);
font-family: var(--font-monospace);
}
.tool-status {
margin-top: 8px;
font-size: 11px;
font-weight: 600;
flex-shrink: 0;
}
.tool-status.approved {
color: var(--color-green);
}
/* Approval Buttons */
.approval-buttons {
display: flex;
gap: 8px;
margin-top: 8px;
}
.approve-btn {
flex: 1;
padding: 6px 12px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 600;
transition: all 0.2s;
background: var(--color-green);
color: white;
}
.approve-btn:hover {
opacity: 0.8;
}
.deny-btn {
flex: 1;
padding: 6px 12px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 600;
transition: all 0.2s;
background: var(--color-red);
color: white;
}
.deny-btn:hover {
opacity: 0.8;
}
/* Checkpoint Indicators */
.checkpoint-message {
font-size: 12px;
color: var(--text-muted);
text-align: center;
padding: 4px 8px;
background: var(--background-secondary);
border-radius: 4px;
}
.checkpoint-indicator {
font-family: var(--font-monospace);
}
/* =============================================================== */
/* First-Run Wizard Modal (Phase 2.3) */
/* =============================================================== */
.vault-operator-wizard .wizard-header {
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 12px;
margin-bottom: 16px;
}
.vault-operator-wizard .wizard-header h2 {
margin: 0 0 4px 0;
font-size: 18px;
font-weight: 600;
color: var(--text-normal);
}
.vault-operator-wizard .wizard-header .wizard-step-counter {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.vault-operator-wizard .wizard-progress {
display: flex;
gap: 4px;
margin: 0 0 20px 0;
}
.vault-operator-wizard .wizard-progress-segment {
flex: 1;
height: 4px;
border-radius: 2px;
background: var(--background-modifier-border);
transition: background-color 0.15s ease;
}
.vault-operator-wizard .wizard-progress-segment.active {
background: var(--interactive-accent);
}
.vault-operator-wizard .wizard-body {
min-height: 320px;
padding: 0 0 8px 0;
}
.vault-operator-wizard .wizard-body p {
margin: 0 0 12px 0;
line-height: 1.5;
}
.vault-operator-wizard .wizard-section {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
margin: 20px 0 8px;
padding: 0 0 4px;
border-bottom: 1px solid var(--background-modifier-border);
}
.vault-operator-wizard .wizard-section:first-child {
margin-top: 0;
}
.vault-operator-wizard .wizard-status {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
margin: 0 0 16px 0;
border-radius: 4px;
background: var(--background-secondary);
font-size: 13px;
}
.vault-operator-wizard .wizard-status-icon {
flex-shrink: 0;
display: flex;
color: var(--text-muted);
}
.vault-operator-wizard .wizard-status.is-ok .wizard-status-icon {
color: var(--color-green);
}
.vault-operator-wizard .wizard-status.is-empty .wizard-status-icon {
color: var(--text-muted);
}
.vault-operator-wizard .wizard-status strong {
font-weight: 600;
color: var(--text-normal);
}
.vault-operator-wizard .wizard-provider-card {
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px 14px;
margin: 8px 0;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-primary);
}
.vault-operator-wizard .wizard-provider-card.is-recommended {
border-color: var(--interactive-accent);
border-width: 2px;
padding: 11px 13px;
}
.vault-operator-wizard .wizard-provider-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
}
.vault-operator-wizard .wizard-provider-name {
font-weight: 600;
color: var(--text-normal);
}
.vault-operator-wizard .wizard-provider-badge {
display: inline-block;
padding: 2px 8px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
border-radius: 10px;
background: var(--background-modifier-border);
color: var(--text-muted);
}
.vault-operator-wizard .wizard-provider-badge.is-free {
background: color-mix(in srgb, var(--color-green) 15%, transparent);
color: var(--color-green);
}
.vault-operator-wizard .wizard-provider-badge.is-paid {
background: var(--background-modifier-border);
color: var(--text-muted);
}
.vault-operator-wizard .wizard-provider-badge.is-recommended {
background: var(--interactive-accent);
color: var(--text-on-accent);
}
.vault-operator-wizard .wizard-provider-link {
font-size: 12px;
color: var(--interactive-accent);
text-decoration: none;
}
.vault-operator-wizard .wizard-provider-link:hover {
text-decoration: underline;
}
.vault-operator-wizard .wizard-provider-note {
font-size: 13px;
color: var(--text-muted);
line-height: 1.5;
}
.vault-operator-wizard .wizard-action-row {
display: flex;
justify-content: flex-end;
margin-top: 16px;
}
.vault-operator-wizard .wizard-radio-row {
display: flex;
align-items: flex-start;
gap: 10px;
}
.vault-operator-wizard .wizard-radio-row input[type="radio"] {
margin-top: 4px;
}
.vault-operator-wizard .wizard-radio-row label {
flex: 1;
cursor: pointer;
}
.vault-operator-wizard .wizard-keyrow {
display: flex;
gap: 8px;
align-items: center;
margin-top: 10px;
}
.vault-operator-wizard .wizard-keyrow input {
flex: 1;
}
.vault-operator-wizard .wizard-asset-status {
font-size: 12px;
margin-top: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.vault-operator-wizard .wizard-asset-status.is-installed { color: var(--color-green); }
.vault-operator-wizard .wizard-asset-status.is-outdated { color: var(--color-orange); }
.vault-operator-wizard .wizard-asset-status.is-missing { color: var(--text-muted); }
.vault-operator-wizard .wizard-asset-status.is-error { color: var(--color-red); }
.vault-operator-wizard .wizard-asset-actions {
display: flex;
gap: 6px;
margin-top: 10px;
}
.vault-operator-wizard .wizard-skip-list {
margin-top: 12px;
padding: 10px 12px;
border-radius: 4px;
background: color-mix(in srgb, var(--color-orange) 8%, var(--background-primary));
border-left: 3px solid var(--color-orange);
font-size: 12px;
}
.vault-operator-wizard .wizard-footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
margin-top: 16px;
padding-top: 12px;
border-top: 1px solid var(--background-modifier-border);
}
.vault-operator-wizard .wizard-footer-left,
.vault-operator-wizard .wizard-footer-right {
display: flex;
gap: 6px;
}
/* AI Disclaimer (sits below the input area as a single small centred line) */
.chat-ai-disclaimer {
flex-shrink: 0;
text-align: center;
font-size: 9px;
line-height: 1.2;
color: var(--text-faint);
padding: 2px 12px 3px 12px;
background: var(--background-primary);
}
/* Chat Input Container (Kilo Code pattern) */
.chat-input-container {
flex-shrink: 0;
padding: 12px;
border-top: 1px solid var(--background-modifier-border);
background: var(--background-primary);
position: relative;
}
/* Unified bordered wrapper (like Kilo Code) */
.chat-input-wrapper {
display: flex;
flex-direction: column;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--input-background);
overflow: hidden;
}
/* Prevent themes from adding a focus ring/border-color change that creates a
visible line between the chips area and the textarea. Class-repetition
bumps specificity (0,3,0) so we don't need !important. */
.chat-input-wrapper.chat-input-wrapper:focus-within {
border-color: var(--background-modifier-border);
outline: none;
box-shadow: none;
}
/* Textarea */
.chat-textarea {
width: 100%;
height: var(--agent-textarea-h, auto);
padding: 12px;
border: none;
background: transparent;
resize: none;
font-family: var(--font-text);
font-size: 14px;
line-height: 1.5;
color: var(--text-normal);
min-height: 72px;
max-height: 360px;
overflow-y: auto;
}
.chat-textarea:focus {
outline: none;
}
.chat-textarea::placeholder {
color: var(--text-muted);
}
/* Chat Toolbar (integrated in input wrapper) */
.chat-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
border-top: 1px solid var(--background-modifier-border);
background: var(--background-secondary-alt);
}
.chat-toolbar-left {
display: flex;
align-items: center;
gap: 8px;
}
.chat-toolbar-right {
display: flex;
align-items: center;
gap: 6px;
}
/* Context chips inside input area (top of input wrapper) */
.chat-context-chips {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 8px 10px 0;
border-bottom: none;
}
.chat-context-chips:empty {
display: none;
}
.chat-context-chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 6px 2px 6px;
background: var(--background-modifier-border);
border-radius: 100px;
font-size: 11px;
font-family: var(--font-interface);
color: var(--text-muted);
max-width: 260px;
overflow: hidden;
cursor: default;
}
.context-chip-icon {
display: flex;
align-items: center;
flex-shrink: 0;
color: var(--text-faint);
}
.context-chip-icon svg {
width: 10px;
height: 10px;
}
.context-chip-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.context-chip-remove {
display: inline-flex;
align-items: center;
flex-shrink: 0;
margin-left: 1px;
color: var(--text-faint);
cursor: pointer;
opacity: 0;
transition: opacity 0.1s;
line-height: 1;
}
.chat-context-chip:hover .context-chip-remove {
opacity: 1;
}
.context-chip-remove svg {
width: 9px;
height: 9px;
}
/* Toolbar Buttons -- borderless by default, modern flat look. The send
* button is the single exception and re-introduces a border below.
* Class repetition (.toolbar-button.toolbar-button) bumps selector
* specificity to (0,2,0) so we overrule Obsidian's default button
* `box-shadow` / `border` from theme button selectors without using
* !important. */
.toolbar-button.toolbar-button {
display: flex;
align-items: center;
gap: 4px;
padding: 2px 6px;
border: none;
border-radius: 4px;
background: none;
box-shadow: none;
outline: none;
min-height: 0;
height: auto;
color: var(--text-normal);
cursor: pointer;
font-size: 12px;
transition: background 0.15s, color 0.15s;
}
.toolbar-button.toolbar-button:hover {
background: var(--background-modifier-hover);
box-shadow: none;
}
.toolbar-button.toolbar-button:focus,
.toolbar-button.toolbar-button:focus-visible {
box-shadow: none;
outline: none;
}
/* Ghost modifier kept for backward compatibility -- effectively the same
* look as the base button now, just muted text colour. */
.toolbar-button.toolbar-ghost {
color: var(--text-muted);
}
.toolbar-button.toolbar-ghost:hover {
color: var(--text-normal);
}
/* Web search toggle — active state */
.web-toggle-button.web-toggle-active {
color: var(--interactive-accent);
}
.web-toggle-button.web-toggle-active:hover {
color: var(--interactive-accent-hover);
}
.toolbar-icon {
display: flex;
align-items: center;
}
.toolbar-icon svg {
width: 16px;
height: 16px;
}
/* Mode Button — no border, icon + label + chevron, compact */
.mode-button {
min-width: unset;
background: none;
border: none;
color: var(--text-muted);
padding: 3px 5px;
font-size: 11px;
}
.mode-button:hover {
background: var(--background-modifier-hover);
border: none;
color: var(--text-normal);
}
.mode-label {
font-weight: 500;
font-size: 11px;
}
.mode-chevron {
display: flex;
align-items: center;
margin-left: 1px;
}
.mode-chevron svg {
width: 10px;
height: 10px;
}
/* Send Button -- the one toolbar button that keeps a border, by design.
* Sits visually apart from the borderless left-side cluster. Class repetition
* (.toolbar-button.send-button.send-button) bumps specificity to (0,3,0) so
* the bordered look wins over the borderless .toolbar-button.toolbar-button
* base without !important. */
.toolbar-button.send-button.send-button {
background: none;
color: var(--interactive-accent);
border: 1px solid var(--background-modifier-border);
padding: 3px 8px;
}
.toolbar-button.send-button.send-button:hover {
background: var(--background-modifier-hover);
color: var(--interactive-accent);
border-color: var(--interactive-accent);
}
.toolbar-button.send-button:active {
opacity: 0.7;
}
/* FEAT-33-12: Send-to-Sidebar button -- sits directly left of the Send
* button in the inline composer. Borderless, matches the toolbar idiom of
* the left-side cluster. The arrow-right-to-line icon makes the affordance
* read as "ship this thread off to the sidebar". */
.toolbar-button.send-to-sidebar-button {
background: none;
color: var(--text-muted);
padding: 3px 6px;
}
.toolbar-button.send-to-sidebar-button:hover {
color: var(--interactive-accent);
}
/* Stop Button -- replaces the send button while a task is running, so it
* inherits the same bordered shape for positional continuity. Same
* specificity bump pattern as .send-button. */
.toolbar-button.stop-button.stop-button {
background: none;
color: var(--text-muted);
border: 1px solid var(--background-modifier-border);
padding: 3px 8px;
}
.toolbar-button.stop-button.stop-button:hover {
background: var(--background-modifier-hover);
color: var(--color-red);
border-color: var(--color-red);
}
/* Streaming indicator (for Q&A mode, no tools) */
.message-streaming .message-content::after {
content: '▋';
animation: blink 1s step-end infinite;
color: var(--text-faint);
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* Header right (new chat button) */
.agent-header-right {
display: flex;
align-items: center;
gap: 6px;
}
/* Header buttons -- same borderless treatment as toolbar buttons. Class
* repetition (.header-button.header-button) bumps specificity to (0,2,0) so
* we beat the native <button> styling from the Obsidian theme without
* !important. */
.header-button.header-button {
display: flex;
align-items: center;
padding: 4px 6px;
border: none;
background: none;
box-shadow: none;
outline: none;
min-height: 0;
height: auto;
color: var(--text-muted);
cursor: pointer;
border-radius: 4px;
transition: color 0.1s, background 0.1s;
}
.header-button.header-button:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
box-shadow: none;
}
.header-button.header-button:focus,
.header-button.header-button:focus-visible {
box-shadow: none;
outline: none;
}
.header-button svg {
width: 16px;
height: 16px;
}
/* Browser-style chat nav arrows: bare icons, no chrome, set apart from
* the rest of the header controls. Modifier-only, additive on top of
* .header-button so the existing layout stays untouched. */
.header-button.header-button--nav {
padding: 0;
background: none;
border-radius: 0;
}
.header-button.header-button--nav:hover:not(:disabled) {
background: none;
}
.header-button.header-button--nav:disabled {
opacity: 0.35;
cursor: default;
}
/* Spacing: separate the nav cluster (now sitting at the far right of
* the header) from the primary controls to its left. Targets the FIRST
* nav arrow that immediately follows a non-nav header button. */
.header-button:not(.header-button--nav) + .header-button.header-button--nav {
margin-left: 10px;
}
/* SoakReportModal: a wide read-only textarea shows the JSON snapshot
* so the user can manually copy or save to vault. Modal owns focus
* which makes clipboard.writeText reliable. */
.vault-operator-soak-report-modal .vault-operator-soak-report-textarea {
width: 100%;
min-height: 360px;
font-family: var(--font-monospace);
font-size: 12px;
line-height: 1.45;
white-space: pre;
resize: vertical;
}
/* Tool call — borderless, subtle rows (Kilo Code style) */
.tool-call-details {
margin: 1px 0;
font-size: 11px;
overflow: hidden;
opacity: 0.65;
transition: opacity 100ms ease-out;
}
.tool-call-details:hover {
opacity: 1;
}
.tool-call-details[open] {
opacity: 1;
}
.tool-call-summary {
display: flex;
align-items: center;
gap: 4px;
padding: 2px 6px;
cursor: pointer;
color: var(--text-faint);
list-style: none;
user-select: none;
font-size: 11px;
}
.tool-call-summary::-webkit-details-marker {
display: none;
}
.tool-call-summary .tool-icon svg {
width: 10px;
height: 10px;
flex-shrink: 0;
}
.tool-call-summary .tool-name {
font-family: var(--font-monospace);
font-weight: normal;
margin-bottom: 0;
flex-shrink: 0;
font-size: 11px;
color: var(--text-muted);
}
.tool-call-summary .tool-brief-param {
flex: 1;
font-family: var(--font-monospace);
font-size: 10px;
color: var(--text-faint);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-left: 2px;
}
.tool-call-summary .tool-time {
font-size: 10px;
color: var(--text-faint);
flex-shrink: 0;
margin-left: 6px;
}
.tool-call-summary .tool-status {
flex-shrink: 0;
font-size: 10px;
width: 10px;
text-align: center;
}
.tool-call-summary .tool-running::after {
content: '';
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--text-faint);
animation: tool-pulse 1s ease-in-out infinite;
}
@keyframes tool-pulse {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.tool-call-summary .tool-done { color: var(--color-green); }
.tool-call-summary .tool-error { color: var(--color-red); }
.tool-diff-badge {
font-size: 11px;
color: var(--color-green);
background: var(--background-modifier-hover);
border-radius: 4px;
padding: 1px 5px;
margin-left: 4px;
font-family: var(--font-monospace);
}
/* .context-condensed-badge: superseded by the later definition near the
Timeline section. Dead in cascade order; kept only as a placeholder
comment so the rule is defined exactly once in this file. */
.tool-call-input,
.tool-call-output {
border-top: 1px solid var(--background-modifier-border);
padding: 4px 8px;
}
/* Grouped tool rows — compact list under a single collapsible header */
.tool-group-body {
padding: 2px 4px 4px 24px;
display: flex;
flex-direction: column;
gap: 1px;
}
.tool-group-item {
display: flex;
align-items: center;
gap: 5px;
padding: 1px 0;
font-size: 11px;
color: var(--text-faint);
transition: color 100ms ease-out;
}
.tool-group-item .tool-item-icon {
width: 10px;
height: 10px;
flex-shrink: 0;
display: flex;
align-items: center;
}
.tool-group-item .tool-item-icon svg { width: 10px; height: 10px; }
.tool-group-item.item-done { color: var(--text-muted); }
.tool-group-item.item-done .tool-item-icon { color: var(--color-green); }
.tool-group-item.item-error { color: var(--text-normal); }
.tool-group-item.item-error .tool-item-icon { color: var(--color-red); }
.tool-item-brief {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 280px;
font-family: var(--font-monospace);
}
.tool-call-input pre,
.tool-call-output pre {
margin: 0;
font-family: var(--font-monospace);
font-size: 11px;
color: var(--text-muted);
white-space: pre-wrap;
word-break: break-all;
}
.tool-status.tool-running {
color: var(--text-faint);
}
.tool-status.tool-done {
color: var(--color-green);
}
.tool-status.tool-error {
color: var(--color-red);
}
/* Token usage footer (Feature 6) */
.message-footer {
padding: 4px 12px 0;
font-size: 10px;
color: var(--text-faint);
font-family: var(--font-interface);
text-align: right;
}
/* FEAT-24-05: cost footer crossed the warn threshold */
.message-footer.agent-cost-warn {
color: var(--text-warning, var(--color-orange));
font-weight: var(--font-semibold, 600);
}
/* Error row inside steps block (Feature 5) */
.tool-step-error {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 6px 8px;
margin: 2px 0;
border-radius: 4px;
background: var(--background-modifier-error);
}
.tool-step-error .tool-step-icon {
flex-shrink: 0;
color: var(--text-error);
display: flex;
align-items: center;
}
.tool-step-error .tool-step-icon svg {
width: 14px;
height: 14px;
}
.tool-step-error .tool-step-text {
display: flex;
flex-direction: column;
gap: 2px;
}
.tool-step-error .error-title {
font-weight: 600;
font-size: 12px;
color: var(--text-error);
}
.tool-step-error .error-detail {
font-size: 11px;
color: var(--text-muted);
}
/* Markdown content reset for chat bubbles */
.assistant-message .message-content p:last-child {
margin-bottom: 0;
}
.assistant-message .message-content pre {
background: var(--code-background);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
padding: 6px 10px;
font-size: 12px;
overflow-x: auto;
}
.assistant-message .message-content code {
font-family: var(--font-monospace);
font-size: 12px;
background: var(--code-background);
padding: 1px 4px;
border-radius: 3px;
}
/* Disabled textarea during generation */
.chat-textarea:disabled {
opacity: 0.7;
cursor: not-allowed;
}
/* Scrollbar */
.chat-messages::-webkit-scrollbar,
.chat-textarea::-webkit-scrollbar {
width: 8px;
}
.chat-messages::-webkit-scrollbar-track,
.chat-textarea::-webkit-scrollbar-track {
background: var(--background-secondary);
}
.chat-messages::-webkit-scrollbar-thumb,
.chat-textarea::-webkit-scrollbar-thumb {
background: var(--background-modifier-border);
border-radius: 4px;
}
.chat-messages::-webkit-scrollbar-thumb:hover,
.chat-textarea::-webkit-scrollbar-thumb:hover {
background: var(--text-muted);
}
/* ── Model button (toolbar) — no border, label + chevron, compact ───────── */
.model-button {
flex-shrink: 0;
background: none;
border: none;
color: var(--text-muted);
padding: 3px 5px;
font-size: 11px;
}
.model-button:hover {
background: var(--background-modifier-hover);
border: none;
color: var(--text-normal);
}
.model-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.model-label {
white-space: nowrap;
font-size: 11px;
}
/* ── Provider badge ────────────────────────────────────────────────────── */
.provider-badge {
display: inline-block;
padding: 1px 5px;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
color: white;
white-space: nowrap;
background: var(--provider-bg, #607d8b);
}
/* ── Settings tab navigation ───────────────────────────────────────────── */
.agent-settings {
padding-top: 0;
}
.agent-settings-nav {
display: flex;
gap: 2px;
padding: 12px 0 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-settings-tab {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
font-size: 13px;
cursor: pointer;
margin-bottom: -1px;
border-radius: 4px 4px 0 0;
transition: color 0.1s;
}
.agent-settings-tab-icon {
display: flex;
align-items: center;
flex-shrink: 0;
}
.agent-settings-tab-icon svg { width: 14px; height: 14px; }
.agent-settings-tab:hover { color: var(--text-normal); }
.agent-settings-tab.active {
color: var(--text-normal);
border-bottom-color: var(--interactive-accent);
font-weight: 500;
}
.agent-settings-coffee-btn {
margin-left: auto;
display: inline-flex;
align-items: center;
align-self: center;
margin-bottom: 2px;
}
.agent-settings-coffee-btn .bmc-header-btn {
height: 26px;
width: auto;
display: block;
border-radius: 4px;
}
/* ── Sub-tab navigation ──────────────────────────────────────────────── */
.agent-settings-subnav {
display: flex;
gap: 2px;
padding: 10px 0 0;
border-bottom: 1px solid var(--background-modifier-border);
margin-bottom: 24px;
}
.agent-settings-subtab {
padding: 4px 12px;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
color: var(--text-muted);
font-size: 12px;
cursor: pointer;
transition: color 0.1s;
border-radius: 4px 4px 0 0;
}
.agent-settings-subtab:hover { color: var(--text-normal); }
.agent-settings-subtab.active {
color: var(--text-normal);
border-bottom-color: var(--interactive-accent);
font-weight: 500;
}
.agent-semantic-status {
margin-top: 4px;
font-weight: 500;
color: var(--text-muted);
}
/* ── Risk note for beta settings ────────────────────────────────────── */
.setting-risk-note {
margin-top: 4px;
font-size: 11px;
color: var(--text-error);
}
/* ── Excluded folder picker ─────────────────────────────────────────── */
.excluded-folder-list {
display: flex;
flex-wrap: wrap;
gap: 4px;
width: 100%;
margin-top: 2px;
padding-bottom: 10px;
}
.excluded-folder-chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 6px;
border-radius: 4px;
background: var(--background-modifier-hover);
font-size: 11px;
color: var(--text-muted);
}
.excluded-folder-remove {
cursor: pointer;
display: inline-flex;
align-items: center;
color: var(--text-faint);
}
.excluded-folder-remove:hover { color: var(--text-error); }
.excluded-folder-remove svg { width: 10px; height: 10px; }
.excluded-folder-input {
width: 100%;
font-size: 12px;
}
/* ── "Coming soon" empty state ───────────────────────────────────────── */
.agent-settings-coming-soon {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 48px 24px;
color: var(--text-muted);
text-align: center;
}
.agent-settings-coming-soon-icon {
display: flex;
align-items: center;
opacity: 0.35;
}
.agent-settings-coming-soon-icon svg { width: 32px; height: 32px; }
.agent-settings-coming-soon-title {
font-size: 14px;
font-weight: 500;
color: var(--text-normal);
}
.agent-settings-coming-soon-desc {
font-size: 12px;
line-height: 1.5;
max-width: 280px;
}
.agent-settings-content {
padding: 12px 0;
}
/* ── Model table ────────────────────────────────────────────────────────── */
.model-table {
width: 100%;
font-size: 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
overflow: hidden;
margin-bottom: 8px;
}
/* Models table: name | provider | key | enable-toggle | default-radio | actions */
.model-row {
display: grid;
grid-template-columns: 1fr 100px 36px 75px 66px 48px;
align-items: center;
padding: 5px 8px;
gap: 4px;
border-bottom: 1px solid var(--background-modifier-border);
}
/* Embeddings table: name | provider | key | active-radio | actions */
.embedding-table .model-row {
grid-template-columns: 1fr 100px 36px 66px 48px;
}
/* EPIC-26 / FEAT-26-03 -- Providers table: name | key | enable | default | actions */
.providers-table .model-row {
grid-template-columns: 1fr 36px 75px 66px 88px;
}
/* Two-line provider row: large label + tier summary sub-line */
.mc-name-sub {
font-size: 11px;
color: var(--text-muted);
margin-top: 2px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.model-row:last-child { border-bottom: none; }
.model-row-header {
background: var(--background-secondary);
color: var(--text-muted);
font-size: 10px;
font-weight: 500;
padding: 5px 8px;
line-height: 1.3;
}
.model-row-active .mc-name-text { color: var(--interactive-accent); }
.model-row-active .mc-name {
border-left: 2px solid var(--interactive-accent);
padding-left: 6px;
}
.model-row:not(.model-row-header):hover { background: var(--background-modifier-hover); }
.model-row-disabled { opacity: 0.5; }
.mc-name { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }
.mc-name-text { font-size: 12px; color: var(--text-normal); }
.mc-provider { overflow: hidden; }
/* Header cells - allow wrapping for longer localized texts */
.model-row-header .mc-enable,
.model-row-header .mc-default {
white-space: normal;
word-wrap: break-word;
text-align: center;
}
.mc-key { display: flex; align-items: center; justify-content: center; }
.mc-key svg { width: 12px; height: 12px; }
.mc-key-ok { color: var(--color-green); }
.mc-key-missing { color: var(--text-faint); }
/* ── Enable column — small toggle switch ─────── */
.mc-enable { display: flex; justify-content: center; align-items: center; }
.mc-toggle {
position: relative;
display: inline-block;
width: 28px;
height: 16px;
flex-shrink: 0;
cursor: pointer;
}
/* Spezifitaet 0,1,2 -- gleicht Theme-Selektoren wie
* `.workspace-leaf input[type='checkbox']` aus. Ohne den `[type='checkbox']`
* Anker rendert Obsidian seinen Default-iOS-Toggle on top auf unsere
* Custom-Pille (Doppel-Toggle). `appearance: none` plus explizite
* background/box-shadow/border-Resets entkoppeln den input von jedem
* Theme-Override. */
.mc-toggle input[type='checkbox'] {
appearance: none;
-webkit-appearance: none;
opacity: 0;
width: 0;
height: 0;
margin: 0;
padding: 0;
border: 0;
background: none;
box-shadow: none;
position: absolute;
pointer-events: none;
}
.mc-toggle-track {
position: absolute;
inset: 0;
border-radius: 8px;
background: var(--background-modifier-border);
transition: background 0.18s;
}
.mc-toggle-track::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--background-primary);
transition: transform 0.18s;
}
.mc-toggle input:checked + .mc-toggle-track {
background: var(--interactive-accent);
}
.mc-toggle input:checked + .mc-toggle-track::after {
transform: translateX(12px);
}
/* ── Radio buttons (Models "Default" + Embeddings "Active") ── */
.mc-default { display: flex; justify-content: center; align-items: center; }
.mc-default input[type='radio'],
.mc-enable input[type='radio'] {
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
border: 2px solid var(--text-faint);
border-radius: 50%;
background: transparent;
cursor: pointer;
position: relative;
margin: 0;
flex-shrink: 0;
transition: border-color 0.15s;
}
.mc-default input[type='radio']::before,
.mc-enable input[type='radio']::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--interactive-accent);
transition: transform 0.15s;
}
.mc-default input[type='radio']:checked,
.mc-enable input[type='radio']:checked {
border-color: var(--interactive-accent);
}
.mc-default input[type='radio']:checked::before,
.mc-enable input[type='radio']:checked::before {
transform: translate(-50%, -50%) scale(1);
}
.mc-default input[type='radio']:disabled,
.mc-enable input[type='radio']:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.mc-actions { display: flex; gap: 4px; justify-content: flex-end; align-items: center; }
.mc-actions button { padding: 3px 5px; border-radius: 4px; }
.mc-action-btn {
display: flex;
align-items: center;
padding: 2px;
border: none;
background: transparent;
color: var(--text-muted);
cursor: pointer;
border-radius: 3px;
}
.mc-action-btn:hover { background: var(--background-modifier-hover); color: var(--text-normal); }
.mc-action-del:hover { color: var(--color-red); }
.mc-action-btn svg { width: 13px; height: 13px; }
.model-table-footer { margin-top: 4px; margin-bottom: 24px; display: flex; gap: 6px; align-items: center; }
.model-add-btn { font-size: 12px; padding: 4px 10px; }
.model-import-btn {
font-size: 12px;
padding: 4px 10px;
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
cursor: pointer;
}
.model-import-btn:hover { background: var(--background-modifier-hover); }
/* ── Code Import Modal ─────────────────────────────────────────────────── */
.code-import-modal { max-width: 560px; }
.cim-title-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.cim-title { margin: 0; font-size: 14px; }
.cim-experimental-tag {
display: inline-block;
padding: 1px 7px;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
background: var(--color-yellow);
color: var(--background-primary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.cim-instructions { font-size: 12px; color: var(--text-muted); margin-bottom: 10px; line-height: 1.5; }
.cim-textarea {
width: 100%;
min-height: 200px;
font-family: var(--font-monospace);
font-size: 12px;
line-height: 1.5;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
color: var(--text-normal);
resize: vertical;
box-sizing: border-box;
tab-size: 4;
}
.cim-textarea:focus { outline: none; border-color: var(--color-accent); }
.cim-textarea::placeholder { color: var(--text-faint); font-size: 11px; }
.cim-parse-row { display: flex; justify-content: flex-end; margin: 6px 0; }
.cim-parse-btn {
font-size: 12px;
padding: 4px 10px;
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
cursor: pointer;
}
.cim-parse-btn:hover { background: var(--background-modifier-hover); }
.cim-preview-box {
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
padding: 10px 12px;
font-size: 12px;
margin-bottom: 8px;
}
.cim-preview-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.cim-format-tag {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
background: var(--background-modifier-border);
color: var(--text-muted);
text-transform: capitalize;
}
.cim-provider-sel {
font-size: 12px;
padding: 2px 6px;
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
}
.cim-preview-field { display: flex; gap: 8px; align-items: baseline; margin-bottom: 4px; }
.cim-field-label { color: var(--text-muted); font-size: 11px; min-width: 80px; flex-shrink: 0; }
.cim-field-value { color: var(--text-normal); font-family: var(--font-monospace); font-size: 11px; word-break: break-all; }
.cim-models-section { margin-top: 8px; border-top: 1px solid var(--background-modifier-border); padding-top: 8px; }
.cim-models-header { font-size: 11px; font-weight: 500; color: var(--text-muted); margin-bottom: 6px; }
.cim-models-list { display: flex; flex-direction: column; gap: 3px; }
.cim-model-item { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 2px 4px; border-radius: 3px; }
.cim-model-icon { display: flex; align-items: center; flex-shrink: 0; }
.cim-model-icon svg { width: 12px; height: 12px; }
.cim-ok { color: var(--color-green); }
.cim-warn { color: var(--color-yellow); }
.cim-model-name { font-family: var(--font-monospace); color: var(--text-normal); }
.cim-model-dup { font-size: 10px; color: var(--text-faint); font-style: italic; }
.cim-model-note { display: block; font-size: 10px; color: var(--text-muted); margin-left: 22px; margin-top: 1px; }
.cim-warnings { margin-bottom: 8px; }
.cim-warning-item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--color-yellow); padding: 3px 0; }
.cim-warning-icon { display: flex; align-items: center; flex-shrink: 0; }
.cim-warning-icon svg { width: 12px; height: 12px; }
.cim-apikey-row { margin-bottom: 10px; }
.cim-apikey-label { font-size: 12px; color: var(--text-muted); margin-bottom: 2px; }
.cim-apikey-desc { font-size: 10px; color: var(--text-faint); margin-bottom: 4px; }
.cim-apikey-input {
width: 100%;
padding: 4px 8px;
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
font-size: 12px;
box-sizing: border-box;
}
/* Temperature row */
.cim-temp-row { margin-bottom: 10px; }
.cim-temp-label { font-size: 12px; color: var(--text-muted); margin-bottom: 2px; }
.cim-temp-desc { font-size: 10px; color: var(--text-faint); margin-bottom: 4px; }
.cim-temp-desc.cim-temp-fixed { color: var(--color-yellow); }
.cim-temp-input {
width: 80px;
padding: 4px 8px;
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
font-size: 12px;
}
.cim-temp-input:disabled { opacity: 0.6; cursor: not-allowed; }
/* Test Connection row */
.cim-test-row { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.cim-test-btn {
flex-shrink: 0;
font-size: 12px;
padding: 4px 12px;
}
.cim-test-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.cim-test-result { display: none; font-size: 11px; align-items: center; gap: 4px; flex: 1; min-width: 0; }
.cim-test-result.cim-test-ok { display: flex; color: var(--color-green); }
.cim-test-result.cim-test-fail { display: block; color: var(--color-red); }
.cim-test-icon { display: inline-flex; align-items: center; flex-shrink: 0; }
.cim-test-icon svg { width: 14px; height: 14px; }
.cim-test-hint { font-size: 10px; color: var(--color-yellow); margin-top: 4px; }
.cim-test-detail { font-size: 10px; color: var(--text-muted); margin-top: 4px; word-break: break-word; }
.cim-actions { display: flex; gap: 6px; justify-content: flex-end; padding-top: 10px; border-top: 1px solid var(--background-modifier-border); }
.cim-import-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.model-table-empty {
padding: 20px 12px;
color: var(--text-muted);
font-size: 12px;
text-align: center;
font-style: italic;
}
.model-table-desc {
font-size: 12px;
color: var(--text-muted);
margin-bottom: 10px;
line-height: 1.5;
}
/* ── Model Config Modal ─────────────────────────────────────────────────── */
.model-config-modal .modal-title { margin: 0 0 12px; font-size: 14px; }
.mcm-form { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
/* Label column has a fixed max-width so the input column keeps a usable
amount of space. Long explanatory descriptions are moved into the (i)
info-popover next to the label (see wireMcmDescTooltips), so the label
column itself stays short.
Affects ModelConfigModal AND ProviderDetailModal (both use .mcm-row). */
.mcm-row {
display: grid;
grid-template-columns: minmax(140px, 200px) minmax(180px, 1fr);
align-items: center;
gap: 12px;
font-size: 12px;
}
.mcm-label {
color: var(--text-muted);
display: flex;
flex-direction: row;
align-items: center;
gap: 6px;
min-width: 0;
overflow-wrap: anywhere;
}
/* Hidden by default: the .mcm-desc spans live in the DOM so the helper
can read their text and attach a tooltip-icon, but they no longer
render inline. Per-element opt-out via .mcm-desc.is-inline. */
.mcm-desc {
display: none;
font-size: 10px;
color: var(--text-faint);
line-height: 1.35;
}
.mcm-desc.is-inline {
display: inline;
}
.mcm-input, .mcm-select {
width: 100%;
padding: 4px 8px;
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
font-size: 12px;
}
.mcm-input-sm { max-width: 100px; }
/* suggest row: select + fetch button */
.mcm-suggest-controls {
display: flex;
gap: 6px;
align-items: center;
}
.mcm-suggest-sel {
flex: 1;
min-width: 0;
}
.mcm-fetch-btn {
flex-shrink: 0;
display: flex;
align-items: center;
padding: 4px 6px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-modifier-form-field);
color: var(--text-muted);
cursor: pointer;
transition: color 0.15s, border-color 0.15s;
}
.mcm-fetch-btn:hover {
color: var(--text-normal);
border-color: var(--text-muted);
}
.mcm-fetch-btn svg {
width: 13px;
height: 13px;
}
.mcm-recommend-btn {
flex-shrink: 0;
background: transparent;
border: none;
box-shadow: none;
padding: 0 4px;
color: var(--text-accent);
cursor: pointer;
font-size: var(--font-ui-smaller);
white-space: nowrap;
}
.mcm-recommend-btn:hover {
text-decoration: underline;
}
.mcm-checkbox-line {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 6px;
font-size: var(--font-ui-smaller);
color: var(--text-muted);
}
.mcm-checkbox-line input[type="checkbox"] {
flex-shrink: 0;
}
.mcm-actions {
display: flex;
gap: 6px;
justify-content: flex-end;
padding-top: 10px;
border-top: 1px solid var(--background-modifier-border);
}
/* EPIC-26 / FEAT-26-03 Welle A follow-up: compact form-control wrapper
used by ProviderDetailModal so each row matches ModelConfigModal's
12px / 110px-label layout. Right-aligns buttons + toggles in the
same column as inputs/selects. */
.provider-detail-modal .mcm-control {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 6px;
min-width: 0;
}
.provider-detail-modal .mcm-control .mcm-input,
.provider-detail-modal .mcm-control .mcm-select {
flex: 1 1 auto;
}
.provider-detail-modal .mcm-btn {
padding: 4px 10px;
font-size: 12px;
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
cursor: pointer;
}
.provider-detail-modal .mcm-btn:hover {
background: var(--background-modifier-hover);
}
.provider-detail-modal .mcm-btn.mod-cta {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: transparent;
}
.provider-detail-modal .mcm-btn.mod-cta:hover {
background: var(--interactive-accent-hover, var(--interactive-accent));
}
.provider-detail-modal .mcm-btn.mod-warning {
color: var(--text-error, var(--color-red));
border-color: var(--background-modifier-border);
}
.provider-detail-modal .mcm-btn.mod-warning:hover {
background: var(--background-modifier-error-hover, var(--background-modifier-hover));
}
/* EPIC-26 / FEAT-26-03 -- inline label-line so a tier badge sits next
to the row label without breaking the .mcm-label vertical stack.
nowrap keeps the info-button glued to the label text (AUDIT-030
follow-up: prior `flex-wrap: wrap` pushed the `(i)` to a new line
when label + icon exceeded the grid column width). */
.mcm-label .mcm-label-line {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: nowrap;
white-space: nowrap;
}
/* Info-icon next to a setting name. Just the Lucide `info` glyph in
muted color, nothing else. Class repetition (.agent-info-btn.agent-info-btn)
bumps specificity to (0,2,0) on the plain selector and the descendant form
already sits at (0,3,0), so both forms overrule Obsidian's default
.setting-item button styling without !important. */
.agent-info-btn.agent-info-btn,
.setting-item .setting-item-name .agent-info-btn {
background: transparent;
background-color: transparent;
border: none;
box-shadow: none;
padding: 0;
margin: 0 0 0 6px;
cursor: pointer;
color: var(--text-faint);
display: inline-flex;
align-items: center;
vertical-align: middle;
line-height: 0;
border-radius: 0;
}
.agent-info-btn.agent-info-btn:hover,
.setting-item .setting-item-name .agent-info-btn:hover {
color: var(--text-normal);
background: transparent;
background-color: transparent;
box-shadow: none;
}
.agent-info-btn:focus-visible {
outline: 1px solid var(--interactive-accent);
outline-offset: 2px;
border-radius: 50%;
}
.agent-info-btn svg { width: 14px; height: 14px; }
/* Info-popover opened by clicking .agent-info-btn. Centered overlay
with a dismiss-on-backdrop click and Escape-key shortcut. Body text
matches the Obsidian setting-item-description size so the visual
register stays consistent with the surrounding settings UI. */
.agent-info-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.25);
z-index: var(--layer-modal, 1000);
display: flex;
align-items: center;
justify-content: center;
}
.agent-info-popover {
background: var(--background-primary);
color: var(--text-normal);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
max-width: 420px;
width: calc(100% - 48px);
padding: 14px 16px 16px;
}
.agent-info-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 6px;
}
.agent-info-title {
font-weight: var(--font-semibold);
color: var(--text-normal);
font-size: 13px;
}
/* Modal close button. Class repetition bumps specificity to (0,2,0) so we
* defeat the Obsidian default button styling inside .modal-* containers
* without !important. */
.agent-info-close.agent-info-close {
background: transparent;
background-color: transparent;
border: none;
box-shadow: none;
padding: 2px;
margin: 0;
cursor: pointer;
color: var(--text-muted);
display: inline-flex;
line-height: 0;
}
.agent-info-close.agent-info-close:hover {
color: var(--text-normal);
background: transparent;
background-color: transparent;
}
.agent-info-close svg { width: 14px; height: 14px; }
.agent-info-body {
font-size: 12px;
line-height: 1.5;
color: var(--text-muted);
}
/* Slider with inline, click-to-edit value display. Track on the left,
value on the right inside the same control. Reads as one widget,
not as a slider plus a separate input box. */
.agent-slider-wrap {
display: flex;
align-items: center;
gap: 8px;
min-width: 180px;
}
.agent-slider {
flex: 1;
min-width: 0;
cursor: pointer;
}
.agent-slider-value {
min-width: 38px;
text-align: right;
font-variant-numeric: tabular-nums;
font-size: 12px;
color: var(--text-normal);
padding: 2px 6px;
border-radius: 4px;
border: 1px solid transparent;
cursor: pointer;
user-select: none;
}
.agent-slider-value:hover,
.agent-slider-value:focus-visible {
background: var(--background-modifier-hover);
outline: none;
}
.agent-slider-value-editing {
min-width: 38px;
text-align: right;
font-variant-numeric: tabular-nums;
font-size: 12px;
color: var(--text-normal);
padding: 0;
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
background: transparent;
cursor: text;
user-select: none;
}
.agent-slider-input.agent-slider-input {
width: 100%;
min-width: 38px;
padding: 2px 6px;
font-size: 12px;
font-variant-numeric: tabular-nums;
text-align: right;
background: transparent;
border: none;
box-shadow: none;
color: var(--text-normal);
}
.agent-slider-input:focus { outline: none; box-shadow: none; }
.agent-slider-input::-webkit-inner-spin-button,
.agent-slider-input::-webkit-outer-spin-button {
display: none;
margin: 0;
}
/* EPIC-26 follow-up #3 -- tier row in ProviderDetailModal.
* Custom grid (label left, control right) so the colored tier badge
* sits right-aligned ABOVE the dropdown instead of inline with the
* tier label (where it overlapped the description text). */
.provider-detail-modal .mcm-tier-row {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(220px, 320px);
gap: 18px;
align-items: start;
padding: 10px 0;
border-top: 1px solid var(--background-modifier-border);
}
.provider-detail-modal .mcm-tier-row:first-of-type { border-top: none; }
.provider-detail-modal .mcm-tier-label-col { min-width: 0; }
.provider-detail-modal .mcm-tier-label {
font-weight: 600;
color: var(--text-normal);
margin-bottom: 2px;
}
.provider-detail-modal .mcm-tier-desc {
color: var(--text-muted);
font-size: 12px;
line-height: 1.4;
}
.provider-detail-modal .mcm-tier-control-col {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
}
.provider-detail-modal .mcm-tier-badge-top {
align-self: flex-end;
font-size: 10px;
font-weight: 700;
padding: 1px 6px;
border-radius: 3px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.provider-detail-modal .mcm-tier-dropdown {
width: 100%;
max-width: 320px;
}
.provider-detail-modal .mcm-tier-manual-back {
font-size: 11px;
padding: 2px 8px;
cursor: pointer;
}
/* FIX-55-02 (issue #55): free-text model-id input. Text-input look, same
width as the tier dropdowns. Previously carried the 'dropdown' class,
which Obsidian styles for <select> elements and which breaks an input. */
.provider-detail-modal .mcm-tier-manual-input {
width: 100%;
max-width: 320px;
font-size: 12px;
padding: 4px 8px;
border: 1px solid var(--background-modifier-border);
border-radius: var(--input-radius, 5px);
background: var(--background-primary);
color: var(--text-normal);
}
/* EPIC-26 / FEAT-26-03 -- section header inside .mcm-form */
.mcm-section {
font-size: 12px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
margin: 14px 0 4px;
padding-bottom: 4px;
border-bottom: 1px solid var(--background-modifier-border);
}
.mcm-form > .mcm-section:first-child { margin-top: 4px; }
/* Inline warning row inside the form (e.g. "Advisor disabled"). Rendered as a
plain block child of contentEl, no grid context above, so no grid override
needed. */
.mcm-warn {
color: var(--text-warning, var(--text-accent));
font-size: 12px;
padding: 6px 8px;
background: var(--background-modifier-error-hover, var(--background-secondary));
border-radius: 4px;
}
.mcm-warn-icon { display: inline-flex; align-items: center; vertical-align: middle; }
.mcm-warn-icon svg { width: 14px; height: 14px; }
/* Inline hint row (faint italic) e.g. "Save first, then refresh". Plain block,
no grid parent. */
.mcm-hint {
font-size: 11px;
color: var(--text-faint);
font-style: italic;
padding: 4px 8px;
}
/* Danger-style button (matches mod-warning convention) */
.mcm-btn-danger {
background: var(--background-secondary);
border: 1px solid var(--background-modifier-error, var(--text-error));
border-radius: 4px;
color: var(--text-error);
padding: 4px 10px;
font-size: 12px;
cursor: pointer;
}
.mcm-btn-danger:hover { background: var(--background-modifier-error-hover, var(--background-modifier-hover)); }
.mcm-btn-test {
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-normal);
padding: 4px 10px;
font-size: 12px;
cursor: pointer;
margin-right: auto;
}
.mcm-btn-test:hover { background: var(--background-modifier-hover); }
.mcm-test-result {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 8px;
border-radius: 4px;
font-size: 11px;
margin-top: 4px;
}
.mcm-ok {
background: color-mix(in srgb, var(--color-green) 12%, transparent);
color: var(--color-green);
border: 1px solid color-mix(in srgb, var(--color-green) 25%, transparent);
}
.mcm-err {
background: color-mix(in srgb, var(--color-red) 12%, transparent);
color: var(--color-red);
border: 1px solid color-mix(in srgb, var(--color-red) 25%, transparent);
}
.mcm-result-icon { display: flex; align-items: center; flex-shrink: 0; }
.mcm-result-icon svg { width: 12px; height: 12px; }
/* ── Provider setup guide ───────────────────────────────────────────────── */
.mcm-guide {
margin-bottom: 4px;
}
.mcm-guide-inner {
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
padding: 10px 12px;
font-size: 12px;
color: var(--text-muted);
line-height: 1.6;
}
.mcm-guide-inner strong {
color: var(--text-normal);
font-size: 12px;
display: block;
margin-bottom: 6px;
}
.mcm-guide-steps {
margin: 0 0 6px 16px;
padding: 0;
}
.mcm-guide-steps li {
margin-bottom: 3px;
}
.mcm-guide-steps a {
color: var(--interactive-accent);
text-decoration: none;
}
.mcm-guide-steps a:hover {
text-decoration: underline;
}
.mcm-guide-steps code {
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
padding: 0 4px;
font-family: var(--font-monospace);
font-size: 11px;
}
.mcm-guide-tip {
font-size: 11px;
color: var(--text-faint);
margin-top: 4px;
}
/* Custom provider table */
.mcm-guide-table {
width: 100%;
border-collapse: collapse;
margin: 6px 0;
font-size: 11px;
}
.mcm-guide-table tr:not(:last-child) td {
border-bottom: 1px solid var(--background-modifier-border);
}
.mcm-guide-table td {
padding: 3px 6px;
vertical-align: top;
}
.mcm-guide-service {
font-weight: 500;
color: var(--text-normal);
white-space: nowrap;
width: 80px;
}
.mcm-guide-url code {
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
padding: 0 4px;
font-family: var(--font-monospace);
font-size: 10px;
color: var(--text-muted);
white-space: nowrap;
}
/* ── Test result detail ─────────────────────────────────────────────────── */
.mcm-result-header {
display: flex;
align-items: center;
gap: 6px;
font-weight: 500;
}
.mcm-result-detail {
margin-top: 6px;
padding-top: 6px;
border-top: 1px solid currentColor;
opacity: 0.85;
font-size: 11px;
white-space: pre-line;
line-height: 1.6;
}
/* ── Ollama model browser ───────────────────────────────────────────────── */
.mcm-ollama-browser {
grid-column: 1 / -1;
margin: -2px 0 2px;
display: flex;
flex-direction: column;
gap: 6px;
}
.mcm-browse-btn {
align-self: flex-start;
width: fit-content;
display: flex;
align-items: center;
gap: 5px;
padding: 3px 10px;
font-size: 11px;
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
}
.mcm-browse-icon {
display: flex;
align-items: center;
}
.mcm-browse-icon svg {
width: 12px;
height: 12px;
}
.mcm-browse-btn:hover:not(:disabled) {
background: var(--background-modifier-hover);
color: var(--text-normal);
}
.mcm-browse-btn:disabled {
opacity: 0.5;
cursor: wait;
}
.mcm-model-list {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 6px 8px;
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
max-height: 120px;
overflow-y: auto;
}
.mcm-model-item {
padding: 2px 8px;
font-size: 11px;
font-family: var(--font-monospace);
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
color: var(--text-normal);
cursor: pointer;
}
.mcm-model-item:hover {
background: var(--background-modifier-hover);
border-color: var(--interactive-accent);
}
.mcm-model-item-selected {
background: color-mix(in srgb, var(--interactive-accent) 15%, transparent);
border-color: var(--interactive-accent);
color: var(--interactive-accent);
font-weight: 500;
}
.mcm-model-empty {
font-size: 11px;
color: var(--text-muted);
font-style: italic;
padding: 2px 0;
}
/* ── Compact chat (overrides merged into earlier blocks; only context-
specific selectors below remain unique to this section) ──────────── */
/* User message: right-aligned pill, compact */
.user-message {
align-items: flex-end;
}
/* user-message .message-content base styles merged into the earlier
block (line 383 area); only context-specific selectors remain below. */
/* Selection highlight: deeper tint of the accent so text stays readable
against the very light user-message bubble. */
.user-message .message-content::selection,
.user-message .message-content *::selection {
background: color-mix(in srgb, var(--interactive-accent) 30%, transparent);
color: var(--text-normal);
}
.user-message .message-content::-moz-selection,
.user-message .message-content *::-moz-selection {
background: color-mix(in srgb, var(--interactive-accent) 30%, transparent);
color: var(--text-normal);
}
/* User message action bar (copy, edit) */
.user-message-actions {
display: flex;
gap: 1px;
justify-content: flex-end;
opacity: 0;
margin-top: 2px;
transition: opacity 0.15s;
}
.user-message:hover .user-message-actions {
opacity: 1;
}
/* Assistant-message bubble styles merged into the earlier block
(line 390 area). user-select is granted by the consolidated rule
.obsidian-agent-sidebar .assistant-message .message-content. */
/* Visible selection highlighting for assistant messages */
.assistant-message .message-content::selection,
.assistant-message .message-content *::selection {
background: var(--text-selection);
color: var(--text-normal);
}
.assistant-message .message-content::-moz-selection,
.assistant-message .message-content *::-moz-selection {
background: var(--text-selection);
color: var(--text-normal);
}
/* Assistant-message pre/code styles merged into the earlier block
(line 1349 area). */
/* Tool calls now live inside .message-tools wrapper */
.message-tools {
display: flex;
flex-direction: column;
gap: 1px;
margin-bottom: 2px;
}
/* ── Agent steps block ──────────────────────────────────────────────────── */
/* All tool calls for one turn are grouped under a single collapsible block. */
/* A thin left border replaces the old individual card borders. */
.agent-steps-block {
border-left: 2px solid var(--background-modifier-border);
padding-left: 8px;
margin: 2px 0 4px;
border-radius: 4px; /* Subtile Abrundung */
}
/* Hide the native disclosure triangle */
.agent-steps-block > summary {
list-style: none;
}
.agent-steps-block > summary::-webkit-details-marker {
display: none;
}
/* Summary line: icon + label, single row */
.agent-steps-summary {
display: flex;
align-items: center;
gap: 5px;
padding: 2px 0;
cursor: pointer;
user-select: none;
color: var(--text-muted);
font-size: 11px;
}
.agent-steps-summary:hover {
color: var(--text-normal);
}
/* Spinning loader icon inside summary */
.steps-icon {
display: flex;
align-items: center;
justify-content: center;
width: 12px;
height: 12px;
flex-shrink: 0;
}
.steps-icon svg {
width: 12px;
height: 12px;
}
/* Label text */
.steps-label {
font-family: var(--font-monospace);
font-size: 11px;
}
/* Body: individual tool call <details> elements */
.agent-steps-body {
display: flex;
flex-direction: column;
gap: 1px;
padding-top: 3px;
}
/* Individual tool entries inside the block are slightly more compact */
.agent-steps-body .tool-call-details {
margin: 0;
}
/* ── Auto-approve bar ─────────────────────────────────────────────────── */
/* Auto-approve bar removed — approval managed in Settings */
/* ── Completion card ─────────────────────────────────────────────────── */
.completion-card {
display: flex;
flex-direction: column;
gap: 4px;
padding: 5px 8px;
margin-top: 4px;
border-radius: 4px;
border-left: 3px solid var(--color-green);
background: color-mix(in srgb, var(--color-green) 7%, transparent);
font-size: 12px;
}
.completion-card-header {
display: flex;
align-items: center;
gap: 5px;
color: var(--color-green);
font-weight: 500;
font-size: 12px;
}
.completion-icon { display: flex; align-items: center; }
.completion-icon svg { width: 13px; height: 13px; }
.completion-body { color: var(--text-normal); font-size: 12px; }
.completion-body p { margin-bottom: 3px; }
.completion-body p:last-child { margin-bottom: 0; }
/* ── Question card (Kilo Code style) ─────────────────────────────────── */
/* ── Todo Box ────────────────────────────────────────────────────────────── */
.agent-todo-box {
margin: 4px 0 2px;
border: 1px solid var(--background-modifier-border);
border-left: 3px solid var(--interactive-accent);
border-radius: 4px;
background: var(--background-secondary);
overflow: hidden;
}
.todo-box-header {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 8px 4px;
border-bottom: 1px solid var(--background-modifier-border);
}
.todo-box-icon {
font-size: 12px;
color: var(--interactive-accent);
}
.todo-box-title {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
}
.todo-box-list {
padding: 4px 0;
}
.todo-item {
display: flex;
align-items: baseline;
gap: 7px;
padding: 2px 10px;
font-size: 12px;
line-height: 1.5;
}
.todo-item-icon {
font-size: 10px;
flex-shrink: 0;
min-width: 10px;
}
.todo-item-text {
color: var(--text-normal);
}
.todo-done .todo-item-icon { color: #4caf50; }
.todo-done .todo-item-text { color: var(--text-muted); text-decoration: line-through; }
.todo-in-progress .todo-item-icon { color: var(--interactive-accent); }
.todo-in-progress .todo-item-text { color: var(--text-normal); font-weight: 500; }
.todo-pending .todo-item-icon { color: var(--text-faint); }
.todo-pending .todo-item-text { color: var(--text-muted); }
/* ── Activity log (collapsed tool calls inside Plan box) ─────────────────── */
.todo-activity-log {
margin-top: 4px;
border-top: 1px solid var(--background-modifier-border);
padding-top: 0;
}
.todo-activity-summary {
font-size: 11px;
color: var(--text-faint);
cursor: pointer;
list-style: none;
padding: 3px 8px;
user-select: none;
display: flex;
align-items: center;
gap: 6px;
}
.todo-activity-summary::-webkit-details-marker { display: none; }
.todo-activity-badge {
font-size: 10px;
color: var(--text-faint);
background: var(--background-secondary);
padding: 1px 6px;
border-radius: 8px;
}
/* ── Followup / question list (unified layout) ─────────────────────────── */
/* Used for both [followups] blocks at end of responses AND ask_followup_question cards */
.followup-list {
margin-top: 10px;
padding-top: 0;
}
.followup-heading {
font-size: var(--font-ui-small);
color: var(--text-normal);
font-weight: 500;
margin-bottom: 8px;
line-height: 1.5;
}
.followup-item-row {
position: relative;
margin-bottom: 4px;
}
.followup-append-btn {
position: absolute;
right: 6px;
top: 50%;
transform: translateY(-50%);
width: 22px;
height: 22px;
padding: 0;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-muted);
font-size: 13px;
font-weight: 600;
line-height: 20px;
text-align: center;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
pointer-events: none;
}
.followup-item-row:hover .followup-append-btn {
opacity: 1;
pointer-events: auto;
}
.followup-append-btn:hover {
border-color: var(--interactive-accent);
color: var(--interactive-accent);
background: var(--background-modifier-hover);
}
/* Class-repetition (.followup-item.followup-item) bumps specificity to
(0,2,0) so we override default button/list-item styles without
needing !important on white-space and height. */
.followup-item.followup-item {
position: relative;
display: block;
width: 100%;
box-sizing: border-box;
text-align: left;
white-space: normal;
word-wrap: break-word;
overflow-wrap: break-word;
height: auto;
min-height: 0;
max-width: 100%;
overflow: visible;
padding: 6px 32px 6px 12px;
margin: 3px 0;
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
background: var(--background-secondary);
color: var(--text-muted);
font-size: 12px;
cursor: pointer;
transition: border-color 0.15s, color 0.15s, background 0.15s;
line-height: 1.45;
}
.followup-item:hover {
border-color: var(--interactive-accent);
color: var(--text-normal);
background: var(--background-modifier-hover);
}
/* Multi-select mode */
.followup-item-selected {
border-color: var(--interactive-accent);
background: var(--interactive-accent);
color: var(--text-on-accent);
}
.followup-item-selected:hover {
opacity: 0.9;
}
.followup-confirm-btn {
display: block;
width: 100%;
margin-top: 6px;
padding: 8px 12px;
border-radius: 8px;
border: 1px solid var(--interactive-accent);
background: var(--interactive-accent);
color: var(--text-on-accent);
font-size: 13px;
font-weight: 600;
font-family: inherit;
cursor: pointer;
transition: opacity 0.15s ease;
}
.followup-confirm-btn:hover {
opacity: 0.85;
}
/* ── Setup Welcome Buttons ─────────────────────────────────────────────── */
.setup-welcome-buttons {
display: flex;
gap: 8px;
margin-top: 14px;
}
.setup-welcome-btn {
padding: 8px 18px;
border-radius: 8px;
border: 1px solid var(--background-modifier-border);
cursor: pointer;
font-size: 13px;
font-family: inherit;
transition: all 0.15s ease;
}
.setup-welcome-btn-primary {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
font-weight: 600;
}
.setup-welcome-btn-primary:hover {
opacity: 0.85;
}
.setup-welcome-btn-secondary {
background: var(--background-secondary);
color: var(--text-muted);
}
.setup-welcome-btn-secondary:hover {
color: var(--text-normal);
border-color: var(--interactive-accent);
}
/* ── Disabled onboarding buttons (after choice is made) ──────────────── */
.setup-btn-disabled {
opacity: 0.4;
cursor: default;
pointer-events: none;
}
/* ── Provider selection buttons (2x2 grid) ───────────────────────────── */
.setup-provider-buttons {
flex-wrap: wrap;
}
.setup-provider-buttons .setup-welcome-btn {
flex: 1 1 calc(50% - 4px);
min-width: 0;
text-align: center;
}
.question-input-row {
display: flex;
gap: 5px;
align-items: center;
margin-top: 4px;
padding-left: 10px;
}
.question-input {
flex: 1;
padding: 3px 7px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-size: 12px;
}
.question-submit-btn {
padding: 3px 10px;
background: var(--interactive-accent);
color: var(--text-on-accent);
border: none;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
}
/* ── Inline approval row (within tool call area) ─────────────────────── */
.tool-approval-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
padding: 10px 12px; /* Mehr Padding für bessere Sichtbarkeit */
margin: 8px 0; /* Mehr Abstand zu anderen Elementen */
border-radius: 8px; /* Konsistent mit Message-Bubbles */
border: 1px solid color-mix(in srgb, #f0a020 30%, var(--background-modifier-border));
background: color-mix(in srgb, #f0a020 4%, transparent);
font-size: 12px;
}
.tool-approval-icon { display: flex; align-items: center; color: #f0a020; flex-shrink: 0; }
.tool-approval-icon svg { width: 11px; height: 11px; }
.tool-approval-text {
flex: 1;
color: var(--text-muted);
font-size: 11px;
}
.tool-approval-actions { display: flex; gap: 3px; flex-shrink: 0; }
.tool-approval-btn {
padding: 1px 7px;
border-radius: 3px;
border: 1px solid transparent;
font-size: 11px;
cursor: pointer;
}
.approval-allow-once {
background: var(--color-green);
color: white;
border-color: var(--color-green);
}
.approval-enable {
background: transparent;
color: var(--text-muted);
border-color: var(--background-modifier-border);
}
.approval-enable:hover {
border-color: var(--interactive-accent);
color: var(--interactive-accent);
}
/* configDir write warning — Shai Hulud Mitigation */
.tool-approval-config-warning {
width: 100%;
display: flex;
align-items: flex-start;
gap: 6px;
padding: 6px 8px;
margin-top: 2px;
border-radius: 4px;
background: color-mix(in srgb, var(--color-red) 8%, transparent);
border: 1px solid color-mix(in srgb, var(--color-red) 25%, var(--background-modifier-border));
}
.tool-approval-warning-icon { display: flex; align-items: center; color: var(--color-red); flex-shrink: 0; margin-top: 1px; }
.tool-approval-warning-icon svg { width: 12px; height: 12px; }
.tool-approval-warning-text { color: var(--color-red); font-size: 11px; line-height: 1.4; }
.approval-deny-small {
background: transparent;
color: var(--text-faint);
border: none;
padding: 1px 4px;
}
.approval-deny-small:hover { color: var(--color-red); }
/* ── Install-prompt row (in-chat asset install consent) ──────────────── */
.tool-approval-row.install-prompt-row {
/* Slightly cooler tone than the amber approval row so the two never blur */
border-color: color-mix(in srgb, var(--interactive-accent) 30%, var(--background-modifier-border));
background: color-mix(in srgb, var(--interactive-accent) 4%, transparent);
}
.tool-approval-row.install-prompt-row .tool-approval-icon { color: var(--interactive-accent); }
.tool-approval-row.install-prompt-row .tool-approval-text {
color: var(--text-normal);
font-weight: 500;
}
.tool-approval-row.install-prompt-row .tool-approval-explanation {
color: var(--text-muted);
font-size: 11px;
width: 100%;
line-height: 1.45;
}
.tool-approval-row.install-prompt-row .tool-approval-explanation.is-hidden {
display: none;
}
/* Human-readable explanation in approval card */
.tool-approval-explanation {
width: 100%;
display: flex;
flex-wrap: wrap;
gap: 4px;
font-size: 12px;
color: var(--text-normal);
line-height: 1.4;
margin-top: 2px;
}
.tool-approval-target {
font-weight: 600;
color: var(--text-normal);
word-break: break-all;
}
/* FEAT-44-02b: scope-only batch approval -- planned file list on the card */
.tool-approval-scope {
width: 100%;
margin-top: 4px;
font-size: 12px;
color: var(--text-normal);
}
.tool-approval-scope-summary {
font-weight: 600;
line-height: 1.4;
}
.tool-approval-scope-heading {
margin-top: 4px;
color: var(--text-muted);
}
.tool-approval-scope-list {
margin: 4px 0 0;
padding: 6px 8px 6px 24px;
background: var(--background-secondary);
border-radius: 4px;
font-family: var(--font-monospace);
font-size: 11px;
line-height: 1.5;
max-height: 160px;
overflow-y: auto;
word-break: break-all;
}
.tool-approval-scope-more {
margin-top: 2px;
font-size: 11px;
color: var(--text-muted);
font-style: italic;
}
.tool-approval-code-preview {
width: 100%;
margin-top: 4px;
}
.tool-approval-code-preview code {
display: block;
font-size: 11px;
font-family: var(--font-monospace);
background: var(--background-secondary);
border-radius: 4px;
padding: 6px 8px;
white-space: pre-wrap;
word-break: break-all;
max-height: 80px;
overflow-y: auto;
color: var(--text-muted);
}
.tool-approval-fo-preview {
width: 100%;
margin-top: 4px;
font-size: 11px;
color: var(--text-normal);
background: var(--background-secondary);
border-radius: 4px;
padding: 6px 8px;
}
.tool-approval-fo-preview-sample {
color: var(--text-muted);
}
.tool-approval-details-toggle {
width: 100%;
font-size: 11px;
color: var(--text-faint);
cursor: pointer;
margin-top: 2px;
}
/* IMP-41-03-05: background research task status tile above the input */
.background-task-tile {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
font-size: 11px;
color: var(--text-muted);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
margin-bottom: 4px;
}
.background-task-tile-label {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.background-task-tile-stop {
font-size: 11px;
padding: 1px 8px;
}
/* IMP-41-01-02: countdown shown during the final 60s before auto-deny */
.tool-approval-countdown {
font-size: 11px;
color: var(--text-faint);
margin-left: auto;
align-self: center;
}
.tool-approval-details-toggle:hover {
color: var(--interactive-accent);
text-decoration: underline;
}
.tool-approval-details {
width: 100%;
display: none;
}
.tool-approval-details.is-visible {
display: block;
}
.tool-approval-details-content {
font-size: 11px;
font-family: var(--font-monospace);
background: var(--background-secondary);
border-radius: 4px;
padding: 6px 8px;
margin: 4px 0 0 0;
white-space: pre-wrap;
word-break: break-all;
max-height: 120px;
overflow-y: auto;
color: var(--text-muted);
line-height: 1.4;
}
/* ── Checkpoint markers (Kilo Code pattern) ──────────────────────────── */
.checkpoint-marker {
display: flex;
align-items: center;
gap: 6px;
padding: 2px 0;
margin: 4px 0;
font-size: 11px;
color: var(--text-faint);
opacity: 0.5;
transition: opacity 0.15s;
}
.checkpoint-marker:hover {
opacity: 1;
}
.checkpoint-marker::before {
content: '';
flex: 1;
height: 1px;
background: linear-gradient(to right, transparent, var(--background-modifier-border));
pointer-events: none;
}
.checkpoint-marker::after {
content: '';
flex: 1;
height: 1px;
background: linear-gradient(to left, transparent, var(--background-modifier-border));
pointer-events: none;
}
.checkpoint-icon {
display: flex;
align-items: center;
}
.checkpoint-icon svg {
width: 12px;
height: 12px;
}
.checkpoint-label {
white-space: nowrap;
font-size: 10px;
}
/* Action row -- always visible ghost icon buttons.
* Pattern adapted from Kilo Code's CheckpointMenu
* (forked-kilocode/webview-ui/src/components/chat/checkpoints/CheckpointMenu.tsx):
* three primary actions in a row + a "more" overflow for the rarely-used
* "Delete chat from here" option. Borderless, transparent, icon-only,
* tooltip via aria-label. */
.checkpoint-actions {
display: flex;
gap: 2px;
align-items: center;
margin-left: 2px;
}
.checkpoint-action-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
padding: 0;
background: transparent;
border: none;
border-radius: 3px;
color: var(--text-faint);
cursor: pointer;
opacity: 0.5;
box-shadow: none;
transition: opacity 0.15s, color 0.15s, background 0.15s;
}
.checkpoint-marker:hover .checkpoint-action-btn {
opacity: 0.8;
}
.checkpoint-action-btn:hover {
opacity: 1;
color: var(--interactive-accent);
background: var(--background-modifier-hover);
}
.checkpoint-action-btn svg {
width: 13px;
height: 13px;
}
/* FIX-44-12: rehydrated marker whose snapshot the shadow repo no longer holds
(pruned refs). Dimmed, no action buttons; the aria-label tooltip says why. */
.checkpoint-marker-expired {
opacity: 0.55;
cursor: help;
}
.checkpoint-restored {
color: var(--color-green);
font-size: 10px;
margin-left: auto;
}
/* ── Undo bar (fallback) ─────────────────────────────────────────────── */
.undo-bar {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
margin: 2px 0;
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
font-size: 11px;
color: var(--text-muted);
}
.undo-label { flex: 1; }
.undo-btn {
padding: 2px 8px;
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
color: var(--text-muted);
font-size: 11px;
cursor: pointer;
white-space: nowrap;
}
.undo-btn:hover {
border-color: var(--interactive-accent);
color: var(--interactive-accent);
}
.undo-success { color: var(--color-green); }
.undo-error { color: var(--color-red); }
/* ── Settings section headings ───────────────────────────────────────── */
.agent-settings-section {
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
text-align: left;
margin: 24px 0 8px;
padding: 0 0 4px;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-settings-section:first-child { margin-top: 2px; }
.agent-settings-section .agent-info-btn {
/* Section headings are uppercase muted, so keep the info icon
in the same muted tone. The 6 px gap from the flex container
already provides the left margin. */
margin-left: 0;
color: var(--text-faint);
}
/* Plain explanatory paragraph that sits directly under a section
heading. Used when the section title alone is not enough to
convey the model, e.g. the cross-surface receive-side policy.
Same register as setting-item-description: muted, 12 px, no
coloured background. */
.agent-settings-section-hint {
font-size: 12px;
line-height: 1.5;
color: var(--text-muted);
margin: 0 0 12px;
padding: 0;
background: transparent;
border: none;
}
/* Pinned-to-memory star: always visible (status indicator), accent
colour, no fill -- the regular `star` icon stays as outline. */
.history-row-action.history-row-action-pinned {
color: var(--text-accent);
opacity: 1;
}
.agent-settings-soul-intro {
margin: 4px 0 16px 0;
padding: 10px 14px;
background: var(--background-secondary);
border-left: 3px solid var(--interactive-accent);
border-radius: 4px;
font-size: 12px;
color: var(--text-muted);
}
.agent-settings-soul-intro p {
margin: 0;
}
.agent-settings-soul-intro p + p {
margin-top: 6px;
}
.agent-settings-soul-block {
margin: 10px 0;
padding: 10px 12px;
background: var(--background-secondary);
border-radius: 6px;
border: 1px solid var(--background-modifier-border);
}
.agent-settings-soul-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.agent-settings-soul-header h4 {
margin: 0;
font-size: 13px;
font-weight: 600;
color: var(--text-normal);
}
.agent-settings-soul-desc {
margin-top: 4px;
font-size: 11px;
color: var(--text-muted);
line-height: 1.4;
}
.agent-settings-soul-desc-example {
color: var(--text-faint);
font-style: italic;
}
.agent-settings-soul-header button {
width: 22px;
height: 22px;
line-height: 1;
padding: 0;
border-radius: 4px;
cursor: pointer;
}
.agent-settings-soul-empty {
margin-top: 8px;
font-size: 12px;
color: var(--text-faint);
font-style: italic;
}
.agent-settings-soul-list {
margin: 8px 0 0 0;
padding: 0;
list-style: none;
}
.agent-settings-soul-list li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 4px 0;
font-size: 13px;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-settings-soul-list li:last-child {
border-bottom: none;
}
.agent-settings-soul-text {
flex: 1 1 auto;
color: var(--text-normal);
}
.agent-settings-soul-remove {
background: none;
border: 1px solid var(--background-modifier-border);
color: var(--text-muted);
font-size: 11px;
padding: 2px 8px;
border-radius: 3px;
cursor: pointer;
}
.agent-settings-soul-remove:hover {
color: var(--text-error);
}
/* Memory viewer modal (FEATURE-0319b).
v2.10.4: switched from :has() to an explicit container class set by
MemoryViewerModal.onOpen() to avoid the :has() warning from the
review-bot. Visual behaviour identical. */
.memory-viewer-modal-container {
width: min(900px, 92vw);
max-width: none;
}
.memory-viewer-modal {
width: 100%;
}
.memory-viewer-intro {
font-size: 12px;
color: var(--text-muted);
margin: 0 0 6px 0;
}
.memory-viewer-stats {
font-size: 11px;
color: var(--text-faint);
margin: 0 0 12px 0;
}
.memory-viewer-tabs {
display: flex;
gap: 4px;
margin: 0 0 10px 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.memory-viewer-tab {
background: none;
border: none;
border-bottom: 2px solid transparent;
padding: 6px 12px;
font-size: 12px;
color: var(--text-muted);
cursor: pointer;
margin-bottom: -1px;
}
.memory-viewer-tab:hover {
color: var(--text-normal);
}
.memory-viewer-tab-active {
color: var(--text-accent);
border-bottom-color: var(--text-accent);
}
.memory-viewer-filter {
margin-bottom: 12px;
}
.memory-viewer-filter input {
width: 100%;
padding: 6px 10px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-secondary);
color: var(--text-normal);
font-size: 13px;
}
.memory-viewer-section {
margin: 18px 0;
}
.memory-viewer-section-header h3 {
margin: 0;
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 4px;
}
.memory-viewer-section-desc {
font-size: 11px;
color: var(--text-muted);
margin: 4px 0 8px 0;
}
.memory-viewer-empty {
font-size: 12px;
color: var(--text-faint);
font-style: italic;
padding: 4px 0;
}
.memory-viewer-list {
margin: 0;
padding: 0;
list-style: none;
}
.memory-viewer-item {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 8px 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.memory-viewer-item:last-child {
border-bottom: none;
}
.memory-viewer-item-main {
flex: 1 1 auto;
min-width: 0;
}
.memory-viewer-item-text {
font-size: 13px;
color: var(--text-normal);
line-height: 1.4;
word-break: break-word;
}
.memory-viewer-item-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 6px;
}
.memory-viewer-tag {
font-size: 10px;
padding: 1px 6px;
border-radius: 3px;
background: var(--background-modifier-border);
color: var(--text-muted);
text-transform: lowercase;
}
.memory-viewer-tag-primary {
background: var(--interactive-accent);
color: var(--text-on-accent);
font-weight: 500;
}
.memory-viewer-item-meta {
font-size: 11px;
color: var(--text-faint);
margin-top: 4px;
}
.memory-viewer-item-actions {
flex-shrink: 0;
display: flex;
gap: 2px;
align-self: flex-start;
}
.memory-viewer-item-edit,
.memory-viewer-item-delete {
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
padding: 4px;
border-radius: 3px;
}
.memory-viewer-item-edit:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.memory-viewer-item-delete:hover {
color: var(--text-error);
background: var(--background-modifier-hover);
}
.memory-viewer-footer {
display: flex;
align-items: center;
gap: 12px;
margin-top: 24px;
padding-top: 16px;
border-top: 1px dashed var(--background-modifier-border);
}
.memory-viewer-wipe {
background: var(--background-modifier-error);
color: var(--text-on-accent, #ffffff);
border: 1px solid var(--background-modifier-error);
padding: 6px 14px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
}
.memory-viewer-wipe:hover {
background: var(--text-error);
border-color: var(--text-error);
}
.memory-viewer-footer-hint {
font-size: 11px;
color: var(--text-faint);
flex: 1;
}
.agent-settings-soul-import {
display: flex;
align-items: center;
gap: 10px;
margin: 16px 0 8px 0;
padding-top: 8px;
border-top: 1px dashed var(--background-modifier-border);
}
.agent-settings-soul-import button {
padding: 4px 10px;
font-size: 12px;
cursor: pointer;
}
.agent-settings-soul-import-hint {
font-size: 11px;
color: var(--text-faint);
}
.agent-settings-soul-caps {
margin: 16px 0;
}
.agent-settings-soul-caps summary {
cursor: pointer;
font-size: 12px;
color: var(--text-muted);
}
.agent-settings-soul-cap-list {
margin: 4px 0 0 16px;
padding: 0;
font-size: 12px;
color: var(--text-muted);
}
/* Plain paragraph -- neutral, no background. */
.agent-settings-paragraph {
font-size: 12px;
color: var(--text-muted);
line-height: 1.5;
margin: 8px 0 16px;
}
/* Inline muted hint or status text inside a settings tab. Plain
paragraph register, no coloured box -- the section info popover
carries the explanatory weight, and the coloured intro callout
at the top of each tab keeps higher visual priority. */
.agent-settings-desc {
font-size: 12px;
color: var(--text-muted);
line-height: 1.5;
margin: 6px 0 12px;
padding: 0;
background: transparent;
border: none;
border-radius: 0;
}
/* ── Unified box system (2026-05-18) ────────────────────────────────────
* One base class `.vault-op-box` plus a semantic modifier:
* --intro blue, tab introduction
* --info grey, helper / aside
* --warning amber, caution
* --error red, risk / failure
* Inner parts: .vault-op-box__icon, .vault-op-box__text, .vault-op-box__actions.
* Status badges (test result, enrichment progress) stay inline and use
* .vault-op-status with .is-ok / .is-error / .is-pending.
*/
.vault-op-box {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 13px;
line-height: 1.55;
margin: 0 0 20px;
padding: 14px 16px;
border: 1px solid color-mix(in srgb, var(--color-blue) 35%, var(--background-modifier-border));
border-left: 4px solid var(--color-blue);
border-radius: 6px;
background: color-mix(in srgb, var(--color-blue) 7%, var(--background-primary));
}
.vault-op-box__icon {
flex-shrink: 0;
margin-top: 2px;
display: flex;
color: var(--color-blue);
}
.vault-op-box__text {
flex: 1;
color: var(--text-normal);
}
.vault-op-box__text strong {
font-weight: var(--font-semibold);
color: var(--text-normal);
}
.vault-op-box__actions {
display: flex;
gap: 6px;
align-items: center;
flex-shrink: 0;
}
.vault-op-box--info {
border-color: var(--background-modifier-border);
border-left-color: var(--interactive-accent);
background: var(--background-secondary);
}
.vault-op-box--info .vault-op-box__icon { color: var(--interactive-accent); }
.vault-op-box--warning {
border-color: color-mix(in srgb, var(--color-yellow) 35%, var(--background-modifier-border));
border-left-color: var(--color-yellow);
background: color-mix(in srgb, var(--color-yellow) 7%, var(--background-primary));
}
.vault-op-box--warning .vault-op-box__icon { color: var(--color-yellow); }
.vault-op-box--error {
border-color: color-mix(in srgb, var(--text-error) 35%, var(--background-modifier-border));
border-left-color: var(--text-error);
background: color-mix(in srgb, var(--text-error) 7%, var(--background-primary));
}
.vault-op-box--error .vault-op-box__icon { color: var(--text-error); }
.vault-op-box--error .vault-op-box__text { color: var(--text-error); }
.vault-op-status {
font-size: 11px;
display: inline-flex;
align-items: center;
gap: 4px;
}
.vault-op-status.is-ok { color: var(--color-green); }
.vault-op-status.is-error { color: var(--text-error); }
.vault-op-status.is-pending { color: var(--text-muted); }
/* Compact Obsidian Setting items within the behavior tab */
.agent-settings-content .setting-item {
padding: 6px 0;
border-top: 1px solid var(--background-modifier-border-hover, rgba(0,0,0,0.06));
border-radius: 0;
}
.agent-settings-content .setting-item:first-of-type,
.agent-settings-content .agent-settings-section + .setting-item,
.agent-settings-content .agent-settings-desc + .setting-item,
.agent-settings-content .agent-semantic-status + .setting-item {
border-top: none;
}
/* Section headings — reset any inherited h3 padding/margin from Obsidian */
.agent-settings-content .agent-settings-section {
padding-left: 0;
padding-right: 0;
margin-left: 0;
margin-right: 0;
}
.agent-settings-content .setting-item-name {
font-size: 13px;
}
.agent-settings-content .setting-item-description {
font-size: 11px;
margin-top: 1px;
}
/* Suppress blinking cursor once tools have appeared (response will render on complete) */
.message-streaming .message-tools:not(:empty) ~ .message-content::after {
display: none;
}
/* Tool rows are fully opaque while the task is running — subtle only on hover after done */
.message-streaming .tool-call-details {
opacity: 1;
}
/* ── Thinking / Reasoning block ──────────────────────────────────────── */
.thinking-block {
margin-bottom: 5px;
border-left: 2px solid var(--background-modifier-border);
padding-left: 8px;
transition: opacity 150ms ease-out;
}
.thinking-header {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
color: var(--text-faint);
font-size: 11px;
user-select: none;
padding: 1px 0;
}
.thinking-header:hover { color: var(--text-muted); }
.thinking-spinner { display: flex; align-items: center; }
.thinking-spinner svg {
width: 11px;
height: 11px;
animation: thinking-spin 1.4s linear infinite;
}
@keyframes thinking-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.thinking-label { font-size: 11px; }
.thinking-content {
color: var(--text-muted);
font-size: 11px;
line-height: 1.4;
padding: 3px 0 2px;
white-space: pre-wrap;
word-break: break-word;
max-height: 200px;
overflow-y: auto;
}
/* ── Response action bar ─────────────────────────────────────────────── */
.message-actions {
display: flex;
gap: 1px;
align-items: center;
opacity: 1;
margin-top: 6px;
padding: 0 2px;
justify-content: flex-end;
}
/* ── Perplexity-style inline citations ──────────────────────────────── */
/* Inline citation badge [1], [2] */
.source-badge {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 9px;
font-weight: 600;
min-width: 15px;
height: 15px;
padding: 0 3px;
border-radius: 8px;
background: var(--background-modifier-border);
color: var(--text-muted);
cursor: pointer;
vertical-align: super;
margin: 0 1px;
line-height: 1;
transition: background 0.15s, color 0.15s;
}
.source-badge:hover {
background: var(--interactive-accent);
color: var(--text-on-accent);
}
/* Sources indicator next to action buttons */
.sources-indicator {
display: flex;
align-items: center;
gap: 4px;
font-size: 11px;
color: var(--text-faint);
cursor: pointer;
margin-right: auto;
padding: 2px 6px;
border-radius: 4px;
transition: color 0.1s, background 0.1s;
}
.sources-indicator:hover {
color: var(--text-muted);
background: var(--background-modifier-hover);
}
.sources-indicator-icon {
display: flex;
align-items: center;
}
.sources-indicator-icon svg {
width: 12px;
height: 12px;
}
/* Source popup (single source or panel) */
.source-popup {
position: fixed;
z-index: 1000;
top: var(--popup-top);
bottom: var(--popup-bottom);
left: var(--popup-left);
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
padding: 10px 14px;
max-width: 320px;
min-width: 180px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
font-size: 12px;
line-height: 1.4;
}
.source-popup-title {
font-weight: 600;
color: var(--text-accent);
cursor: pointer;
margin-bottom: 2px;
}
.source-popup-title:hover {
text-decoration: underline;
}
.source-popup-context {
color: var(--text-muted);
font-size: 11px;
}
/* Sources panel (all sources list) */
.sources-panel {
max-height: 300px;
overflow-y: auto;
}
.source-panel-row {
display: flex;
align-items: baseline;
gap: 6px;
padding: 4px 0;
flex-wrap: wrap;
}
.source-panel-row:not(:last-child) {
border-bottom: 1px solid var(--background-modifier-border);
}
.source-panel-row .source-badge {
flex-shrink: 0;
vertical-align: baseline;
}
.source-panel-title {
font-weight: 600;
color: var(--text-accent);
cursor: pointer;
}
.source-panel-title:hover {
text-decoration: underline;
}
.source-panel-context {
width: 100%;
color: var(--text-muted);
font-size: 11px;
padding-left: 21px;
}
.message-action-btn {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: none;
border-radius: 4px;
color: var(--text-faint);
cursor: pointer;
transition: color 0.1s, background 0.1s;
}
.message-action-btn:hover {
color: var(--text-muted);
background: var(--background-modifier-hover);
}
.message-action-btn svg {
width: 13px;
height: 13px;
}
/* ── Working / loading indicator ─────────────────────────────────────── */
.message-loading {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 0;
color: var(--text-faint);
font-size: 12px;
}
.message-loading-icon {
display: flex;
align-items: center;
}
.message-loading-icon svg {
width: 13px;
height: 13px;
animation: thinking-spin 1.4s linear infinite;
}
.message-loading-text {
color: var(--text-faint);
}
/* Hide the blinking cursor when the loading indicator is present.
v2.10.4: switched from :has(.message-loading) to an explicit
has-loading flag class set in createMessageEl() and removed in
removeLoading(). Avoids the :has() invalidation cost the
review-bot warns about. */
.message-streaming .message-content.has-loading::after {
display: none;
}
/* ── Between-iteration "Analyzing results…" indicator ──────────────── */
.tool-computing-row {
display: flex;
align-items: center;
gap: 5px;
padding: 2px 6px;
font-size: 11px;
color: var(--text-faint);
}
.tool-computing-icon {
display: flex;
align-items: center;
}
.tool-computing-icon svg {
width: 10px;
height: 10px;
animation: thinking-spin 1.4s linear infinite;
}
.tool-computing-text {
font-size: 11px;
color: var(--text-faint);
}
/* ── Attachment chip bar (input area) ────────────────────────────────── */
.chat-attachment-chips {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 6px 10px 0;
border-bottom: none;
}
.chat-attachment-chips:empty {
display: none;
}
.chat-attachment-chip {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 6px 2px 4px;
background: white;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
font-size: 11px;
color: var(--text-muted);
max-width: 180px;
overflow: hidden;
cursor: default;
}
.attachment-chip-thumb {
width: 32px;
height: 32px;
object-fit: cover;
border-radius: 3px;
flex-shrink: 0;
}
.attachment-chip-icon {
display: flex;
align-items: center;
flex-shrink: 0;
color: var(--text-faint);
}
.attachment-chip-icon svg { width: 11px; height: 11px; }
.attachment-chip-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 120px;
}
.attachment-chip-remove {
display: inline-flex;
align-items: center;
flex-shrink: 0;
margin-left: 1px;
color: var(--text-faint);
cursor: pointer;
opacity: 0;
transition: opacity 0.1s;
}
.chat-attachment-chip:hover .attachment-chip-remove { opacity: 1; }
.attachment-chip-remove svg { width: 9px; height: 9px; }
/* Drag-over highlight on input wrapper */
.chat-input-wrapper.drag-over {
border-color: var(--interactive-accent);
background: color-mix(in srgb, var(--interactive-accent) 5%, var(--input-background));
}
/* ── Attachment previews above user message bubble ───────────────────── */
.message-attachment-previews {
display: flex;
flex-wrap: wrap;
gap: 4px;
justify-content: flex-end;
margin-bottom: 4px;
max-width: 85%;
align-self: flex-end;
}
.message-attachment-chip {
display: inline-flex;
align-items: center;
gap: 3px;
padding: 2px 6px 2px 4px;
background: white;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
font-size: 11px;
color: var(--text-muted);
max-width: 200px;
overflow: hidden;
}
.message-attachment-chip .attachment-chip-thumb {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 4px;
}
.message-attachment-chip .attachment-chip-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ── "Current" badge on active file chip ─────────────────────────────── */
.attachment-current-badge {
display: inline-block;
padding: 0px 4px;
margin-left: 2px;
background: var(--interactive-accent);
color: var(--text-on-accent);
border-radius: 3px;
font-size: 9px;
font-weight: 600;
letter-spacing: 0.03em;
line-height: 1.6;
flex-shrink: 0;
}
/* ── Modes Settings Tab ────────────────────────────────────────────────── */
/* ── Modes Tab — Kilo Code style ────────────────────────────────────────── */
.modes-top-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.modes-select {
flex: 1;
min-width: 0;
padding: 6px 10px;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-primary);
color: var(--text-normal);
font-size: 0.92em;
cursor: pointer;
}
.modes-select optgroup {
font-weight: 700;
font-size: 0.88em;
color: var(--text-muted);
}
.modes-btn-group {
display: flex;
gap: 6px;
flex-shrink: 0;
}
.modes-top-btn {
white-space: nowrap;
}
/* Form area */
.modes-form-area {
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
padding: 16px;
background: var(--background-secondary);
}
.modes-field {
margin-bottom: 14px;
}
.modes-field-label {
display: block;
font-weight: 600;
font-size: 0.88em;
margin-bottom: 4px;
color: var(--text-normal);
}
.modes-field-desc {
font-size: 0.8em;
color: var(--text-muted);
margin-bottom: 6px;
line-height: 1.4;
}
.modes-textarea {
width: 100%;
font-family: var(--font-monospace);
font-size: 0.82em;
padding: 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
resize: vertical;
box-sizing: border-box;
}
.modes-textarea:disabled {
opacity: 0.55;
cursor: default;
}
.modes-groups-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px 12px;
padding: 8px 0;
}
.modes-group-row {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.85em;
color: var(--text-muted);
}
.modes-group-row input[type="checkbox"]:disabled {
opacity: 0.5;
cursor: default;
}
/* Customized badge (built-in modes with user overrides) */
.modes-customized-badge {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 10px;
margin-bottom: 12px;
background: color-mix(in srgb, var(--interactive-accent) 8%, transparent);
border: 1px solid color-mix(in srgb, var(--interactive-accent) 30%, transparent);
border-radius: 6px;
font-size: 12px;
}
.modes-customized-icon {
display: flex;
align-items: center;
color: var(--interactive-accent);
}
.modes-customized-icon svg {
width: 13px;
height: 13px;
}
.modes-customized-text {
color: var(--interactive-accent);
font-weight: 500;
}
.modes-restore-btn {
font-size: 12px;
padding: 3px 10px;
background: transparent;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
}
.modes-restore-btn:hover:not(:disabled) {
color: var(--text-normal);
border-color: var(--text-muted);
}
.modes-restore-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* Bottom action bar */
.modes-bottom-bar {
display: flex;
align-items: center;
gap: 8px;
margin-top: 16px;
padding-top: 12px;
border-top: 1px solid var(--background-modifier-border);
}
.modes-active-badge {
font-size: 0.82em;
font-weight: 600;
color: var(--color-green);
margin-right: auto;
}
.modes-export-btn {
margin-left: auto;
}
.modes-delete-btn {
margin-left: 4px;
}
.modes-preview-btn {
/* sits before export — no extra margin needed */
}
/* Tools header row (label + Edit button) */
.modes-tools-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 4px;
}
.modes-tools-header .modes-field-label {
margin-bottom: 0;
}
.modes-edit-tools-btn {
font-size: 0.8em;
padding: 2px 10px;
border: 1px solid var(--interactive-accent);
color: var(--interactive-accent);
background: transparent;
border-radius: 4px;
cursor: pointer;
flex-shrink: 0;
}
.modes-edit-tools-btn:hover {
background: var(--interactive-accent);
color: var(--text-on-accent);
}
.modes-tools-list {
font-size: 0.88em;
color: var(--text-muted);
line-height: 1.6;
display: block;
margin-top: 2px;
}
.modes-tools-none {
font-size: 0.88em;
color: var(--text-faint);
font-style: italic;
display: block;
margin-top: 2px;
}
.modes-group-desc {
font-size: 0.82em;
color: var(--text-muted);
font-weight: normal;
}
/* Global Custom Instructions section */
.modes-global-section {
margin-top: 24px;
padding-top: 16px;
border-top: 1px solid var(--background-modifier-border);
}
.modes-global-section h3 {
margin-top: 0;
margin-bottom: 6px;
}
/* ── System Prompt Preview Modal ───────────────────────────────────────── */
.system-prompt-preview-modal {
max-width: 800px;
}
.system-prompt-preview-pre {
font-family: var(--font-monospace);
font-size: 0.78em;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-word;
padding: 12px;
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
overflow-y: auto;
max-height: 70vh;
color: var(--text-normal);
}
/* ── New Mode Modal ─────────────────────────────────────────────────────── */
.new-mode-modal .new-mode-groups {
margin: 10px 0;
}
.new-mode-groups-label,
.new-mode-field-label {
display: block;
font-weight: 600;
font-size: 0.88em;
margin-bottom: 4px;
color: var(--text-normal);
}
.new-mode-groups-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px 12px;
margin-bottom: 10px;
}
.new-mode-group-row {
display: flex;
align-items: center;
gap: 5px;
font-size: 0.85em;
color: var(--text-muted);
}
.new-mode-textarea {
width: 100%;
font-family: var(--font-monospace);
font-size: 0.82em;
padding: 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
resize: vertical;
margin-bottom: 12px;
box-sizing: border-box;
}
.new-mode-actions {
display: flex;
gap: 8px;
justify-content: flex-end;
}
.new-mode-field-desc {
font-size: 0.8em;
color: var(--text-muted);
margin-bottom: 6px;
line-height: 1.4;
}
.new-mode-location {
margin: 10px 0;
}
.new-mode-loc-grid {
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px 0;
}
.new-mode-loc-row {
display: flex;
align-items: flex-start;
gap: 6px;
font-size: 0.88em;
}
/* Backup section */
.agent-backup-section {
margin-bottom: 24px;
}
.agent-backup-section h4 {
margin: 16px 0 8px;
font-size: 14px;
font-weight: 600;
}
.agent-backup-category-list {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 12px;
}
.agent-backup-category-row {
display: flex;
align-items: center;
}
.agent-backup-label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
font-size: 13px;
line-height: 1.4;
}
.agent-backup-label input[type="checkbox"] {
flex-shrink: 0;
}
.agent-backup-label-text {
display: inline;
}
.agent-backup-label-name {
font-weight: 500;
}
.agent-backup-label-desc {
color: var(--text-muted);
}
.agent-backup-label-stats {
color: var(--text-faint);
font-size: 12px;
}
.agent-backup-row {
display: flex;
gap: 8px;
margin-top: 8px;
}
.agent-backup-import-info {
color: var(--text-muted);
font-size: 13px;
margin: 4px 0 8px;
}
.agent-backup-warning {
color: var(--text-error);
font-size: 12px;
margin: 8px 0 4px;
}
/* ── Operation Log ─────────────────────────────────────────────────── */
.agent-log-controls {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.agent-log-date-select {
flex: 1;
max-width: 160px;
}
.agent-log-table-wrap {
overflow-x: auto;
max-height: 400px;
overflow-y: auto;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
margin-bottom: 8px;
}
.agent-log-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
.agent-log-table th,
.agent-log-table td {
padding: 4px 8px;
border-bottom: 1px solid var(--background-modifier-border);
text-align: left;
white-space: nowrap;
}
.agent-log-table thead th {
background: var(--background-secondary);
font-weight: 600;
color: var(--text-muted);
position: sticky;
top: 0;
}
.agent-log-success { color: var(--color-green); font-weight: 600; }
.agent-log-error { color: var(--color-red); font-weight: 600; }
.agent-log-error-msg { color: var(--text-muted); font-size: 11px; }
.agent-log-row-expandable { cursor: pointer; }
.agent-log-row-expandable:hover { background: var(--background-secondary); }
.agent-log-row-expanded { background: var(--background-secondary); }
.agent-log-detail-row td { padding: 0 8px 8px; }
.agent-log-hidden { display: none; }
.agent-log-detail-label {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
margin: 6px 0 2px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.agent-log-detail-content {
font-size: 11px;
line-height: 1.4;
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
padding: 6px 8px;
margin: 0 0 4px;
max-height: 200px;
overflow: auto;
white-space: pre-wrap;
word-break: break-word;
}
.agent-log-detail-error {
border-color: var(--color-red);
color: var(--color-red);
}
.agent-log-download-btn {
font-size: 12px;
}
/* ── Rules tab ─────────────────────────────────────────────────────── */
.agent-rules-create-row {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.agent-rules-name-input {
flex: 1;
}
.agent-rules-list {
display: flex;
flex-direction: column;
gap: 0;
}
.agent-rules-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 3px 8px;
font-size: var(--font-ui-small);
border-bottom: 1px solid var(--background-modifier-border-hover);
}
.agent-rules-row:last-child {
border-bottom: none;
}
/* ── Plugin Skills compact table ── */
.agent-skill-controls {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
/* Empty state text (no background box) */
.agent-empty-state {
font-size: 12px;
color: var(--text-muted);
padding: 8px 0;
margin: 0;
}
/* Collapsible skill group headers */
.agent-skill-group-header {
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;
padding: 6px 0;
font-weight: var(--font-semibold);
font-size: var(--font-ui-medium);
color: var(--text-normal);
user-select: none;
}
.agent-skill-group-header:hover {
color: var(--text-accent);
}
.agent-skill-group-chevron {
display: flex;
align-items: center;
color: var(--text-muted);
}
.agent-skill-group-chevron svg {
width: 16px;
height: 16px;
}
.agent-skill-group-collapsed {
display: none;
}
.agent-skill-table {
width: 100%;
border-collapse: collapse;
font-size: var(--font-ui-small);
margin-bottom: 16px;
table-layout: fixed;
}
.agent-skill-table thead th {
text-align: left;
padding: 4px 8px;
font-weight: 600;
color: var(--text-muted);
font-size: var(--font-ui-smaller);
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-skill-th-status { width: 16px; }
.agent-skill-th-cmds { width: 80px; }
.agent-skill-th-actions { width: 80px; }
.agent-skill-th-toggle { width: 50px; text-align: center; }
.agent-skill-table tbody tr {
border-bottom: 1px solid var(--background-modifier-border-hover);
}
.agent-skill-table tbody tr:hover {
background: var(--background-secondary);
}
.agent-skill-table tbody tr.agent-skill-disabled {
opacity: 0.5;
}
.agent-skill-table td {
padding: 3px 8px;
vertical-align: middle;
}
.agent-skill-status-cell {
width: 16px;
text-align: center;
}
.agent-skill-dot {
display: inline-block;
width: 7px;
height: 7px;
border-radius: 50%;
}
.agent-skill-dot-on {
background: var(--color-green);
}
.agent-skill-dot-off {
background: var(--text-faint);
}
.agent-skill-name-cell {
vertical-align: top;
padding-top: 5px;
padding-bottom: 5px;
word-wrap: break-word;
overflow: hidden;
overflow-wrap: break-word;
}
.agent-skill-name {
font-weight: 500;
word-wrap: break-word;
overflow-wrap: break-word;
}
.agent-skill-desc {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
line-height: 1.3;
margin-top: 1px;
word-wrap: break-word;
overflow-wrap: break-word;
}
.agent-skill-desc-clamped {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.agent-skill-source-badge {
display: inline-block;
padding: 1px 6px;
border-radius: 4px;
font-size: 11px;
font-weight: 500;
white-space: nowrap;
}
.agent-skill-source-bundled,
.agent-skill-source-builtin {
background-color: var(--background-modifier-success);
color: var(--text-on-accent);
}
.agent-skill-source-agent,
.agent-skill-source-learned {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.agent-skill-source-user {
background-color: var(--background-modifier-border);
color: var(--text-muted);
}
.agent-skill-source-pro {
background-color: var(--color-purple, #7c3aed);
color: var(--text-on-accent);
}
.agent-skill-cmd-cell {
width: 80px;
text-align: center;
color: var(--text-muted);
font-size: var(--font-ui-smaller);
word-break: keep-all;
overflow: visible;
white-space: nowrap;
}
.agent-skill-actions-cell {
width: 100px;
text-align: right;
white-space: nowrap;
}
/* Borderless icon button used in skill rows. Higher specificity via
the table-cell ancestor wins over Obsidian's default .setting-item
button styling. Matches the chat-toolbar button look (transparent,
icon-only). */
.agent-skill-actions-cell button.agent-skill-action-btn,
.agent-skill-action-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: none;
box-shadow: none;
cursor: pointer;
color: var(--text-muted);
border-radius: 4px;
}
.agent-skill-action-btn svg {
width: 14px;
height: 14px;
}
.agent-skill-actions-cell button.agent-skill-action-btn:hover,
.agent-skill-action-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
box-shadow: none;
}
.agent-skill-action-btn-faint {
opacity: 0.3;
}
/* ---------------------------------------------------------------------------
* Generic borderless icon-only buttons across the Settings tab.
*
* Targets any <button> inside .agent-settings that has a direct <svg> child
* AND no other direct children (i.e. setIcon() was called on it and there
* is no accompanying label text). Text-buttons (Create, Import, Reload,
* Save) and CTA-styled buttons (.mod-cta) keep their default look so
* primary actions stay visually distinct.
*
* FIX-29-17 (Review-Bot CSS-lint, post v2.11.7): replaced the
* `:has() / :not(:has())` selector chain with an explicit class set by
* `decorateIconOnlyButtons(root)` at render time (called from
* AgentSettingsTab.buildTabContent). Same pattern the codebase already
* applies for MemoryViewerModal (line ~3562) and the message-loading
* container (line ~4153). Drops the broad style-invalidation cost of
* `:has()` flagged by the bot.
* ------------------------------------------------------------------------ */
.agent-settings button.agent-icon-only-btn {
background: transparent;
border: none;
box-shadow: none;
padding: 0;
width: 24px;
height: 24px;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
border-radius: 4px;
cursor: pointer;
}
.agent-settings button.agent-icon-only-btn:hover {
background: var(--background-modifier-hover);
color: var(--text-normal);
box-shadow: none;
}
.agent-settings button.agent-icon-only-btn svg {
width: 14px;
height: 14px;
}
.agent-settings button.agent-icon-only-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.agent-skill-toggle-cell {
width: 50px;
text-align: center;
}
.agent-skill-toggle.checkbox-container {
transform: scale(0.75);
margin: 0 auto;
}
.agent-rules-label {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
min-width: 0;
font-size: var(--font-ui-small);
}
.agent-rules-actions {
display: flex;
gap: 4px;
}
.agent-rules-toggle.checkbox-container {
transform: scale(0.75);
flex-shrink: 0;
margin-left: 4px;
}
.agent-rules-edit-btn,
.agent-rules-export-btn,
.agent-rules-delete-btn {
background: none;
border: none;
padding: 4px;
cursor: pointer;
color: var(--text-muted);
border-radius: 4px;
display: flex;
align-items: center;
}
.agent-rules-edit-btn:hover,
.agent-rules-export-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.agent-rules-delete-btn:hover {
color: var(--color-red);
background: var(--background-modifier-hover);
}
.agent-rules-edit-btn svg,
.agent-rules-export-btn svg,
.agent-rules-delete-btn svg {
width: 14px;
height: 14px;
}
.agent-rules-import-btn {
font-size: 12px;
padding: 2px 8px;
}
.agent-workflow-slug {
font-size: 11px;
color: var(--text-muted);
font-family: var(--font-monospace);
background: var(--background-modifier-hover);
border-radius: 3px;
padding: 1px 5px;
margin-left: 4px;
}
/* ── Autocomplete dropdown (Sprint B3) ──────────────────────────────── */
.autocomplete-dropdown {
position: absolute;
bottom: calc(100% + 4px);
left: 0;
right: 0;
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
box-shadow: 0 4px 16px rgba(0,0,0,0.2);
z-index: 100;
overflow: hidden;
max-height: 220px;
overflow-y: auto;
}
.autocomplete-item {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 2px;
padding: 6px 12px;
cursor: pointer;
border-bottom: 1px solid var(--background-modifier-border-hover);
}
.autocomplete-item:last-child {
border-bottom: none;
}
.autocomplete-item:hover,
.autocomplete-item.active {
background: var(--background-modifier-hover);
}
.autocomplete-top {
display: flex;
align-items: center;
gap: 8px;
}
.autocomplete-label {
flex: 1;
font-size: 13px;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.autocomplete-tag {
font-size: 9px;
color: var(--text-on-accent);
background: var(--interactive-accent);
padding: 0 5px;
border-radius: 3px;
flex-shrink: 0;
opacity: 0.85;
text-transform: uppercase;
letter-spacing: 0.3px;
}
/* FEAT-02-11: file vs folder tag variants. File = light grey chip,
folder = darker grey chip. Skills/prompts/workflows keep the accent
colour because they omit tagVariant. */
.autocomplete-tag.tag-file {
color: var(--text-muted);
background: var(--background-modifier-border);
opacity: 1;
}
.autocomplete-tag.tag-folder {
color: var(--text-normal);
background: var(--background-modifier-border-hover);
opacity: 1;
}
.autocomplete-sub {
font-size: 11px;
color: var(--text-muted);
font-family: var(--font-monospace);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ── Per-model temperature controls (ModelConfigModal) ────────────── */
.mcm-temperature-controls {
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
}
.mcm-temperature-toggle {
display: flex;
align-items: center;
gap: 6px;
}
.mcm-temperature-toggle-label {
font-size: 12px;
color: var(--text-normal);
cursor: pointer;
}
.mcm-temperature-slider-wrap {
display: flex;
align-items: center;
gap: 10px;
}
.mcm-temperature-slider {
flex: 1;
cursor: pointer;
}
.mcm-temperature-value {
font-size: 12px;
font-variant-numeric: tabular-nums;
color: var(--text-normal);
min-width: 32px;
text-align: right;
}
.mcm-temperature-note {
font-size: 11px;
color: var(--text-muted);
font-style: italic;
}
/* ── Chat History Modal ──────────────────────────────────────────────── */
.chat-history-modal { min-width: 400px; }
.chat-history-list { display: flex; flex-direction: column; gap: 8px; }
.chat-history-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-secondary);
}
.chat-history-info { flex: 1; min-width: 0; }
.chat-history-title {
font-weight: 500;
font-size: var(--font-ui-small);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chat-history-date {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
margin-top: 2px;
}
.chat-history-actions { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }
.chat-history-delete-btn {
background: none;
border: none;
cursor: pointer;
color: var(--text-muted);
padding: 4px;
display: flex;
align-items: center;
}
.chat-history-delete-btn:hover { color: var(--color-red); }
.chat-history-empty {
color: var(--text-muted);
font-style: italic;
text-align: center;
padding: 24px 0;
}
/* ── ApproveEditModal ────────────────────────────────────────────────── */
.approve-edit-modal { min-width: 520px; max-width: 800px; }
.approve-edit-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
gap: 12px;
}
.approve-edit-path {
display: flex;
align-items: center;
gap: 6px;
font-size: var(--font-ui-small);
color: var(--text-muted);
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.approve-edit-path-icon { display: inline-flex; align-items: center; flex-shrink: 0; }
.approve-edit-stats { display: flex; gap: 8px; flex-shrink: 0; font-weight: 600; font-size: var(--font-ui-small); }
.diff-stat-added { color: var(--color-green); }
.diff-stat-removed { color: var(--color-red); }
.diff-stat-none { color: var(--text-muted); font-weight: normal; }
.approve-edit-diff {
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
overflow: auto;
max-height: 420px;
background: var(--background-primary);
margin-bottom: 16px;
}
.diff-line {
display: flex;
gap: 4px;
padding: 1px 8px;
line-height: 1.5;
}
.diff-line-added { background: rgba(var(--color-green-rgb, 68,196,68), 0.12); border-left: 3px solid var(--color-green); }
.diff-line-removed { background: rgba(var(--color-red-rgb, 240,60,60), 0.12); border-left: 3px solid var(--color-red); }
.diff-line-unchanged { border-left: 3px solid transparent; }
.diff-line-prefix {
color: var(--text-muted);
user-select: none;
flex-shrink: 0;
width: 12px;
}
.diff-line-added > .diff-line-prefix { color: var(--color-green); }
.diff-line-removed > .diff-line-prefix { color: var(--color-red); }
.diff-line-content { white-space: pre-wrap; word-break: break-all; }
/* Side-by-side diff rows */
.diff-row {
display: flex;
}
.diff-side {
flex: 1;
display: flex;
gap: 4px;
padding: 1px 8px;
line-height: 1.5;
min-width: 0;
overflow: hidden;
}
.diff-side-old { border-right: 1px solid var(--background-modifier-border); }
.diff-side.diff-line-added { background: rgba(var(--color-green-rgb, 68,196,68), 0.12); }
.diff-side.diff-line-removed { background: rgba(var(--color-red-rgb, 240,60,60), 0.12); }
.diff-side-empty {
background: var(--background-secondary);
min-height: 1.5em;
}
.diff-collapse-btn {
display: block;
width: 100%;
background: var(--background-secondary);
border: none;
border-top: 1px solid var(--background-modifier-border);
border-bottom: 1px solid var(--background-modifier-border);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
padding: 4px 8px;
cursor: pointer;
text-align: left;
}
.diff-collapse-btn:hover { color: var(--text-normal); background: var(--background-modifier-hover); }
.approve-edit-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
}
.approve-edit-reject { color: var(--color-red); }
/* ── DiffReviewModal ─────────────────────────────────────────────────── */
.diff-review-modal {
width: 70vw;
height: 70vh;
max-width: none;
max-height: none;
display: flex;
flex-direction: column;
}
.diff-review-modal .modal-content { flex: 1; overflow-y: auto; min-height: 0; }
/* Semantic Group (replaces per-hunk containers) */
.diff-semantic-group {
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
margin: 8px 0;
overflow: hidden;
}
.diff-group-approved { border-color: var(--color-green); }
.diff-group-rejected { border-color: var(--color-red); opacity: 0.5; }
/* Section Header */
.diff-section-header {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
background: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
font-size: var(--font-ui-small);
}
.diff-section-label {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
color: var(--text-normal);
}
.diff-section-icon {
display: inline-flex;
align-items: center;
flex-shrink: 0;
color: var(--text-muted);
}
.diff-section-stats {
display: flex;
gap: 6px;
flex-shrink: 0;
font-size: var(--font-ui-smaller);
}
.diff-section-actions {
display: flex;
gap: 4px;
flex-shrink: 0;
}
/* Section Buttons */
.diff-section-btn {
padding: 2px 10px;
font-size: 11px;
border-radius: 3px;
border: 1px solid var(--background-modifier-border);
background: transparent;
cursor: pointer;
color: var(--text-muted);
}
.diff-section-keep:hover { border-color: var(--color-green); color: var(--color-green); }
.diff-section-undo:hover { border-color: var(--color-red); color: var(--color-red); }
.diff-section-edit:hover { border-color: var(--color-accent); color: var(--color-accent); }
/* Section body (diff lines) */
.diff-section-body {
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
}
/* Section Editor Textarea */
.diff-section-editor {
padding: 8px 10px;
border-top: 1px solid var(--background-modifier-border);
background: var(--background-primary-alt);
}
.diff-section-editor-label {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
margin-bottom: 6px;
}
.diff-section-textarea {
width: 100%;
min-height: 60px;
max-height: 300px;
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
line-height: 1.5;
padding: 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
resize: vertical;
box-sizing: border-box;
}
.diff-section-textarea:focus {
outline: none;
border-color: var(--color-accent);
}
.diff-section-editor-footer {
display: flex;
justify-content: flex-end;
gap: 6px;
margin-top: 6px;
}
/* Checkpoint diff header */
.checkpoint-diff-header {
font-size: var(--font-ui-small);
color: var(--text-muted);
margin-bottom: 12px;
}
/* Footer */
.diff-review-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 12px;
border-top: 1px solid var(--background-modifier-border);
margin-top: 12px;
}
.diff-review-reject-all { color: var(--color-red); }
.diff-review-accept-selected:disabled { opacity: 0.4; }
/* ─── MCP Settings Tab ─────────────────────────────────────────── */
.agent-mcp-add-btn { margin-bottom: 12px; }
.agent-mcp-list { display: flex; flex-direction: column; gap: 4px; }
.agent-mcp-server-row {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
}
.agent-mcp-status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.agent-mcp-status-dot.connected { background: var(--color-green); }
.agent-mcp-status-dot.disconnected { background: var(--text-faint); }
.agent-mcp-status-dot.error { background: var(--color-red); }
.agent-mcp-status-dot.connecting { background: var(--color-yellow); }
.agent-mcp-server-info {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.agent-mcp-server-name { font-weight: 600; }
.agent-mcp-server-type { color: var(--text-muted); font-size: var(--font-smaller); }
.agent-mcp-server-tools { color: var(--text-muted); font-size: var(--font-smaller); }
.agent-mcp-server-error {
color: var(--color-red);
font-size: var(--font-smaller);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* MCP Add/Edit modal */
.agent-mcp-modal-input {
width: 100%;
margin: 4px 0 12px;
padding: 4px 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-secondary);
color: var(--text-normal);
font-family: var(--font-monospace);
font-size: var(--font-smaller);
box-sizing: border-box;
}
.agent-mcp-section { margin-bottom: 8px; }
.agent-mcp-modal-save { margin-top: 8px; }
/* ─── Custom Prompts Tab ───────────────────────────────────────── */
.agent-prompt-builtin-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.agent-prompt-builtin-row {
display: flex;
align-items: baseline;
gap: 8px;
padding: 4px 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-prompt-builtin-name { font-weight: 600; min-width: 130px; }
.agent-prompt-builtin-desc { color: var(--text-muted); font-size: var(--font-smaller); }
.agent-prompt-form {
padding: 12px;
margin-bottom: 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
background: var(--background-secondary);
}
.agent-prompt-form-title { font-weight: 600; margin: 0 0 8px; }
.agent-prompt-input {
display: block;
width: 100%;
margin-bottom: 8px;
padding: 4px 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
box-sizing: border-box;
}
.agent-prompt-textarea {
display: block;
width: 100%;
margin-bottom: 8px;
padding: 4px 8px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-primary);
color: var(--text-normal);
font-family: var(--font-monospace);
font-size: var(--font-smaller);
resize: vertical;
box-sizing: border-box;
}
.agent-prompt-form-btns { display: flex; gap: 8px; }
.agent-prompt-add-btn { margin-bottom: 12px; }
.agent-prompt-mode-row { display: flex; align-items: flex-start; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.agent-prompt-mode-label { font-size: var(--font-smaller); color: var(--text-muted); }
.agent-prompt-mode-select { width: 100%; }
.agent-prompt-mode-badge {
display: inline-block;
font-size: var(--font-smaller);
color: var(--text-on-accent);
background: var(--interactive-accent);
border-radius: 3px;
padding: 1px 5px;
margin-left: 4px;
vertical-align: middle;
}
/* ── Tool Picker Popover (Copilot style) ───────────────────────────────── */
.tool-picker-popover {
position: var(--tp-pos, fixed);
z-index: 1000;
top: var(--tp-top);
bottom: var(--tp-bottom);
left: var(--tp-left);
width: var(--tp-w);
min-width: var(--tp-min-w, 320px);
max-width: var(--tp-max-w, 400px);
max-height: var(--tp-max-h, 520px);
background: var(--background-primary);
border-radius: 8px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.22);
padding: 0;
overflow: hidden;
display: flex;
flex-direction: column;
border: none;
}
.tool-picker-header {
padding: 10px 12px 6px;
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.tool-picker-title {
font-size: 12px;
font-weight: 600;
color: var(--text-normal);
}
.tool-picker-count {
font-size: 11px;
color: var(--text-faint);
}
.tool-picker-search {
width: 100%;
border: none;
border-bottom: 1px solid var(--background-modifier-border);
border-radius: 0;
padding: 5px 12px;
font-size: 12px;
background: transparent;
box-shadow: none;
outline: none;
flex-shrink: 0;
}
.tool-picker-scroll {
overflow-y: auto;
flex: 1;
padding: 2px 0;
}
/* Top-level category row */
.tp-cat-row {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 10px 5px 8px;
cursor: pointer;
user-select: none;
}
.tp-cat-row:hover {
background: var(--background-modifier-hover);
}
.tp-cat-arrow {
font-size: 10px;
color: var(--text-faint);
display: inline-block;
transition: transform 0.15s;
flex-shrink: 0;
width: 10px;
text-align: center;
}
.tp-cat-row.is-open .tp-cat-arrow {
transform: rotate(90deg);
}
.tp-cat-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-faint);
flex: 1;
}
.tp-cat-group-cb {
margin: 0;
cursor: pointer;
flex-shrink: 0;
}
.tp-cat-body {
/* display toggled by JS */
}
/* Sub-category row (tool group inside Built-In) */
.tp-subcat-row {
display: flex;
align-items: center;
gap: 6px;
padding: 3px 10px 3px 20px;
cursor: pointer;
user-select: none;
}
.tp-subcat-row:hover {
background: var(--background-modifier-hover);
}
.tp-subcat-arrow {
font-size: 9px;
color: var(--text-faint);
transition: transform 0.15s;
flex-shrink: 0;
width: 10px;
text-align: center;
}
.tp-subcat-row.is-open .tp-subcat-arrow {
transform: rotate(90deg);
}
.tp-subcat-icon {
width: 14px;
height: 14px;
color: var(--text-muted);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
.tp-subcat-icon svg {
width: 14px;
height: 14px;
}
.tp-subcat-label {
font-size: 12px;
color: var(--text-normal);
flex: 1;
font-weight: 600;
}
.tp-subcat-body {
/* display toggled by JS */
}
/* Individual item row */
.tp-item-row {
display: flex;
align-items: center;
gap: 7px;
padding: 3px 10px 3px 48px;
}
/* Items under top-level categories (MCP/Skills/Workflows) —
same indent as tool items under Built-In sub-categories */
.tp-item-indent-cat {
display: flex;
align-items: center;
gap: 7px;
padding: 3px 10px 3px 48px;
}
.tp-item-row input[type="checkbox"],
.tp-item-indent-cat input[type="checkbox"] {
order: 99;
margin-left: auto;
}
.tp-item-row:hover,
.tp-item-indent-cat:hover {
background: var(--background-modifier-hover);
}
.tp-item-name {
font-size: 12px;
color: var(--text-normal);
flex-shrink: 0;
}
.tp-item-desc {
font-size: 11px;
color: var(--text-faint);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.tp-empty-hint {
display: block;
font-size: 11px;
color: var(--text-faint);
font-style: italic;
padding: 4px 10px 4px 28px;
}
/* EPIC-26 / FEAT-26-05 -- chat-header model picker rows.
Flat list (no category indentation) + vertical label/desc stack. */
.chat-model-picker .tp-item-row.chat-model-picker-row {
padding: 6px 10px;
cursor: pointer;
gap: 10px;
}
.chat-model-picker .tp-item-label-wrap {
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}
.chat-model-picker .tp-item-label {
font-size: 12px;
color: var(--text-normal);
display: flex;
align-items: center;
gap: 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.chat-model-picker .tp-item-desc {
/* override the auto-flex from .tp-item-desc so the description
sits below the label, not in a wide flex cell to the right */
flex: 0 0 auto;
}
.chat-model-picker .tp-item-icon {
display: inline-flex;
align-items: center;
color: var(--text-muted);
}
.chat-model-picker .tp-item-icon svg { width: 14px; height: 14px; }
.chat-model-picker-check {
display: inline-flex;
align-items: center;
color: var(--text-accent);
margin-left: auto;
}
.chat-model-picker-check svg { width: 14px; height: 14px; }
/* Provider switcher chips (issue #48.5) */
.chat-model-picker-providers {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 6px 8px;
border-bottom: 1px solid var(--background-modifier-border);
}
.chat-model-picker-provider-chip {
padding: 2px 8px;
font-size: 11px;
border-radius: 10px;
border: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
color: var(--text-muted);
cursor: pointer;
}
.chat-model-picker-provider-chip:hover {
color: var(--text-normal);
border-color: var(--interactive-accent);
}
.chat-model-picker-provider-chip.is-active {
background: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
cursor: default;
}
/* Tier badge -- small pill next to the model name */
.chat-model-picker-tier {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 1px 6px;
border-radius: 8px;
color: var(--text-on-accent, white);
background: var(--text-muted);
}
.chat-model-picker-tier-fast { background: #5c6bc0; }
.chat-model-picker-tier-mid { background: #2e7d32; }
.chat-model-picker-tier-flagship { background: #c27c4a; }
/* FIX-55-01: badge for manually typed tier-override ids (issue #55) */
.chat-model-picker-manual-badge {
background: var(--background-modifier-border);
color: var(--text-muted);
}
.chat-model-picker-auto {
border-bottom: 1px solid var(--background-modifier-border);
margin-bottom: 4px;
}
/* Issue #44: per-conversation thinking binary switch.
A pill track with a sliding knob, accent-filled when on. */
.chat-model-picker-thinking {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
border-top: 1px solid var(--background-modifier-border);
padding: 8px 10px;
flex-shrink: 0;
}
.chat-model-picker-thinking-label {
font-size: 11px;
color: var(--text-muted);
}
.chat-model-picker-thinking-switch {
position: relative;
flex-shrink: 0;
width: 34px;
height: 18px;
margin-left: auto;
padding: 0;
border: 1px solid var(--background-modifier-border);
border-radius: 999px;
background: var(--background-modifier-border);
cursor: pointer;
transition: background 0.12s ease;
}
.chat-model-picker-thinking-switch.is-on {
background: var(--interactive-accent);
border-color: var(--interactive-accent);
}
.chat-model-picker-thinking-knob {
position: absolute;
top: 1px;
left: 1px;
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--background-primary);
transition: transform 0.12s ease;
}
.chat-model-picker-thinking-switch.is-on .chat-model-picker-thinking-knob {
transform: translateX(16px);
}
.chat-model-picker-thinking-switch:focus-visible {
outline: 2px solid var(--interactive-accent);
outline-offset: 2px;
}
.chat-model-picker-thinking-state {
font-size: 11px;
font-weight: 600;
color: var(--text-normal);
min-width: 22px;
text-align: right;
}
/* IMP-54-05a: one-line discoverability hint sitting where the effort slider
would be (thinking on, but Auto active or the pinned model resolves no
effort levels). Muted, single line, toggled live with the thinking switch. */
.chat-model-picker-effort-hint {
border-top: 1px solid var(--background-modifier-border);
padding: 6px 10px;
font-size: 11px;
color: var(--text-faint);
flex-shrink: 0;
}
/* Per-conversation reasoning-effort slider: a Claude-Code-style pill slider
with discrete dot markers and a round knob, accent-filled up to the knob. */
.chat-model-picker-effort {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
border-top: 1px solid var(--background-modifier-border);
padding: 8px 10px;
flex-shrink: 0;
}
.chat-model-picker-effort-labelwrap {
display: flex;
align-items: baseline;
gap: 6px;
min-width: 0;
}
.chat-model-picker-effort-label {
font-size: 11px;
color: var(--text-muted);
}
.chat-model-picker-effort-value {
font-size: 11px;
font-weight: 600;
color: var(--text-normal);
}
/* A visible pill track with a round knob slightly larger than the pill so the
circle stands proud above and below the track at every stop. The knob box
always stays inside the pill horizontally (left travels 0..width-KNOB), so
the full circle is visible at both extremes ('auto' flush-left, 'max'
flush-right) without any visual clipping by the pill's rounded ends. */
.chat-model-picker-effort-pill {
position: relative;
width: 148px;
height: 14px;
flex-shrink: 0;
border-radius: 999px;
background: var(--background-modifier-border);
cursor: pointer;
/* let a pointer drag move the knob without the list scrolling underneath */
touch-action: none;
/* knob overhangs the track vertically; never clip it. */
overflow: visible;
}
/* Accent track filled up to the knob centre: KNOB_PX/2 + frac * (100% - KNOB_PX),
with KNOB_PX = 18px, so the fill always ends exactly under the knob. */
.chat-model-picker-effort-fill {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: calc(9px + var(--effort-frac, 0) * (100% - 18px));
border-radius: 999px;
background: var(--interactive-accent);
pointer-events: none;
}
.chat-model-picker-effort-dots {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: space-between;
/* 7.5px = knob-centre inset (9px) minus half a dot (1.5px), so the dot
centres line up exactly with the knob stops. */
padding: 0 7.5px;
pointer-events: none;
}
.chat-model-picker-effort-dot {
width: 3px;
height: 3px;
border-radius: 50%;
background: var(--background-primary);
opacity: 0.65;
}
/* The knob: 18px circle that sits ON TOP of the 6px track. Its top-left
travels from left=0 to left=width-18px, so the full circle is always
visible inside the pill's horizontal bounding box -- flush-left at 'auto'
and flush-right at 'max' without any visual clipping. */
.chat-model-picker-effort-knob {
position: absolute;
top: 50%;
left: calc(var(--effort-frac, 0) * (100% - 18px));
width: 18px;
height: 18px;
transform: translateY(-50%);
border-radius: 50%;
background: var(--background-primary);
border: 2px solid var(--interactive-accent);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
pointer-events: none;
}
.chat-model-picker-effort-pill:focus-visible {
outline: 2px solid var(--interactive-accent);
outline-offset: 2px;
}
/* Issue #44: thinking-override badge on the chat-header model button */
/* Footer */
.tool-picker-footer {
border-top: 1px solid var(--background-modifier-border);
padding: 5px 10px;
flex-shrink: 0;
}
.tool-picker-save-btn {
display: flex;
align-items: center;
gap: 5px;
font-size: 11px;
color: var(--text-muted);
background: none;
border: none;
cursor: pointer;
padding: 2px 0;
}
.tool-picker-save-btn:hover {
color: var(--text-normal);
}
.tp-save-icon {
display: flex;
align-items: center;
}
.tp-save-icon svg {
width: 12px;
height: 12px;
}
/* ── Settings: Tool Group Accordion ────────────────────────────────────── */
.modes-tool-group-accordion {
margin-bottom: 4px;
border-radius: 6px;
border: 1px solid var(--background-modifier-border);
overflow: hidden;
}
.modes-tool-group-summary {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
cursor: pointer;
background: var(--background-secondary);
list-style: none;
user-select: none;
transition: background 0.1s;
}
.modes-tool-group-summary:hover {
background: var(--background-modifier-hover);
}
.modes-tool-group-summary::-webkit-details-marker { display: none; }
.modes-tool-group-label {
font-weight: 500;
font-size: 13px;
flex: 1;
}
.modes-tool-count-badge {
font-size: 11px;
color: var(--text-faint);
background: var(--background-primary);
border-radius: 10px;
padding: 1px 7px;
margin-left: auto;
border: 1px solid var(--background-modifier-border);
}
.modes-tool-checkboxes {
display: flex;
flex-direction: column;
gap: 0;
padding: 4px 0;
background: var(--background-primary);
}
.modes-tool-row {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 5px 10px 5px 28px;
transition: background 0.08s;
}
.modes-tool-row:hover {
background: var(--background-modifier-hover);
}
.modes-tool-row input[type="checkbox"] {
margin-top: 3px;
flex-shrink: 0;
cursor: pointer;
}
/* Label container: stacked label + description */
.modes-tool-name {
display: flex;
flex-direction: column;
gap: 1px;
cursor: pointer;
}
.modes-tool-label-text {
font-size: 12px;
font-weight: 500;
color: var(--text-normal);
}
.modes-tool-label-desc {
font-size: 11px;
color: var(--text-muted);
line-height: 1.3;
}
/* ── Mode Editor: Forced Skills + Allowed MCP sections ─────────────────── */
.modes-skills-list {
display: flex;
flex-direction: column;
gap: 0;
padding: 4px 0;
background: var(--background-primary);
}
.modes-skills-row {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 5px 10px 5px 28px;
transition: background 0.08s;
}
.modes-skills-row:hover {
background: var(--background-modifier-hover);
}
.modes-skills-row input[type="checkbox"] {
margin-top: 3px;
flex-shrink: 0;
cursor: pointer;
}
.modes-skills-label {
font-size: 12px;
font-weight: 500;
color: var(--text-normal);
cursor: pointer;
}
.modes-skills-desc {
display: block;
font-size: 11px;
color: var(--text-muted);
line-height: 1.3;
margin-top: 1px;
}
.modes-loading-hint {
font-size: 11px;
color: var(--text-faint);
font-style: italic;
padding: 6px 28px;
}
/* ── Global: Borderless buttons and selects inside the plugin ───────────── */
.agent-sidebar button,
.agent-settings-panel button {
border: none;
}
.agent-sidebar select,
.agent-settings-panel select {
border: none;
background: var(--background-secondary);
}
/* Sub-category label font-weight merged into earlier .tp-subcat-label block. */
/* ── ContentEditorModal ──────────────────────────────────────────────────── */
.content-editor-modal {
padding: 16px;
}
.content-editor-title {
margin: 0 0 12px;
font-size: 15px;
font-weight: 600;
}
.content-editor-textarea {
width: 100%;
min-height: 360px;
font-family: var(--font-monospace);
font-size: 13px;
line-height: 1.6;
padding: 10px 12px;
border-radius: 6px;
border: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
color: var(--text-normal);
resize: vertical;
box-sizing: border-box;
}
.content-editor-textarea:focus {
outline: none;
border-color: var(--color-accent);
}
.content-editor-btn-row {
display: flex;
gap: 8px;
margin-top: 12px;
justify-content: flex-end;
}
/* ── Vault File Picker Popover ───────────────────────────────────────────── */
.vault-file-picker {
position: var(--vfp-pos, fixed);
z-index: 1000;
top: var(--vfp-top);
bottom: var(--vfp-bottom);
left: var(--vfp-left);
width: var(--vfp-w);
min-width: 280px;
max-width: 320px;
max-height: var(--vfp-max-h, 280px);
display: flex;
flex-direction: column;
background: var(--background-primary);
border: none;
border-radius: 8px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.22);
overflow: hidden;
padding: 0;
}
.vfp-search-row {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 10px;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.vfp-search-icon {
display: flex;
align-items: center;
color: var(--text-faint);
flex-shrink: 0;
}
.vfp-search-icon svg { width: 13px; height: 13px; }
.vfp-search-input {
flex: 1;
border: none;
background: transparent;
outline: none;
font-size: 13px;
color: var(--text-normal);
box-shadow: none;
}
.vfp-search-input::placeholder { color: var(--text-faint); }
.vfp-list {
flex: 1;
overflow-y: auto;
padding: 4px 0;
}
.vfp-row {
display: flex;
align-items: center;
gap: 8px;
padding: 5px 10px;
cursor: pointer;
user-select: none;
}
.vfp-row:hover,
.vfp-row-active { background: var(--background-modifier-hover); }
.vfp-row-checked { background: color-mix(in srgb, var(--interactive-accent) 8%, transparent); }
.vfp-row input[type="checkbox"] {
flex-shrink: 0;
cursor: pointer;
accent-color: var(--interactive-accent);
pointer-events: none;
}
.vfp-row-info {
display: flex;
flex-direction: column;
gap: 1px;
min-width: 0;
}
.vfp-row-name {
font-size: 12px;
color: var(--text-normal);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.vfp-row-path {
font-size: 10px;
color: var(--text-faint);
font-family: var(--font-monospace);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.vfp-empty {
padding: 16px 10px;
font-size: 12px;
color: var(--text-faint);
font-style: italic;
text-align: center;
}
.vfp-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
border-top: 1px solid var(--background-modifier-border);
flex-shrink: 0;
gap: 8px;
}
.vfp-count {
font-size: 11px;
color: var(--interactive-accent);
font-weight: 500;
flex: 1;
}
.vfp-add-btn {
padding: 3px 12px;
background: var(--interactive-accent);
color: var(--text-on-accent);
border: none;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
font-weight: 500;
}
.vfp-add-btn:hover { opacity: 0.85; }
/* ─── History Panel ─────────────────────────────────────────────────────────── */
.history-panel {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
background: var(--background-primary);
border-right: 1px solid var(--background-modifier-border);
z-index: 10;
display: flex;
flex-direction: column;
transform: translateX(-100%);
transition: transform 0.2s ease;
}
.history-panel-open {
transform: translateX(0);
}
.history-panel-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.history-panel-title {
font-size: 14px;
font-weight: 700;
font-family: Consolas, monospace;
color: var(--text-normal);
}
.history-panel-close {
background: none;
border: none;
cursor: pointer;
color: var(--text-muted);
padding: 4px;
}
.history-panel-filter {
padding: 8px 16px;
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
/* BA-26 / FEAT-23-03: Source-Tabs */
.history-panel-tabs {
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 4px 16px 8px;
border-bottom: 1px solid var(--background-modifier-border);
flex-shrink: 0;
}
.history-panel-tab {
background: none;
border: 1px solid var(--background-modifier-border);
border-radius: 999px;
padding: 3px 10px;
cursor: pointer;
color: var(--text-muted);
font-size: 0.78em;
line-height: 1.4;
}
.history-panel-tab:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.history-panel-tab-active {
color: var(--text-on-accent);
background: var(--interactive-accent);
border-color: var(--interactive-accent);
}
/* BA-26 / FEAT-23-03: Source-Pill on conversation rows */
.history-row-title-row {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.history-row-source-pill {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 0.7em;
font-weight: 500;
background: var(--background-modifier-border);
color: var(--text-muted);
line-height: 1.4;
white-space: nowrap;
}
.history-row-source-pill-claude-ai,
.history-row-source-pill-claude-code {
background: rgba(204, 120, 92, 0.18);
color: rgb(204, 120, 92);
}
.history-row-source-pill-chatgpt {
background: rgba(16, 163, 127, 0.18);
color: rgb(16, 163, 127);
}
.history-row-source-pill-perplexity {
background: rgba(82, 82, 199, 0.18);
color: rgb(82, 82, 199);
}
/* BA-26 / FEAT-23-04: Pending-Marker */
.history-row-pending-marker {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 0.7em;
font-weight: 500;
background: rgba(217, 161, 32, 0.18);
color: rgb(217, 161, 32);
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* FIX-23-01-01: Thread-Pill (klickbarer Filter-Button) auf Listeneintraegen.
Style matched .history-row-source-pill 1:1, plus button-resets damit der
Browser-Default fuer <button> nicht reinkommt. */
.history-row-thread-pill {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 0.7em;
font-weight: 500;
background: rgba(120, 80, 200, 0.16);
color: rgb(120, 80, 200);
line-height: 1.4;
white-space: nowrap;
border: none;
margin: 0;
box-shadow: none;
cursor: pointer;
font-family: inherit;
height: auto;
min-height: 0;
}
.history-row-thread-pill:hover {
background: rgba(120, 80, 200, 0.28);
box-shadow: none;
}
/* FIX-23-01-01: Thread-Filter-Chip (oben in der Sidebar wenn Filter aktiv) */
.history-panel-thread-chip-row {
padding: 6px 16px 0;
flex-shrink: 0;
}
.history-panel-thread-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 4px 4px 10px;
background: rgba(120, 80, 200, 0.18);
color: rgb(120, 80, 200);
border-radius: 999px;
font-size: 0.78em;
font-weight: 500;
}
.history-panel-thread-chip-close {
background: none;
border: none;
cursor: pointer;
padding: 2px;
color: rgb(120, 80, 200);
line-height: 0;
}
.history-panel-thread-chip-close:hover {
color: rgb(80, 50, 160);
}
.history-panel-memory-toggle {
background: none;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
padding: 5px 8px;
cursor: pointer;
color: var(--text-muted);
flex-shrink: 0;
}
.history-panel-memory-toggle:hover {
color: var(--text-normal);
}
.history-panel-memory-toggle-active {
color: var(--text-accent);
border-color: var(--text-accent);
background: var(--background-secondary);
}
.history-panel-filter-input {
flex: 1 1 auto;
padding: 6px 10px;
font-size: 12px;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background: var(--background-secondary);
color: var(--text-normal);
}
.history-panel-list {
flex: 1;
overflow-y: auto;
padding: 0 8px 8px;
}
.history-panel-empty {
padding: 24px 16px;
text-align: center;
color: var(--text-muted);
font-size: 12px;
}
.history-group-label {
padding: 12px 8px 4px;
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.history-row {
display: flex;
align-items: center;
padding: 8px;
border-radius: 4px;
cursor: pointer;
gap: 8px;
}
.history-row:hover {
background: var(--background-modifier-hover);
}
.history-row-active {
background: color-mix(in srgb, var(--interactive-accent) 12%, transparent);
}
.history-row-info {
flex: 1;
min-width: 0;
}
.history-row-title {
font-size: 12px;
font-weight: 600;
color: var(--text-normal);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.history-row-meta {
font-size: 11px;
color: var(--text-muted);
}
.history-row-actions {
display: flex;
gap: 2px;
flex-shrink: 0;
}
/* Hide hover-only buttons by default; reveal the whole bar on row hover. */
.history-row-action {
background: none;
border: none;
cursor: pointer;
color: var(--text-muted);
padding: 4px;
opacity: 0;
}
.history-row:hover .history-row-action {
opacity: 1;
}
/* Memory-pinned star styles already defined earlier (line 3081 area). */
.history-row-action:hover {
color: var(--text-normal);
}
.history-row-action-danger:hover {
color: var(--text-error);
}
/* ── Task Selection Modal (FEATURE-100) ─────────────────────────────── */
.task-selection-modal {
max-width: 520px;
}
.task-selection-title {
margin: 0 0 4px 0;
}
.task-selection-subtitle {
margin: 0 0 12px 0;
color: var(--text-muted);
font-size: var(--font-ui-small);
}
.task-selection-toggle {
margin-bottom: 8px;
font-size: var(--font-ui-small);
}
.task-selection-toggle a {
cursor: pointer;
color: var(--text-accent);
}
.task-selection-list {
max-height: 320px;
overflow-y: auto;
margin-bottom: 16px;
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
}
.task-selection-item {
display: flex;
flex-direction: column;
padding: 8px 12px;
border-bottom: 1px solid var(--background-modifier-border);
}
.task-selection-item:last-child {
border-bottom: none;
}
.task-selection-label {
display: flex;
align-items: flex-start;
gap: 8px;
cursor: pointer;
}
.task-selection-checkbox {
flex-shrink: 0;
margin-top: 2px;
}
.task-selection-text {
flex: 1;
line-height: 1.4;
}
.task-selection-meta {
margin-left: 26px;
margin-top: 2px;
font-size: var(--font-ui-smaller);
color: var(--text-muted);
}
.task-selection-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
/* ── Utility classes ──────────────────────────────────────────────────── */
/* Class repetition raises specificity to (0,2,0) so plain theme styles do
not override these utilities without needing !important. */
.agent-u-hidden.agent-u-hidden { display: none; }
.agent-u-visibility-hidden.agent-u-visibility-hidden {
opacity: 0;
pointer-events: none;
}
.agent-u-cursor-pointer { cursor: pointer; }
/* Copy button spacing (SystemPromptPreviewModal) */
.agent-u-mb-12 { margin-bottom: 12px; }
/* EmbeddingsTab quick-setup guide */
.agent-embed-guide {
margin-bottom: 12px;
padding: 8px 12px;
border-left: 3px solid var(--interactive-accent);
background: var(--background-secondary);
border-radius: 4px;
}
/* ── Security warning callouts (Settings > Permissions) ────────────────── */
.agent-setting-warning {
font-size: 11px;
color: #d97706;
margin-top: -8px;
padding: 0 55px 8px 0;
line-height: 1.4;
}
.agent-setting-warning-icon {
display: inline-flex;
vertical-align: middle;
margin-right: 4px;
color: #d97706;
}
.agent-setting-warning--high-risk .agent-setting-warning-icon {
color: #d97706;
}
.agent-setting-warning-icon svg {
width: 12px;
height: 12px;
}
/* Disabled state for category toggles when master auto-approve is off */
.agent-approval-categories--disabled {
opacity: 0.4;
pointer-events: none;
}
/* ── Context Display Progress Bar ─────────────────────────────────────── */
.context-display-container {
padding: 8px 12px;
border-bottom: 1px solid var(--background-modifier-border);
background: var(--background-primary);
}
.context-display-labels {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
font-size: 11px;
color: var(--text-muted);
}
.context-progress-bar-wrapper {
position: relative;
}
.context-progress-bar {
display: flex;
height: 4px;
border-radius: 2px;
overflow: hidden;
background: var(--background-modifier-border);
position: relative;
}
.context-segment-current {
height: 100%;
width: var(--ctx-seg-w, 0%);
transition: width 0.3s ease-out;
background: var(--text-normal);
}
.context-segment-reserved {
height: 100%;
width: var(--ctx-seg-w, 0%);
transition: width 0.3s ease-out;
background: var(--text-muted);
opacity: 0.5;
}
.context-segment-available {
height: 100%;
width: var(--ctx-seg-w, 0%);
transition: width 0.3s ease-out;
background: transparent;
}
/* Color variants */
.context-green .context-segment-current {
background: var(--color-green);
}
.context-yellow .context-segment-current {
background: var(--color-yellow);
}
.context-red .context-segment-current {
background: var(--color-red);
}
/* Condense Button */
.context-condense-button {
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
opacity: 0.6;
transition: opacity 0.2s;
color: var(--text-muted);
border-radius: 3px;
}
.context-condense-button:hover {
opacity: 1;
background: var(--background-modifier-hover);
}
.context-condense-button-disabled {
opacity: 0.3;
cursor: not-allowed;
}
.context-condense-button-disabled:hover {
opacity: 0.3;
background: transparent;
}
/* Tooltip */
.context-tooltip {
position: absolute;
top: 24px;
left: 50%;
transform: translateX(-50%);
background: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
padding: 8px;
font-size: 11px;
z-index: 100;
white-space: nowrap;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* Condensation Feedback */
.condensation-feedback {
display: flex;
padding: 8px 12px;
background: var(--background-secondary);
border-radius: 4px;
margin-bottom: 8px;
border-left: 3px solid var(--interactive-accent);
}
.condensation-feedback-header {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
flex: 1;
}
.condensation-icon {
color: var(--interactive-accent);
flex-shrink: 0;
}
.condensation-title {
font-weight: 600;
color: var(--text-normal);
}
.condensation-tokens {
color: var(--text-muted);
}
.condensation-cost {
margin-left: auto;
font-weight: 500;
color: var(--text-accent);
}
/* Timeline Entry for Context Condensing (fallback badge) */
.context-condensed-badge {
display: inline-block;
padding: 2px 6px;
background: var(--interactive-accent);
color: var(--text-on-accent);
border-radius: 3px;
font-size: 11px;
font-weight: 600;
margin-bottom: 4px;
}
.context-condensed-desc {
font-size: 12px;
color: var(--text-muted);
}
/* ReviewBot: no-static-styles-assignment -- dismiss link for task hint */
.agent-u-task-hint-dismiss-link {
display: block;
margin-top: 6px;
font-size: 0.85em;
}
/* ── Implicit Connection Suggestions (FEATURE-1506) ──────────────── */
.agent-suggestions-banner {
border-top: 1px solid var(--background-modifier-border);
background-color: var(--background-secondary);
padding: 0;
flex-shrink: 0;
}
.agent-suggestions-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 12px;
cursor: pointer;
font-size: 0.8em;
font-weight: 500;
color: var(--text-muted);
}
.agent-suggestions-header:hover {
color: var(--text-normal);
}
.agent-suggestions-toggle {
display: flex;
align-items: center;
}
.agent-suggestions-toggle svg {
width: 14px;
height: 14px;
}
.agent-suggestions-header-actions {
display: flex;
align-items: center;
gap: 4px;
}
.agent-suggestions-close {
background: transparent;
border: none;
padding: 2px;
cursor: pointer;
color: var(--text-muted);
display: flex;
align-items: center;
}
.agent-suggestions-close:hover {
color: var(--text-normal);
}
.agent-suggestions-close svg {
width: 14px;
height: 14px;
}
.agent-suggestions-list {
overflow: hidden;
transition: max-height 0.2s ease;
max-height: 300px;
}
.agent-suggestions-list.is-collapsed {
max-height: 0;
}
.agent-suggestion-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 12px;
font-size: 0.78em;
border-top: 1px solid var(--background-modifier-border-hover);
}
.agent-suggestion-item:hover {
background-color: var(--background-modifier-hover);
}
.agent-suggestion-text {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-suggestion-link {
color: var(--text-accent);
}
.agent-suggestion-arrow {
color: var(--text-faint);
margin: 0 2px;
}
.agent-suggestion-score {
color: var(--text-faint);
font-size: 0.9em;
}
.agent-suggestion-actions {
display: flex;
gap: 4px;
margin-left: 8px;
flex-shrink: 0;
}
.agent-suggestion-btn {
background: none;
border: none;
cursor: pointer;
padding: 2px;
border-radius: 4px;
color: var(--text-muted);
display: flex;
align-items: center;
}
.agent-suggestion-btn:hover {
background-color: var(--background-modifier-hover);
color: var(--text-normal);
}
.agent-suggestion-btn svg {
width: 14px;
height: 14px;
}
.agent-suggestion-dismiss:hover {
color: var(--text-error);
}
/* ── Connector Card (MCP Settings) ───────────────────────── */
.agent-mcp-connector-card {
border: 1px solid var(--background-modifier-border);
border-radius: 8px;
padding: 12px 16px;
margin: 8px 0 16px;
background: var(--background-secondary);
}
.agent-mcp-connector-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.agent-mcp-connector-name {
font-weight: 600;
font-size: 0.95em;
}
.agent-mcp-status-badge {
font-size: 0.75em;
padding: 2px 8px;
border-radius: 10px;
font-weight: 500;
}
.agent-mcp-status-badge.running {
background: var(--color-green);
color: var(--text-on-accent);
}
.agent-mcp-status-badge.enabled {
background: var(--color-yellow);
color: var(--text-on-accent);
}
.agent-mcp-status-badge.off {
background: var(--background-modifier-border);
color: var(--text-muted);
}
/* ── Relay Setup Wizard ──────────────────────────────── */
.agent-relay-step {
margin: 12px 0;
padding: 8px 0;
border-bottom: 1px solid var(--background-modifier-border-hover);
}
.agent-relay-step:last-child {
border-bottom: none;
}
.agent-relay-step p {
margin: 4px 0;
font-size: 0.9em;
color: var(--text-muted);
}
.agent-relay-step pre {
background: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
padding: 8px 12px;
margin: 6px 0;
font-size: 0.85em;
overflow-x: auto;
}
.agent-relay-step code {
font-family: var(--font-monospace);
white-space: pre;
}
/* ── Settings buttons: muted look across all Vault Operator tabs ──────────
* Sebastian feedback 2026-05-20 (FEAT-29-01):
* Plugin settings buttons should all render in the muted opacity used by
* Obsidian's disabled-button state, regardless of enabled/disabled status.
* Disabled-state cues come from the tooltip on hover plus the no-op notice
* on click, not from a separate visual treatment. Selector scoped to the
* Obsidian settings modal so other plugins are unaffected.
*/
.modal-container .vertical-tab-content .setting-item-control > button,
.modal-container .vertical-tab-content .setting-item-control > .clickable-icon,
.modal-container .vertical-tab-content .setting-item-control > .extra-setting-button {
opacity: 0.65;
transition: opacity 0.15s ease;
}
.modal-container .vertical-tab-content .setting-item-control > button:hover:not(:disabled),
.modal-container .vertical-tab-content .setting-item-control > .clickable-icon:hover,
.modal-container .vertical-tab-content .setting-item-control > .extra-setting-button:hover {
opacity: 1;
}
.modal-container .vertical-tab-content .setting-item-control > button:disabled {
opacity: 0.45;
cursor: not-allowed;
}
/* FEAT-29-09 SkillVersionsModal -- moved off element.style.setProperty */
.skill-version-row {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 0;
border-bottom: 1px solid var(--background-modifier-border);
}
.skill-version-info { flex: 1; }
.skill-version-meta { font-size: 12px; }
.skill-version-actions { display: flex; gap: 4px; }
/* FEAT-29-08 PartialTranslationModal -- moved off element.style.setProperty */
.partial-translation-table {
width: 100%;
border-collapse: collapse;
margin: 12px 0;
}
.partial-translation-table th {
text-align: left;
padding: 4px 8px;
border-bottom: 1px solid var(--background-modifier-border);
}
.partial-translation-table td { padding: 4px 8px; }
.partial-translation-heading { margin-top: 16px; }
.partial-translation-reason { font-size: 0.9em; }
.partial-translation-button-bar {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 20px;
}
/* ── Inline-Editor-AI-Actions (EPIC-33) ───────────────────────────── */
.agent-inline-menu {
position: absolute;
z-index: 1000;
background: var(--background-secondary);
color: var(--text-normal);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
padding: 4px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
font-size: var(--font-ui-small);
user-select: none;
}
.agent-inline-menu__item {
display: block;
width: 100%;
text-align: left;
background: transparent;
color: inherit;
border: none;
padding: 6px 10px;
border-radius: 4px;
cursor: pointer;
font: inherit;
}
.agent-inline-menu__item:hover,
.agent-inline-menu__item:focus {
background: var(--background-modifier-hover);
outline: none;
}
.agent-inline-menu__item:active {
background: var(--background-modifier-active-hover);
}
.agent-inline-action-preview {
background: var(--background-primary-alt);
border: 1px solid var(--background-modifier-border);
border-radius: 6px;
padding: 10px 12px;
margin: 8px 0;
font-size: var(--font-ui-small);
}
.agent-inline-action-preview__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 6px;
font-weight: 600;
}
.agent-inline-action-preview__body {
white-space: pre-wrap;
}
.agent-inline-action-preview__actions {
display: flex;
gap: 6px;
margin-top: 8px;
}
.agent-inline-diff-add {
background: rgba(40, 167, 69, 0.18);
border-bottom: 1px solid rgba(40, 167, 69, 0.6);
}
.agent-inline-diff-remove {
background: rgba(220, 53, 69, 0.18);
text-decoration: line-through;
border-bottom: 1px solid rgba(220, 53, 69, 0.6);
}
.agent-inline-diff-hunk-actions {
display: inline-flex;
gap: 4px;
margin-left: 4px;
}
.agent-inline-diff-hunk-actions button {
font-size: 11px;
padding: 2px 6px;
border-radius: 3px;
background: var(--background-modifier-hover);
color: var(--text-normal);
border: 1px solid var(--background-modifier-border);
cursor: pointer;
}
/* ── Inline Chat Panel (EPIC-33 UX-refresh) ───────────────────────── */
.agent-inline-panel {
position: absolute;
z-index: 1000;
display: flex;
flex-direction: column;
background: var(--background-primary);
color: var(--text-normal);
/* User feedback 2026-06-24 (round 3): bumped to the faint-text token
and 2 px so the frame reads as a distinct enclosure against busy
note backgrounds in both light and dark mode. Earlier
`--background-modifier-border-hover` was still too subtle. */
border: 2px solid var(--text-faint);
border-radius: 8px;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.25);
font-size: var(--font-ui-small);
/* overflow: visible so the @-mention / slash-command autocomplete
dropdown can rise above the composer (the dropdown lives inside
.chat-input-container and uses position:absolute + bottom:100%).
The chat-bubble scroll area has its own overflow-y:auto, so the
panel's content still scrolls properly. */
overflow: visible;
}
/* FEAT-33-12: inline-block variant -- panel renders inside a CM6 block
widget so it flows with the editor instead of overlaying it. Position is
handled by the CM6 layout, the panel is full-width. `position: relative`
(not static) so the absolute close button anchors to the panel itself
(user feedback 2026-06-24 round 3: previously the X drifted into the
composer area because it fell through to a far-away positioned
ancestor when the panel was static). */
.agent-inline-panel--inline-block {
position: relative;
z-index: auto;
width: 100%;
max-height: 60vh;
/* User feedback 2026-06-24 round 3: a full text line of breathing room
above + below so the panel visually detaches from prose. Earlier
0.75 em felt cramped. */
margin: 1.5em 0;
box-shadow: 0 2px 14px rgba(0, 0, 0, 0.22);
}
/* The composer is the bottom-most child and carries its own background
from the sidebar styles. With the panel's `overflow: visible` (needed
so the autocomplete dropdown can escape the composer rect), the
composer's square background was painting over the panel's rounded
bottom corners. Round the composer's bottom corners to the same
radius minus the border width so the visible curve stays continuous
with the frame. (user feedback 2026-06-24 round 3) */
.agent-inline-panel .agent-inline-panel__composer {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
overflow: hidden;
}
.agent-inline-panel--inline-block .agent-inline-panel__drag-handle,
.agent-inline-panel--inline-block .agent-inline-panel__resize-handle {
display: none;
}
/* Wrapper the CM6 block-widget hands to CodeMirror. Acts as a flex
container so the panel can expand vertically without breaking the
editor's line layout. overflow:visible so the autocomplete dropdown
can escape the widget bounds (same reason as .agent-inline-panel). */
.agent-inline-chat-block {
display: block;
width: 100%;
/* Matching breathing room on the CM6 block wrapper so the half-line
margin is honored even if the inner panel's margin collapses with
the wrapper. */
margin: 0.75em 0;
overflow: visible;
}
/* FEAT-33-12 (user feedback 2026-06-24): selection-affordance pill.
Appears next to a settled selection and -- on click -- opens the
inline chat. position:fixed so it floats independently of the
editor scroll layer; left/top are set per-instance via setCssStyles
based on the live selection rect. Keep this LIGHT: the pill must
not feel like a modal or popover. */
/* FEAT-33-12 selection-affordance pill -- intentionally chromeless.
Bare lucide icon in the accent colour, sitting above the top-right
corner of the marked text. The class is doubled in the selector
('.agent-inline-action-pill.agent-inline-action-pill') to win over
theme-level button rules that would otherwise paint a background or
border. `appearance: none` neutralises the native button chrome.
svg uses stroke: currentColor so the lucide stroke inherits the
pill's color (which is what makes the accent colour visible idle). */
.agent-inline-action-pill.agent-inline-action-pill {
position: fixed;
z-index: 1100;
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
padding: 0;
margin: 0;
appearance: none;
-webkit-appearance: none;
background: transparent;
background-color: transparent;
background-image: none;
color: var(--interactive-accent);
border: none;
border-radius: 0;
box-shadow: none;
outline: none;
cursor: pointer;
opacity: 1;
transition: color 80ms ease-out, transform 80ms ease-out;
}
.agent-inline-action-pill.agent-inline-action-pill:hover,
.agent-inline-action-pill.agent-inline-action-pill:focus,
.agent-inline-action-pill.agent-inline-action-pill:focus-visible,
.agent-inline-action-pill.agent-inline-action-pill:active {
background: transparent;
background-color: transparent;
background-image: none;
border: none;
box-shadow: none;
outline: none;
}
.agent-inline-action-pill.agent-inline-action-pill:hover {
color: var(--interactive-accent-hover, var(--interactive-accent));
transform: scale(1.15);
}
.agent-inline-action-pill.agent-inline-action-pill:active {
transform: scale(1);
}
.agent-inline-action-pill svg {
width: 18px;
height: 18px;
color: inherit;
stroke: currentColor;
fill: none;
}
/* FEAT-33-12 (user feedback 2026-06-24): persistent highlight of the
selection that triggered the inline chat. The native DOM selection
disappears as soon as the user clicks into the chat composer, so we
paint the same range as a CodeMirror mark decoration. The decoration
survives focus changes and is cleaned up when the inline chat closes.
Background colour is intentionally distinct from native selection so
the user can tell "this is what the chat is working on" vs an active
text selection. */
.agent-inline-selection-highlight {
background-color: var(--text-selection);
border-bottom: 2px solid var(--interactive-accent);
}
.agent-inline-panel__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 6px 10px;
background: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
}
/* Selection preview at the top of the panel. */
.agent-inline-panel__anchor {
position: relative;
padding: 8px 28px 8px 12px;
background: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.agent-inline-panel__anchor-label {
font-size: var(--font-ui-smaller);
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
margin-bottom: 4px;
}
.agent-inline-panel__anchor-text {
color: var(--text-normal);
font-size: var(--font-ui-small);
line-height: 1.4;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 4.4em;
overflow: hidden;
}
.agent-inline-panel__anchor-text--expanded {
max-height: 320px;
overflow-y: auto;
}
/* Anchor-toggle: same frameless treatment as the close button.
Obsidian default `button` background is forced to transparent via
!important so no theme can re-introduce the tile on hover. */
/* Pattern M (class repetition) instead of !important: doubling the
* class bumps specificity from (0,1,0) to (0,2,0) which beats both
* `button { background: var(--interactive-normal) }` and most theme
* `.popover button` overrides without the bot's avoid-!important
* warning. Verified visually in the 3.0.x release. */
.agent-inline-panel__anchor-toggle.agent-inline-panel__anchor-toggle,
.agent-inline-panel__anchor-toggle.agent-inline-panel__anchor-toggle:hover,
.agent-inline-panel__anchor-toggle.agent-inline-panel__anchor-toggle:focus,
.agent-inline-panel__anchor-toggle.agent-inline-panel__anchor-toggle:active,
.agent-inline-panel__anchor-toggle.agent-inline-panel__anchor-toggle:focus-visible {
background: transparent;
background-color: transparent;
border: none;
box-shadow: none;
outline: none;
}
.agent-inline-panel__anchor-toggle {
position: absolute;
bottom: 4px;
right: 6px;
color: var(--text-muted);
cursor: pointer;
padding: 2px 4px;
display: flex;
align-items: center;
justify-content: center;
}
.agent-inline-panel__anchor-toggle:hover {
color: var(--text-normal);
}
.agent-inline-panel__anchor-toggle-icon {
display: inline-flex;
width: 14px;
height: 14px;
line-height: 1;
}
.agent-inline-panel__anchor-toggle-icon svg {
width: 14px;
height: 14px;
}
/* Close button (absolute top-right corner). */
/* Close button: frameless icon button, mirrors the other icon
buttons in the panel. NO background ever (Obsidian's default
`button { background: var(--interactive-normal) }` would otherwise
render a tile on hover). `!important` is the cleanest way to
ensure no theme accidentally re-introduces the tile. */
/* Pattern M (class repetition): same approach as the anchor toggle
* block above -- doubling the class bumps specificity to (0,2,0) so
* the no-tile rule wins without `!important`. */
.agent-inline-panel__close.agent-inline-panel__close,
.agent-inline-panel__close.agent-inline-panel__close:hover,
.agent-inline-panel__close.agent-inline-panel__close:focus,
.agent-inline-panel__close.agent-inline-panel__close:active,
.agent-inline-panel__close.agent-inline-panel__close:focus-visible {
background: transparent;
background-color: transparent;
border: none;
box-shadow: none;
outline: none;
}
.agent-inline-panel__close {
position: absolute;
top: 4px;
right: 6px;
color: var(--text-muted);
cursor: pointer;
font-size: 18px;
line-height: 1;
padding: 2px 6px;
z-index: 1;
}
.agent-inline-panel__close:hover {
color: var(--text-normal);
}
/* Drag handle: slim strip at the top of the panel. Pointer drag
* moves the whole window. Centered grip dots hint at the affordance
* but stay subtle so the panel does not look like a system window. */
.agent-inline-panel__drag-handle {
flex: 0 0 auto;
height: 14px;
cursor: move;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-faint);
user-select: none;
-webkit-user-select: none;
opacity: 0.55;
transition: opacity 0.12s ease;
}
.agent-inline-panel__drag-handle::before {
content: '⋯⋯';
font-size: 14px;
letter-spacing: 2px;
line-height: 1;
}
.agent-inline-panel__drag-handle:hover {
opacity: 0.95;
}
/* Resize handle: corner triangle in the bottom-right. Sits absolutely
* inside the panel root so the body keeps its full flex extent. */
.agent-inline-panel__resize-handle {
position: absolute;
right: 2px;
bottom: 2px;
width: 14px;
height: 14px;
cursor: nwse-resize;
background:
linear-gradient(135deg,
transparent 0%, transparent 50%,
var(--text-faint) 50%, var(--text-faint) 60%,
transparent 60%, transparent 70%,
var(--text-faint) 70%, var(--text-faint) 80%,
transparent 80%);
opacity: 0.6;
z-index: 2;
}
.agent-inline-panel__resize-handle:hover {
opacity: 1;
}
/* Message body (flex column, scrollable). */
.agent-inline-panel__body {
flex: 1;
min-height: 100px;
max-height: 320px;
overflow-y: auto;
padding: 10px 12px;
display: flex;
flex-direction: column;
gap: 8px;
}
.agent-inline-panel__body:empty {
min-height: 40px;
}
/* Message bubbles -- mirror the sidebar's .message-content pattern:
assistant text has NO background and NO border, user bubble carries
a subtle accent-tint with asymmetric radius. Identical numbers as
styles.css lines 350-484 (sidebar). */
.agent-inline-panel__bubble {
padding: 7px 10px;
border-radius: 8px;
line-height: 1.45;
font-size: 13px;
white-space: normal;
word-wrap: break-word;
max-width: 100%;
border: none;
background: transparent;
user-select: text;
cursor: text;
}
.agent-inline-panel__bubble--user {
background: color-mix(in srgb, var(--interactive-accent) 20%, var(--background-primary));
color: var(--text-normal);
align-self: flex-end;
max-width: 85%;
border-radius: 12px 12px 4px 12px;
padding: 6px 11px;
border: none;
}
.agent-inline-panel__bubble--assistant {
background: transparent;
border: none;
align-self: stretch;
max-width: 100%;
padding: 4px 2px;
}
.agent-inline-panel__bubble--system {
background: transparent;
align-self: center;
font-size: var(--font-ui-smaller);
font-style: italic;
color: var(--text-muted);
border: none;
}
/* Rendered Markdown inside the assistant bubble: same paragraph
spacing + heading treatment as the sidebar .message-content. */
.agent-inline-panel__bubble--assistant p {
margin: 0 0 8px 0;
}
.agent-inline-panel__bubble--assistant p:last-child { margin-bottom: 0; }
.agent-inline-panel__bubble--assistant ul,
.agent-inline-panel__bubble--assistant ol {
margin-left: 0;
padding-left: 16px;
margin-bottom: 8px;
}
.agent-inline-panel__bubble--assistant li { margin-bottom: 4px; }
.agent-inline-panel__bubble--assistant h1,
.agent-inline-panel__bubble--assistant h2,
.agent-inline-panel__bubble--assistant h3,
.agent-inline-panel__bubble--assistant h4 {
margin-top: 14px;
margin-bottom: 8px;
font-weight: 600;
}
.agent-inline-panel__bubble--assistant h1:first-child,
.agent-inline-panel__bubble--assistant h2:first-child,
.agent-inline-panel__bubble--assistant h3:first-child {
margin-top: 0;
}
.agent-inline-panel__bubble--assistant code {
background: var(--background-secondary);
padding: 0 4px;
border-radius: 3px;
font-size: 0.92em;
}
.agent-inline-panel__bubble--assistant pre {
background: var(--background-secondary);
padding: 8px 10px;
border-radius: 4px;
overflow-x: auto;
margin: 8px 0;
}
.agent-inline-panel__bubble--assistant pre code {
background: transparent;
padding: 0;
}
/* Status pill. */
.agent-inline-panel__status {
padding: 4px 12px;
font-size: var(--font-ui-smaller);
color: var(--text-muted);
border-top: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
}
.agent-inline-panel__status--error {
color: var(--text-error);
background: var(--background-modifier-error-hover);
}
/* Composer wrapper inside the panel: cap padding so the sidebar
styles do not push the panel beyond its width budget. */
.agent-inline-panel__composer {
border-top: 1px solid var(--background-modifier-border);
padding: 6px 8px;
}
/* Lookup-Button is the inline-specific quick-action sitting next to "+". */
.agent-inline-panel .lookup-button {
/* Inherits .toolbar-button base styling from the sidebar; no extra
rules needed beyond hover hint that matches the sidebar buttons. */
}
.agent-inline-panel .lookup-button:hover {
color: var(--interactive-accent);
}
/* Constrain the composer textarea so it fits the panel width. */
.agent-inline-panel .chat-textarea {
min-height: 60px;
max-height: 140px;
}
/* ── EditReviewPanel: the approval gate (FEAT-44-15 redesign) ─────────
*
* The gate is what the user reads before the agent writes, so it has to be
* readable first and pretty second.
*
* The one structural rule: there is ONE scroll container (`__body`) holding ONE
* row element per diff line, and each row is a two-column grid. A grid row is as
* tall as its tallest cell, so when a German paragraph wraps to three lines on
* the left and one on the right, BOTH cells become three lines tall and the two
* sides stay in lock-step. No JavaScript, no scroll syncing, no measuring.
*
* The previous build had two independent scroll containers, which cannot work:
* that is diff2html's long-standing bug (#99) -- when a line wraps in one table,
* the other table has no way to learn about it.
*/
/* `.agent-edit-review-modal` lands on the `.modal` element itself, so the
* selector must be `.modal.agent-edit-review-modal`. Repeating the class lifts
* specificity above Obsidian's own `.modal` width rules without `!important`. */
.modal.agent-edit-review-modal.agent-edit-review-modal.agent-edit-review-modal {
/* Capped, not 95vw. On a wide monitor 95vw gave each column ~1000px, which is
* roughly 130 characters of prose -- you have to move your head to take one
* line in, and comparing two of them side by side stops working. 1240px total
* puts each column near 70 characters, which is the range typography has
* agreed on for a century. */
width: min(1240px, 95vw);
min-width: min(900px, 96vw);
max-width: min(1240px, 95vw);
height: 88vh;
max-height: 88vh;
}
.modal.agent-edit-review-modal .modal-content {
padding: 0;
height: 100%;
overflow: hidden;
}
.agent-edit-review {
display: flex;
flex-direction: column;
height: 100%;
min-height: 420px;
background: var(--background-primary);
color: var(--text-normal);
/* Colour tokens. Only --color-red/-green/-blue/-orange and their -rgb
* variants are reliable across themes; --background-modifier-error is a
* solid dark red in some themes and a soft tint in others, so it is unusable
* for a tint. The row tint stays soft and the word highlight carries the
* signal -- that is the pattern every mature diff converged on. */
--vo-add-row: rgba(var(--color-green-rgb), 0.10);
--vo-add-word: rgba(var(--color-green-rgb), 0.32);
--vo-add-bar: var(--color-green);
--vo-del-row: rgba(var(--color-red-rgb), 0.09);
--vo-del-word: rgba(var(--color-red-rgb), 0.26);
--vo-del-bar: var(--color-red);
}
.theme-dark .agent-edit-review {
--vo-add-row: rgba(var(--color-green-rgb), 0.13);
--vo-add-word: rgba(var(--color-green-rgb), 0.30);
--vo-del-row: rgba(var(--color-red-rgb), 0.16);
--vo-del-word: rgba(var(--color-red-rgb), 0.36);
}
/* Header ------------------------------------------------------------- */
.agent-edit-review__header {
padding: 14px 18px 10px;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-edit-review__title {
font-size: var(--font-ui-medium);
font-weight: 600;
color: var(--text-normal);
}
.agent-edit-review__subtitle {
margin-top: 2px;
font-size: var(--font-ui-smaller);
color: var(--text-muted);
}
.agent-edit-review__empty {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
.agent-edit-review__main {
flex: 1;
display: flex;
min-height: 0;
}
/* File list (only when more than one file) ---------------------------- */
.agent-edit-review__filelist {
width: 220px;
flex-shrink: 0;
border-right: 1px solid var(--background-modifier-border);
overflow-y: auto;
padding: 10px 0;
background: var(--background-secondary);
}
.agent-edit-review__filelist-heading {
padding: 0 14px 8px;
font-size: var(--font-ui-smaller);
color: var(--text-faint);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.agent-edit-review__file {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 6px 14px;
border: none;
border-radius: 0;
background: transparent;
color: var(--text-muted);
font-size: var(--font-ui-small);
text-align: left;
cursor: pointer;
box-shadow: none;
}
.agent-edit-review__file:hover {
background: var(--background-modifier-hover);
color: var(--text-normal);
}
.agent-edit-review__file.is-selected {
background: var(--background-modifier-active-hover);
color: var(--text-normal);
font-weight: 500;
}
.agent-edit-review__file.is-skipped .agent-edit-review__file-label {
text-decoration: line-through;
opacity: 0.55;
}
.agent-edit-review__file-status {
color: var(--text-faint);
font-family: var(--font-monospace);
}
.agent-edit-review__file-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Diff pane ----------------------------------------------------------- */
.agent-edit-review__diff {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
.agent-edit-review__diff-header {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
border-bottom: 1px solid var(--background-modifier-border);
}
.agent-edit-review__diff-path {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--font-ui-small);
color: var(--text-muted);
}
.agent-edit-review__stats {
font-size: var(--font-ui-smaller);
font-variant-numeric: tabular-nums;
color: var(--text-faint);
white-space: nowrap;
}
.agent-edit-review__stats.is-changed {
color: var(--text-muted);
}
.agent-edit-review__edit-btn,
.agent-edit-review__skip-btn {
padding: 3px 10px;
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
background: transparent;
color: var(--text-muted);
font-size: var(--font-ui-smaller);
cursor: pointer;
box-shadow: none;
white-space: nowrap;
}
.agent-edit-review__edit-btn:hover,
.agent-edit-review__skip-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.agent-edit-review__edit-btn.is-active,
.agent-edit-review__skip-btn.is-active {
color: var(--text-on-accent);
background: var(--interactive-accent);
border-color: var(--interactive-accent);
}
/* Column headings ------------------------------------------------------ */
.agent-edit-review__edit-discard-btn {
padding: 3px 10px;
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
background: transparent;
color: var(--text-muted);
font-size: var(--font-ui-smaller);
cursor: pointer;
box-shadow: none;
white-space: nowrap;
}
.agent-edit-review__edit-discard-btn:hover {
color: var(--text-error);
background: var(--background-modifier-hover);
}
.agent-edit-review__edit-discard-btn.is-hidden {
display: none;
}
.agent-edit-review__colheads {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
border-bottom: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
}
.agent-edit-review__colhead {
padding: 5px 14px;
font-size: var(--font-ui-smaller);
color: var(--text-faint);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.agent-edit-review__colhead + .agent-edit-review__colhead {
box-shadow: inset 1px 0 0 0 var(--background-modifier-border);
}
/* THE single scroll container ------------------------------------------ */
.agent-edit-review__body {
flex: 1;
overflow-y: auto;
/* Prose wraps. It is never scrolled sideways. */
overflow-x: hidden;
/* Proportional, not monospace: this is German prose, not code. Monospace
* eats 20-30 % more width for the same characters and reads as "code". */
font-family: var(--font-text);
font-size: var(--font-ui-medium);
line-height: 1.6;
padding: 6px 0 24px;
}
.agent-edit-review.is-editing .agent-edit-review__body,
.agent-edit-review.is-editing .agent-edit-review__colheads {
display: none;
}
.agent-edit-review__empty-diff {
padding: 24px 14px;
color: var(--text-faint);
text-align: center;
}
/* Sticky section heading: in a note THIS is what orients you, not a line
* number. Nobody references line 47 of a transcript. */
.agent-edit-review__hunk-head {
position: sticky;
top: 0;
z-index: 1;
padding: 4px 14px;
background: var(--background-secondary);
border-top: 1px solid var(--background-modifier-border);
border-bottom: 1px solid var(--background-modifier-border);
font-size: var(--font-ui-smaller);
font-weight: 600;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* One row = one diff line = both columns. The row is as tall as its tallest
* cell, which is the entire alignment mechanism. */
.agent-edit-review__row {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
align-items: stretch;
/* Free virtualization: the browser skips layout and paint for rows that are
* off-screen. `auto` in contain-intrinsic-size makes it remember the height
* it last measured, which is what variable-height wrapped rows need. */
content-visibility: auto;
contain-intrinsic-size: auto 26px;
}
.agent-edit-review__row--collapsed {
grid-template-columns: 1fr;
}
.agent-edit-review__collapsed {
width: 100%;
padding: 3px 14px;
margin: 3px 0;
background: var(--background-secondary);
border: none;
border-top: 1px solid var(--background-modifier-border);
border-bottom: 1px solid var(--background-modifier-border);
border-radius: 0;
box-shadow: none;
color: var(--text-faint);
font-size: var(--font-ui-smaller);
text-align: center;
cursor: pointer;
}
.agent-edit-review__collapsed:hover {
background: var(--background-modifier-hover);
color: var(--text-muted);
}
.agent-edit-review__cell {
display: grid;
/* Marker slot | text. Row-invariant, so the text edges line up down the
* whole column. */
grid-template-columns: 1.5em minmax(0, 1fr);
align-items: start;
/* Grid blowout guard. Together with minmax(0,1fr) and overflow-wrap:anywhere
* below, this is what stops one long URL from bursting the column. */
min-width: 0;
/* The change bar slot is ALWAYS there, so a changed line does not shift the
* text by 3px relative to an unchanged one. */
border-left: 3px solid transparent;
padding: 1px 12px 1px 0;
}
.agent-edit-review__cell--new {
box-shadow: inset 1px 0 0 0 var(--background-modifier-border);
}
.agent-edit-review__cell.is-del {
background: var(--vo-del-row);
border-left-color: var(--vo-del-bar);
}
.agent-edit-review__cell.is-add {
background: var(--vo-add-row);
border-left-color: var(--vo-add-bar);
}
.agent-edit-review__cell.is-pad {
background: var(--background-secondary);
opacity: 0.4;
}
/* Redundant, non-colour cue (WCAG 1.4.1: meaning must not rest on colour
* alone -- ~8 % of men cannot separate red from green). */
.agent-edit-review__marker {
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
line-height: 1.6;
text-align: center;
color: var(--text-faint);
user-select: none;
}
.agent-edit-review__cell.is-del .agent-edit-review__marker {
color: var(--vo-del-bar);
}
.agent-edit-review__cell.is-add .agent-edit-review__marker {
color: var(--vo-add-bar);
}
.agent-edit-review__text {
min-width: 0;
white-space: pre-wrap;
/* `anywhere`, NOT `break-word`. Only `anywhere` is honoured when the browser
* computes min-content, so a 200-character URL cannot force the grid track
* wider than its share. With `break-word` the column still bursts. */
overflow-wrap: anywhere;
}
.agent-edit-review__text.is-mono {
font-family: var(--font-monospace);
font-size: var(--font-ui-small);
}
/* The word-level highlight. The row tint says WHICH line changed; this says
* WHAT changed in it. That contrast is the whole readability gain. */
.agent-edit-review__word {
border-radius: 3px;
padding: 0 1px;
}
/* text-decoration-thickness / -color are only partially supported on the
* Electron build behind Obsidian 1.7.4, so the strike is left at its default
* weight and inherits the text colour. The row tint already carries the
* del/add signal; the strike only has to be visible. */
.agent-edit-review__word.is-del-word {
background: var(--vo-del-word);
text-decoration: line-through;
}
.agent-edit-review__word.is-add-word {
background: var(--vo-add-word);
}
/* Editing surface: a plain textarea. Separate from the diff on purpose -- the
* old contenteditable WAS the diff, so the highlighting fell apart as soon as
* you typed, and the text had to be scraped back out of the mangled DOM. */
.agent-edit-review__textarea {
display: none;
flex: 1;
width: 100%;
margin: 0;
border: none;
border-radius: 0;
padding: 12px 16px;
background: var(--background-primary);
color: var(--text-normal);
font-family: var(--font-text);
font-size: var(--font-ui-medium);
line-height: 1.6;
resize: none;
outline: none;
}
.agent-edit-review.is-editing .agent-edit-review__textarea {
display: block;
}
/* Deleting: the whole note is the loss. Say so, do not just tint it. */
.agent-edit-review.is-deleting .agent-edit-review__colhead + .agent-edit-review__colhead {
color: var(--vo-del-bar);
}
/* Footer -------------------------------------------------------------- */
.agent-edit-review__footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding: 12px 16px;
border-top: 1px solid var(--background-modifier-border);
background: var(--background-secondary);
}
.agent-edit-review__apply-run-btn,
.agent-edit-review__apply-session-btn {
border: 1px solid var(--background-modifier-border);
background: transparent;
color: var(--text-muted);
box-shadow: none;
}
.agent-edit-review__apply-run-btn:hover,
.agent-edit-review__apply-session-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.agent-edit-review__discard-btn {
border: 1px solid var(--background-modifier-border);
background: transparent;
color: var(--text-muted);
box-shadow: none;
}
.agent-edit-review__discard-btn:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
/* Checkpoint marker in the inline panel inherits the sidebar
* `.checkpoint-marker` rules (divider lines + ghost icon buttons). The
* legacy `.agent-inline-panel__checkpoint-*` styles were removed when
* the inline marker adopted the sidebar DOM (EPIC-33 checkpoint-
* parity wave, 2026-06-23). The remaining
* `.agent-inline-panel__bubble--checkpoint` modifier raises the
* default opacity from the sidebar's 0.5 (decorative) to a fully
* visible state -- in the inline panel the marker IS the main
* post-edit affordance, not a separator between tool steps. */
.agent-inline-panel__bubble--checkpoint {
align-self: stretch;
max-width: 100%;
padding: 4px 6px;
}
.agent-inline-panel__bubble--checkpoint.checkpoint-marker {
opacity: 1;
color: var(--text-normal);
font-size: var(--font-ui-small);
}
.agent-inline-panel__bubble--checkpoint .checkpoint-label {
font-size: var(--font-ui-small);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.agent-inline-panel__bubble--checkpoint .checkpoint-action-btn {
opacity: 0.8;
}
.agent-inline-panel__bubble--checkpoint .checkpoint-action-btn:hover {
opacity: 1;
}
/* FEAT-42-05: clickable language-pack download notice */
.agent-clickable-notice {
cursor: pointer;
}