/* * GNU AGPL-3.0 License * * Copyright (c) 2021 - present core.ai . All rights reserved. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License * for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see https://opensource.org/licenses/AGPL-3.0. * */ /* Terminal Extension Styles */ /* Dark theme (default) */ .dark .terminal-panel-container, .darkTheme .terminal-panel-container { --terminal-background: #1e1e1e; --terminal-foreground: #cccccc; --terminal-cursor: #ffffff; --terminal-selection: rgba(255, 255, 255, 0.2); --terminal-scrollbar-thumb: rgba(255, 255, 255, 0.24); --terminal-border: #333333; --terminal-toolbar-bg: #1e1e1e; --terminal-tab-bg: #181818; --terminal-tab-text: #999999; --terminal-tab-active-bg: rgba(255, 255, 255, 0.05); --terminal-tab-active-text: #cccccc; --terminal-ansi-black: #000000; --terminal-ansi-red: #cd3131; --terminal-ansi-green: #0dbc79; --terminal-ansi-yellow: #e5e510; --terminal-ansi-blue: #2472c8; --terminal-ansi-magenta: #bc3fbc; --terminal-ansi-cyan: #11a8cd; --terminal-ansi-white: #e5e5e5; --terminal-ansi-bright-black: #666666; --terminal-ansi-bright-red: #f14c4c; --terminal-ansi-bright-green: #23d18b; --terminal-ansi-bright-yellow: #f5f543; --terminal-ansi-bright-blue: #3b8eea; --terminal-ansi-bright-magenta: #d670d6; --terminal-ansi-bright-cyan: #29b8db; --terminal-ansi-bright-white: #ffffff; } /* Light theme */ .terminal-panel-container { --terminal-background: #ffffff; --terminal-foreground: #383a42; --terminal-cursor: #383a42; --terminal-selection: rgba(0, 0, 0, 0.12); --terminal-scrollbar-thumb: @linux-scrollbar-thumb; --terminal-border: #e0e0e0; --terminal-toolbar-bg: #f5f5f5; --terminal-tab-bg: #eeeeee; --terminal-tab-text: #666666; --terminal-tab-active-bg: rgba(0, 0, 0, 0.05); --terminal-tab-active-text: #333333; --terminal-ansi-black: #383a42; --terminal-ansi-red: #e45649; --terminal-ansi-green: #50a14f; --terminal-ansi-yellow: #c18401; --terminal-ansi-blue: #4078f2; --terminal-ansi-magenta: #a626a4; --terminal-ansi-cyan: #0184bc; --terminal-ansi-white: #a0a1a7; --terminal-ansi-bright-black: #4f525e; --terminal-ansi-bright-red: #e06c75; --terminal-ansi-bright-green: #98c379; --terminal-ansi-bright-yellow: #d19a66; --terminal-ansi-bright-blue: #61afef; --terminal-ansi-bright-magenta: #c678dd; --terminal-ansi-bright-cyan: #56b6c2; --terminal-ansi-bright-white: #ffffff; } .terminal-panel-container { display: flex; flex-direction: column; height: 100%; background: var(--terminal-toolbar-bg); } /* Body: content + tab bar spacer */ .terminal-body { display: flex; flex: 1; min-height: 0; position: relative; } /* Tab bar: static sidebar, width switches via .terminal-tabs-expanded on container */ .terminal-tab-bar { position: relative; /* wide enough for a short name; the strip shows names rather than a row of identical terminal icons, which told the tabs apart not at all */ width: 84px; min-width: 84px; } .terminal-tabs-expanded .terminal-tab-bar { width: 159px; min-width: 159px; } /* ─── Tab sidebar: static, no flyout/hover ─── */ .terminal-tab-flyout { display: flex; position: relative; width: 100%; height: 100%; background: var(--terminal-tab-bg); border-left: 1px solid var(--terminal-border); flex-direction: column; overflow: hidden; } /* Fade gradient at bottom of tab list to hint overflow */ .terminal-tab-flyout::after { content: ''; position: absolute; bottom: 29px; /* sits above the actions row */ left: 0; right: 0; height: 20px; background: linear-gradient(to bottom, transparent, var(--terminal-tab-bg)); pointer-events: none; z-index: 1; } /* Tab list: scrollable, scrollbar hidden, scroll via wheel/trackpad */ .terminal-tab-flyout .terminal-flyout-list { flex: 1; min-height: 0; overflow-x: hidden; overflow-y: auto; scrollbar-width: none; &::-webkit-scrollbar { display: none; } } /* Flyout item */ .terminal-flyout-item { position: relative; display: flex; align-items: center; height: 28px; min-height: 28px; cursor: pointer; color: var(--terminal-tab-active-text); font-size: 12px; white-space: nowrap; overflow: hidden; } .terminal-flyout-item:hover { background: rgba(255, 255, 255, 0.05); } .terminal-flyout-item.active { background: var(--terminal-tab-active-bg); color: var(--terminal-tab-active-text); box-shadow: inset 2px 0 0 #007acc; } /* Title always shows; the CWD is what collapsed drops for want of room */ .terminal-flyout-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; } .terminal-flyout-cwd { font-size: 12px; color: var(--terminal-tab-text); flex-shrink: 1; min-width: 0; max-width: 50%; margin-left: 4px; margin-right: 2px; opacity: 0.8; overflow: hidden; text-overflow: ellipsis; display: none; } /* Close button: absolutely positioned on the right, visible on item hover only */ .terminal-flyout-close { position: absolute; right: 0; top: 0; bottom: 0; width: 20px; display: none; align-items: center; justify-content: center; font-size: 10px; color: var(--terminal-tab-text); background: transparent; z-index: 1; } .terminal-flyout-item:hover .terminal-flyout-close { display: flex; } .terminal-flyout-close:hover { color: var(--terminal-tab-active-text); background: rgba(255, 255, 255, 0.1); } /* ─── Expanded mode ─── */ .terminal-tabs-expanded .terminal-flyout-cwd { display: block; } /* Reserve space so cwd text doesn't sit under the close button */ .terminal-tabs-expanded .terminal-flyout-cwd { margin-right: 20px; } /* ─── Tab name and its hover controls ─── */ /* The row always carries its name. The icon it replaces was the same glyph on every row, so it said nothing the name does not say better. */ .terminal-flyout-title { padding-left: 8px; } /* A name the user typed, set apart from the process name detected for them */ .terminal-flyout-item.renamed .terminal-flyout-title { font-style: italic; } /* Rename pencil: sits inboard of the close, so both hover controls share the right edge and the name's left edge never shifts under the pointer. */ .terminal-flyout-edit { position: absolute; right: 20px; top: 0; bottom: 0; width: 20px; display: none; align-items: center; justify-content: center; font-size: 10px; color: var(--terminal-tab-text); background: transparent; z-index: 1; cursor: pointer; } .terminal-flyout-item:hover .terminal-flyout-edit { display: flex; } .terminal-flyout-edit:hover { color: var(--terminal-tab-active-text); background: rgba(255, 255, 255, 0.1); } /* Hovering trades the cwd for the controls. Reserving room for them instead would mean retuning this margin for every control ever added to the right edge — which is how the 20px above went stale the moment a second one appeared — and it leaves the name more room, not less. */ .terminal-flyout-item:hover .terminal-flyout-cwd { display: none; } .terminal-flyout-item:hover .terminal-flyout-title { padding-right: 40px; } /* Rename field, sized to sit on the row rather than grow it. Matched on the attribute as well as the class: the theme's own input[type="text"] sets a height, padding and border of its own, and outranks a lone class, so a plain .terminal-flyout-rename would render at the full row height. This takes the rule above it without !important. */ input[type="text"].terminal-flyout-rename { box-sizing: border-box; flex: 1; min-width: 0; height: 20px; /* all four sides, because the theme gives form inputs a bottom margin of their own and that pushes the field off the row's centre line */ margin: 0 22px 0 6px; padding: 0 4px; font-size: 12px; line-height: 18px; /* background and text colour are left to the theme's own input styling, so this field reads like every other one — white on a light theme rather than a dark patch on a light strip. Only the border is ours, to mark the row as being edited. */ border: 1px solid #007acc; border-radius: 2px; outline: none; } /* Nothing competes with the field while it is open */ .terminal-flyout-item.renaming .terminal-flyout-edit, .terminal-flyout-item.renaming .terminal-flyout-close, .terminal-flyout-item.renaming .terminal-flyout-cwd { display: none; } /* Confirm button, in the slot the pencil and close vacate while editing */ .terminal-flyout-rename-done { position: absolute; right: 0; top: 0; bottom: 0; width: 20px; display: flex; align-items: center; justify-content: center; font-size: 10px; color: var(--terminal-tab-text); background: transparent; z-index: 2; cursor: pointer; } .terminal-flyout-rename-done:hover { color: var(--terminal-tab-active-text); background: rgba(255, 255, 255, 0.1); } /* ─── Flyout bottom actions ─── */ .terminal-flyout-actions { border-top: 1px solid var(--terminal-border); position: relative; } /* New terminal row: + button fills, dropdown chevron on the right */ .terminal-flyout-new-row { display: flex; align-items: center; height: 28px; } .terminal-flyout-new-btn { display: flex; align-items: center; justify-content: center; gap: 6px; flex: 1; height: 100%; padding: 0; cursor: pointer; color: var(--terminal-tab-active-text); font-size: 12px; background: transparent; border: none; overflow: hidden; white-space: nowrap; } .terminal-flyout-new-btn:hover { background: rgba(255, 255, 255, 0.05); } /* Dropdown chevron: visible in both modes */ .terminal-flyout-dropdown-btn { display: flex; align-items: center; justify-content: center; width: 30px; height: 100%; padding: 0; cursor: pointer; color: var(--terminal-tab-text); font-size: 9px; background: transparent; border: none; border-left: 1px solid var(--terminal-border); flex-shrink: 0; } .terminal-flyout-dropdown-btn:hover { background: rgba(255, 255, 255, 0.05); color: var(--terminal-tab-active-text); } /* Icon in action buttons */ .terminal-flyout-btn-icon { font-size: 12px; flex-shrink: 0; } /* Button labels: hidden in collapsed, shown in expanded */ .terminal-btn-label { display: none; } .terminal-tabs-expanded .terminal-btn-label { display: inline; } /* ─── Shell dropdown (positioned on $panel to avoid flyout overflow clip) ─── */ .terminal-shell-dropdown { min-width: 180px; background: var(--terminal-tab-bg); border: 1px solid var(--terminal-border); border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); z-index: 100; padding: 4px 0; } .terminal-shell-dropdown .shell-option { display: flex; align-items: center; gap: 8px; padding: 6px 12px; cursor: pointer; color: var(--terminal-tab-text); font-size: 12px; white-space: nowrap; } .terminal-shell-dropdown .shell-option:hover { background: rgba(255, 255, 255, 0.1); color: var(--terminal-tab-active-text); } .terminal-shell-dropdown .shell-option .shell-default-badge { font-size: 10px; opacity: 0.5; margin-left: auto; } .terminal-shell-dropdown .shell-option .shell-check { width: 14px; font-size: 11px; text-align: center; flex-shrink: 0; } /* ─── Terminal Content Area ─── */ .terminal-content-area { flex: 1; position: relative; background: var(--terminal-background); min-width: 0; overflow: hidden; } .terminal-project-banner { position: absolute; bottom: 0; left: 0; right: 0; z-index: 5; box-sizing: border-box; max-height: 100%; overflow: auto; padding: 8px 10px; background: var(--terminal-toolbar-bg); color: var(--terminal-foreground); border-top: 1px solid var(--terminal-border); border-left: 3px solid var(--terminal-ansi-yellow); box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.2); white-space: normal; .terminal-project-message, .terminal-project-path { padding-right: 28px; } .terminal-project-path { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 4px 0; font-weight: 600; } .terminal-project-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-top: 8px; } .terminal-project-dismiss { position: absolute; top: 5px; right: 6px; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; margin: 0; border: 0; border-radius: 3px; background: transparent; box-shadow: none; color: inherit; font-size: 21px; line-height: 1; cursor: pointer; opacity: 0.75; &:hover { background: rgba(128, 128, 128, 0.18); opacity: 1; } &:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; opacity: 1; } &:disabled { background: transparent; cursor: default; opacity: 0.4; } } } .terminal-instance-container { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: none; box-sizing: border-box; background: var(--terminal-background); } .terminal-instance-container.active { display: block; } /* xterm.js overrides */ .terminal-instance-container .xterm { height: 100%; padding-left: 4px; } .terminal-instance-container .xterm-viewport { overflow-y: auto; background-color: var(--terminal-background) !important; } // xterm draws DOM scrollbars, so the app's native scrollbar selectors do not apply. .terminal-instance-container .xterm .xterm-scrollable-element > .xterm-scrollbar { &:hover { background-color: var(--terminal-scrollbar-track-hover, transparent); } > .xterm-slider { box-sizing: border-box; border: 2px solid transparent; border-radius: 999px; background-color: var(--terminal-scrollbar-thumb); background-clip: padding-box; &:hover { background-color: var(--terminal-scrollbar-thumb-hover, var(--terminal-scrollbar-thumb)); } &.xterm-active { background-color: var(--terminal-scrollbar-thumb-active, var(--terminal-scrollbar-thumb)); } .platform-win & { border: none; border-radius: 0; } } } // Match the Windows colors in brackets_scrollbars.less, including the always-dark AI terminals. .platform-win .terminal-panel-container { --terminal-scrollbar-thumb: @win-scrollbar-thumb; --terminal-scrollbar-thumb-hover: @win-scrollbar-thumb-hover; --terminal-scrollbar-thumb-active: @win-scrollbar-thumb-active; --terminal-scrollbar-track-hover: @win-scrollbar-track; } .dark.platform-win .terminal-panel-container, .darkTheme.platform-win .terminal-panel-container, .platform-win .ai-chat-body-cli { --terminal-scrollbar-thumb: rgb(49, 49, 49); --terminal-scrollbar-thumb-hover: rgb(89, 89, 89); --terminal-scrollbar-thumb-active: rgb(169, 169, 169); --terminal-scrollbar-track-hover: rgba(15, 15, 15, 0.5); } /* Empty state */ .terminal-empty-state { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--terminal-tab-text); font-size: 13px; }