Changeset 0.25.0 (#160)
This commit is contained in:
153
src/css/admin-surfaces.css
Normal file
153
src/css/admin-surfaces.css
Normal file
@@ -0,0 +1,153 @@
|
||||
/* ==========================================
|
||||
Chat Switchboard — Admin Surfaces
|
||||
==========================================
|
||||
v0.25.0: Surface lifecycle management UI.
|
||||
========================================== */
|
||||
|
||||
.admin-surface-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
background: var(--border, #2a2a2e);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.admin-surface-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 14px 16px;
|
||||
background: var(--bg-secondary, #151517);
|
||||
}
|
||||
|
||||
.admin-surface-row:hover {
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.admin-surface-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.admin-surface-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.admin-surface-name {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
.admin-surface-badge {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.admin-surface-badge--core {
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.15));
|
||||
color: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
.admin-surface-badge--extension {
|
||||
background: var(--purple-dim, rgba(160, 120, 255, 0.1));
|
||||
color: var(--purple, #a078ff);
|
||||
}
|
||||
|
||||
.admin-surface-badge--required {
|
||||
background: var(--bg-raised, #2a2a2e);
|
||||
color: var(--text-3, #555);
|
||||
}
|
||||
|
||||
.admin-surface-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text-3, #555);
|
||||
}
|
||||
|
||||
.admin-surface-id {
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.admin-surface-route {
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
font-size: 11px;
|
||||
color: var(--text-3, #555);
|
||||
}
|
||||
|
||||
.admin-surface-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Toggle switch */
|
||||
.admin-surface-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.admin-surface-toggle--locked {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.admin-surface-toggle input[type="checkbox"] {
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background: var(--bg-raised, #2a2a2e);
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.admin-surface-toggle input[type="checkbox"]:checked {
|
||||
background: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
.admin-surface-toggle input[type="checkbox"]::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.admin-surface-toggle input[type="checkbox"]:checked::after {
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
.admin-surface-toggle input[type="checkbox"]:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.admin-surface-toggle-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-2, #999);
|
||||
min-width: 56px;
|
||||
}
|
||||
412
src/css/chat-pane.css
Normal file
412
src/css/chat-pane.css
Normal file
@@ -0,0 +1,412 @@
|
||||
/* ==========================================
|
||||
Chat Switchboard — ChatPane Component CSS
|
||||
==========================================
|
||||
v0.25.0-cs11.1: Self-contained styles for the ChatPane
|
||||
component. Works in any context — sidebar chat, editor
|
||||
assist pane, standalone embed. No external CSS dependencies.
|
||||
========================================== */
|
||||
|
||||
/* ── Container ─────────────────────────────── */
|
||||
|
||||
.chat-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: var(--bg, #0e0e10);
|
||||
}
|
||||
|
||||
/* ── Header Bar (standalone mode) ──────────── */
|
||||
|
||||
.chat-pane-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
background: var(--bg-secondary, #151517);
|
||||
flex-shrink: 0;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.chat-pane-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.chat-pane-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.chat-pane-chat-select {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
background: var(--bg, #0e0e10);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 4px;
|
||||
color: var(--text, #eee);
|
||||
font-size: 11px;
|
||||
font-family: inherit;
|
||||
padding: 4px 6px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.chat-pane-chat-select:focus {
|
||||
border-color: var(--accent, #b38a4e);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.chat-pane-new-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
background: none;
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 4px;
|
||||
color: var(--text-2, #999);
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition: color 0.15s, border-color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
.chat-pane-new-btn:hover {
|
||||
color: var(--accent, #b38a4e);
|
||||
border-color: var(--accent, #b38a4e);
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.1));
|
||||
}
|
||||
|
||||
/* Model selector in header */
|
||||
.chat-pane-model-select {
|
||||
background: var(--bg, #0e0e10);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 4px;
|
||||
color: var(--text-2, #999);
|
||||
font-size: 11px;
|
||||
font-family: inherit;
|
||||
padding: 4px 6px;
|
||||
cursor: pointer;
|
||||
max-width: 140px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.chat-pane-model-select:focus {
|
||||
border-color: var(--accent, #b38a4e);
|
||||
outline: none;
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
/* ── Messages Area ─────────────────────────── */
|
||||
|
||||
.chat-pane-messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
scroll-behavior: smooth;
|
||||
padding: 12px 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Message Bubbles ───────────────────────── */
|
||||
|
||||
.chat-msg {
|
||||
padding: 8px 16px;
|
||||
font-size: var(--msg-font, 14px);
|
||||
line-height: 1.65;
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
.chat-msg + .chat-msg {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* User messages — right-aligned bubble */
|
||||
.chat-msg--user {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.chat-msg--user .chat-msg__content {
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.15));
|
||||
color: var(--text, #eee);
|
||||
padding: 8px 14px;
|
||||
border-radius: 12px 12px 2px 12px;
|
||||
max-width: 85%;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Assistant messages — left-aligned */
|
||||
.chat-msg--assistant {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.chat-msg--assistant .chat-msg__content {
|
||||
max-width: 100%;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* ── Streaming indicator ───────────────────── */
|
||||
|
||||
.chat-msg--streaming .chat-msg__content::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 14px;
|
||||
background: var(--accent, #b38a4e);
|
||||
margin-left: 2px;
|
||||
vertical-align: text-bottom;
|
||||
animation: cp-cursor-blink 0.8s step-end infinite;
|
||||
}
|
||||
|
||||
@keyframes cp-cursor-blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* ── Typing dots ───────────────────────────── */
|
||||
|
||||
.chat-msg--typing {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
/* System/error messages */
|
||||
.chat-msg--system {
|
||||
padding: 6px 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.chat-msg--typing .typing-dots {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.chat-msg--typing .typing-dots span {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--text-3, #555);
|
||||
animation: cp-dot-bounce 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.chat-msg--typing .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
|
||||
.chat-msg--typing .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
|
||||
|
||||
@keyframes cp-dot-bounce {
|
||||
0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
|
||||
30% { transform: translateY(-4px); opacity: 1; }
|
||||
}
|
||||
|
||||
/* ── Markdown content ──────────────────────── */
|
||||
|
||||
.chat-msg__content p { margin: 0 0 0.5em; }
|
||||
.chat-msg__content p:last-child { margin-bottom: 0; }
|
||||
|
||||
.chat-msg__content pre {
|
||||
background: var(--bg-secondary, #151517);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 6px;
|
||||
padding: 10px 12px;
|
||||
overflow-x: auto;
|
||||
margin: 8px 0;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
}
|
||||
|
||||
.chat-msg__content code {
|
||||
background: var(--bg-secondary, #151517);
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.88em;
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
}
|
||||
|
||||
.chat-msg__content pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.chat-msg__content ul, .chat-msg__content ol {
|
||||
margin: 4px 0;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
.chat-msg__content blockquote {
|
||||
border-left: 3px solid var(--accent, #b38a4e);
|
||||
padding: 4px 12px;
|
||||
margin: 8px 0;
|
||||
color: var(--text-2, #999);
|
||||
}
|
||||
|
||||
.chat-msg__content a {
|
||||
color: var(--accent, #b38a4e);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.chat-msg__content a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.chat-msg__content table {
|
||||
border-collapse: collapse;
|
||||
margin: 8px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.chat-msg__content th,
|
||||
.chat-msg__content td {
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.chat-msg__content th {
|
||||
background: var(--bg-secondary, #151517);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ── Welcome / Empty State ─────────────────── */
|
||||
|
||||
.chat-welcome {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.chat-welcome__title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--text, #eee);
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
|
||||
.chat-welcome__hint {
|
||||
font-size: 13px;
|
||||
color: var(--text-3, #555);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ── Input Bar ─────────────────────────────── */
|
||||
|
||||
.chat-pane-input-bar {
|
||||
flex-shrink: 0;
|
||||
border-top: 1px solid var(--border, #2a2a2e);
|
||||
background: var(--bg-secondary, #151517);
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.chat-pane-input-wrap {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 6px;
|
||||
background: var(--bg, #0e0e10);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 8px;
|
||||
padding: 6px 8px;
|
||||
transition: border-color 0.15s;
|
||||
}
|
||||
|
||||
.chat-pane-input-wrap:focus-within {
|
||||
border-color: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
.chat-pane-input {
|
||||
flex: 1;
|
||||
min-height: 20px;
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
font-size: 13px;
|
||||
color: var(--text, #eee);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* CM6 editor inside chat-pane-input */
|
||||
.chat-pane-input .cm-editor {
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.chat-pane-input .cm-editor .cm-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chat-pane-input .cm-editor .cm-line {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.chat-pane-input .cm-editor.cm-focused {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Textarea fallback */
|
||||
.chat-pane-input textarea {
|
||||
width: 100%;
|
||||
min-height: 20px;
|
||||
max-height: 160px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text, #eee);
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
line-height: 1.5;
|
||||
resize: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ── Send Button ───────────────────────────── */
|
||||
|
||||
.chat-pane-send {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
color: var(--accent, #b38a4e);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.chat-pane-send:hover {
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.15));
|
||||
color: var(--accent-hover, #c9a05e);
|
||||
}
|
||||
|
||||
.chat-pane-send:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* ── Toolbar ───────────────────────────────── */
|
||||
|
||||
.chat-pane-toolbar {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.chat-pane-toolbar:empty {
|
||||
display: none;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/* ==========================================
|
||||
Editor Surface (v0.21.5)
|
||||
IDE-like layout: file tree | code + chat
|
||||
========================================== */
|
||||
|
||||
/* ── Header ──────────────────────────────── */
|
||||
|
||||
.editor-header {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 6px 12px; gap: 8px;
|
||||
font-size: 13px; color: var(--text-secondary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
min-height: 36px; box-sizing: border-box;
|
||||
}
|
||||
.editor-header-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||||
.editor-ws-name { font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.editor-branch { font-size: 12px; color: var(--text-tertiary); white-space: nowrap; }
|
||||
.editor-header-right { display: flex; align-items: center; gap: 4px; }
|
||||
.editor-hdr-btn {
|
||||
background: none; border: none; color: var(--text-secondary);
|
||||
cursor: pointer; padding: 4px; border-radius: 4px;
|
||||
display: flex; align-items: center;
|
||||
}
|
||||
.editor-hdr-btn:hover { background: var(--hover); color: var(--text-primary); }
|
||||
.editor-hdr-label { font-size: 12px; margin-left: 3px; }
|
||||
.editor-hdr-sep { width: 1px; height: 16px; background: var(--border); margin: 0 2px; }
|
||||
|
||||
/* Chat toggle */
|
||||
.editor-chat-toggle.active { color: var(--accent); }
|
||||
|
||||
/* Export dropdown */
|
||||
.editor-export-wrap { position: relative; }
|
||||
.editor-export-menu {
|
||||
display: none; position: absolute; right: 0; top: 100%;
|
||||
background: var(--bg-primary); border: 1px solid var(--border);
|
||||
border-radius: 6px; padding: 4px 0; z-index: 100;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.2); min-width: 160px;
|
||||
}
|
||||
.editor-export-menu.open { display: block; }
|
||||
.editor-export-item {
|
||||
display: block; width: 100%; padding: 6px 12px; font-size: 13px;
|
||||
background: none; border: none; text-align: left; cursor: pointer;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.editor-export-item:hover { background: var(--hover); }
|
||||
|
||||
/* ── File Tree (sidebar-content region) ──── */
|
||||
|
||||
.editor-file-tree {
|
||||
flex: 1; overflow-y: auto; overflow-x: hidden;
|
||||
font-size: 13px; user-select: none;
|
||||
display: flex; flex-direction: column;
|
||||
}
|
||||
.editor-tree-header {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 6px 8px; flex-shrink: 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.editor-tree-title { font-size: 11px; font-weight: 600; text-transform: uppercase; color: var(--text-tertiary); letter-spacing: 0.5px; }
|
||||
.editor-tree-add {
|
||||
background: none; border: none; color: var(--text-tertiary);
|
||||
cursor: pointer; padding: 2px; border-radius: 4px;
|
||||
display: flex; align-items: center;
|
||||
}
|
||||
.editor-tree-add:hover { background: var(--hover); color: var(--accent); }
|
||||
.editor-tree-content { flex: 1; overflow-y: auto; padding: 4px 0; }
|
||||
.editor-file-tree.drag-over { outline: 2px dashed var(--accent, #5865f2); outline-offset: -2px; background: rgba(88,101,242,0.05); }
|
||||
.editor-tree-row {
|
||||
display: flex; align-items: center; gap: 4px;
|
||||
padding: 3px 8px; cursor: pointer;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
border-radius: 4px; margin: 0 4px;
|
||||
}
|
||||
.editor-tree-row:hover { background: var(--hover); }
|
||||
.editor-tree-row.active { background: var(--active-bg, rgba(59,130,246,0.12)); color: var(--accent); }
|
||||
.editor-tree-arrow { width: 14px; text-align: center; font-size: 10px; color: var(--text-tertiary); flex-shrink: 0; }
|
||||
.editor-tree-arrow.expanded { /* already rotated via character */ }
|
||||
.editor-tree-icon { flex-shrink: 0; font-size: 14px; line-height: 1; }
|
||||
.editor-tree-name { overflow: hidden; text-overflow: ellipsis; }
|
||||
|
||||
/* Git status indicators (v0.21.6) */
|
||||
.editor-tree-row.git-modified .editor-tree-name { color: var(--warning, #e5a50a); }
|
||||
.editor-tree-row.git-added .editor-tree-name { color: var(--success, #22c55e); }
|
||||
.editor-tree-row.git-untracked .editor-tree-name { color: var(--text-tertiary); font-style: italic; }
|
||||
.editor-tree-row.git-deleted .editor-tree-name { color: var(--error, #ef4444); text-decoration: line-through; }
|
||||
.editor-tree-row.git-modified::after,
|
||||
.editor-tree-row.git-added::after,
|
||||
.editor-tree-row.git-untracked::after {
|
||||
font-size: 10px; margin-left: auto; padding-right: 4px; flex-shrink: 0;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
.editor-tree-row.git-modified::after { content: 'M'; color: var(--warning, #e5a50a); }
|
||||
.editor-tree-row.git-added::after { content: 'A'; color: var(--success, #22c55e); }
|
||||
.editor-tree-row.git-untracked::after { content: 'U'; }
|
||||
|
||||
.editor-tree-loading, .editor-tree-empty, .editor-tree-error {
|
||||
padding: 16px; text-align: center; color: var(--text-tertiary); font-size: 12px;
|
||||
}
|
||||
|
||||
/* ── Main Split Layout ───────────────────── */
|
||||
|
||||
.editor-main {
|
||||
display: flex; flex: 1; min-height: 0; overflow: hidden;
|
||||
}
|
||||
.editor-left-pane {
|
||||
display: flex; flex-direction: column; min-width: 200px; overflow: hidden;
|
||||
}
|
||||
.editor-right-pane {
|
||||
display: flex; flex-direction: column; min-width: 200px; overflow: hidden;
|
||||
border-left: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Resize handle */
|
||||
.editor-split-handle {
|
||||
width: 5px; cursor: col-resize; flex-shrink: 0;
|
||||
background: transparent; position: relative; z-index: 5;
|
||||
}
|
||||
.editor-split-handle:hover,
|
||||
.editor-split-handle:active {
|
||||
background: var(--accent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* ── Tab Bar ─────────────────────────────── */
|
||||
|
||||
.editor-tab-bar {
|
||||
display: flex; overflow-x: auto; overflow-y: hidden;
|
||||
border-bottom: 1px solid var(--border);
|
||||
min-height: 32px; flex-shrink: 0;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.editor-tab-bar::-webkit-scrollbar { height: 0; }
|
||||
|
||||
.editor-tab {
|
||||
display: flex; align-items: center; gap: 4px;
|
||||
padding: 4px 10px; font-size: 12px;
|
||||
cursor: pointer; white-space: nowrap;
|
||||
border-right: 1px solid var(--border);
|
||||
color: var(--text-secondary);
|
||||
flex-shrink: 0; max-width: 180px;
|
||||
position: relative;
|
||||
}
|
||||
.editor-tab:hover { background: var(--hover); }
|
||||
.editor-tab.active {
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
border-bottom: 2px solid var(--accent);
|
||||
}
|
||||
.editor-tab.modified .editor-tab-name { font-style: italic; }
|
||||
.editor-tab-icon { font-size: 13px; flex-shrink: 0; }
|
||||
.editor-tab-name { overflow: hidden; text-overflow: ellipsis; }
|
||||
.editor-tab-modified { color: var(--accent); font-size: 10px; margin-left: 2px; }
|
||||
.editor-tab-close {
|
||||
background: none; border: none; color: var(--text-tertiary);
|
||||
cursor: pointer; font-size: 11px; padding: 0 2px;
|
||||
border-radius: 3px; opacity: 0; transition: opacity 0.1s;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.editor-tab:hover .editor-tab-close { opacity: 1; }
|
||||
.editor-tab-close:hover { background: var(--hover); color: var(--text-primary); }
|
||||
|
||||
/* ── Code Editor Area ────────────────────── */
|
||||
|
||||
.editor-code-area {
|
||||
flex: 1; min-height: 0; position: relative; overflow: hidden;
|
||||
}
|
||||
.editor-cm-wrap {
|
||||
position: absolute; inset: 0; overflow: hidden;
|
||||
}
|
||||
.editor-cm-wrap .cm-editor { height: 100%; }
|
||||
.editor-cm-wrap .cm-scroller { overflow: auto; }
|
||||
|
||||
/* Textarea fallback */
|
||||
.editor-textarea-fallback {
|
||||
width: 100%; height: 100%; resize: none; border: none; outline: none;
|
||||
background: var(--bg-primary); color: var(--text-primary);
|
||||
font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
|
||||
font-size: 13px; line-height: 1.5;
|
||||
padding: 8px 12px; box-sizing: border-box;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
/* Welcome screen */
|
||||
.editor-welcome {
|
||||
position: absolute; inset: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.editor-welcome-inner { text-align: center; color: var(--text-tertiary); }
|
||||
.editor-welcome-inner p { margin: 8px 0; font-size: 14px; }
|
||||
.editor-welcome-hint { font-size: 12px; opacity: 0.6; }
|
||||
.editor-welcome-hint kbd {
|
||||
background: var(--hover); border: 1px solid var(--border);
|
||||
border-radius: 3px; padding: 1px 5px; font-size: 11px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* ── Chat Panel (right pane) ─────────────── */
|
||||
|
||||
.editor-chat-header {
|
||||
padding: 6px 12px; font-size: 12px; font-weight: 600;
|
||||
color: var(--text-secondary); border-bottom: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.editor-chat-messages {
|
||||
flex: 1; overflow-y: auto; min-height: 0;
|
||||
}
|
||||
/* Inherit chat message styles when embedded */
|
||||
.editor-chat-messages .messages { height: auto; overflow: visible; }
|
||||
.editor-chat-input { flex-shrink: 0; max-height: 140px; overflow: hidden; }
|
||||
/* Inherit input-area styles — constrain for narrow pane */
|
||||
.editor-chat-input .input-area { border-top: 1px solid var(--border); padding: 0 8px 8px; }
|
||||
.editor-chat-input .input-wrap { max-width: none; }
|
||||
.editor-chat-input .input-wrap textarea,
|
||||
.editor-chat-input #messageInputWrap .cm-editor { max-height: 80px; padding: 8px; font-size: 13px; }
|
||||
.editor-chat-input .input-meta { min-height: 0; padding: 2px 4px 0; }
|
||||
.editor-chat-input .input-toolbar { gap: 2px; }
|
||||
.editor-chat-input .input-toolbar button { padding: 4px; }
|
||||
|
||||
/* ── Status Bar (footer) ─────────────────── */
|
||||
|
||||
.editor-status-bar {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 2px 12px; font-size: 11px;
|
||||
color: var(--text-tertiary);
|
||||
border-top: 1px solid var(--border);
|
||||
min-height: 22px; flex-shrink: 0;
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
.editor-status-sep { opacity: 0.3; }
|
||||
.editor-status-right { margin-left: auto; display: flex; gap: 8px; }
|
||||
.editor-status-branch { font-size: 11px; }
|
||||
.editor-status-file { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.editor-status-save { font-size: 11px; }
|
||||
.editor-status-save.unsaved { color: var(--warning, #e5a50a); }
|
||||
.editor-status-words { font-size: 11px; }
|
||||
|
||||
/* ── Context Menu ────────────────────────── */
|
||||
|
||||
.editor-ctx-menu {
|
||||
position: fixed; z-index: 1000;
|
||||
background: var(--bg-primary); border: 1px solid var(--border);
|
||||
border-radius: 6px; padding: 4px 0;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.2);
|
||||
min-width: 120px; font-size: 13px;
|
||||
}
|
||||
.editor-ctx-item {
|
||||
padding: 6px 12px; cursor: pointer;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.editor-ctx-item:hover { background: var(--hover); }
|
||||
|
||||
/* ── Quick Open Overlay ──────────────────── */
|
||||
|
||||
.editor-quick-open {
|
||||
position: fixed; inset: 0; z-index: 2000;
|
||||
background: rgba(0,0,0,0.4);
|
||||
display: flex; align-items: flex-start; justify-content: center;
|
||||
padding-top: 15vh;
|
||||
}
|
||||
.editor-qo-dialog {
|
||||
background: var(--bg-primary); border: 1px solid var(--border);
|
||||
border-radius: 8px; width: 460px; max-width: 90vw;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.3);
|
||||
overflow: hidden;
|
||||
}
|
||||
.editor-qo-input {
|
||||
width: 100%; padding: 10px 14px; font-size: 14px;
|
||||
border: none; outline: none; box-sizing: border-box;
|
||||
background: var(--bg-primary); color: var(--text-primary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.editor-qo-results { max-height: 300px; overflow-y: auto; }
|
||||
.editor-qo-row {
|
||||
padding: 6px 14px; cursor: pointer; font-size: 13px;
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.editor-qo-row:hover { background: var(--hover); }
|
||||
.editor-qo-icon { font-size: 14px; flex-shrink: 0; }
|
||||
|
||||
/* ── Mobile: single pane ─────────────────── */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.editor-main { flex-direction: column; }
|
||||
.editor-left-pane { flex: 1 !important; min-width: 0; }
|
||||
.editor-right-pane { min-width: 0; border-left: none; border-top: 1px solid var(--border); max-height: 40vh; }
|
||||
.editor-split-handle { display: none; }
|
||||
}
|
||||
535
src/css/editor-surface.css
Normal file
535
src/css/editor-surface.css
Normal file
@@ -0,0 +1,535 @@
|
||||
/* ==========================================
|
||||
Chat Switchboard — Editor Surface (v0.25.0)
|
||||
==========================================
|
||||
Replaces editor-mode.css for the pane-based editor.
|
||||
Covers: topbar, bootstrap, and component-specific
|
||||
overrides within the editor context.
|
||||
========================================== */
|
||||
|
||||
/* ── Surface Shell ─────────────────────────── */
|
||||
|
||||
.surface-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: var(--bg, #0e0e10);
|
||||
}
|
||||
|
||||
/* ── Topbar ────────────────────────────────── */
|
||||
|
||||
.editor-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
height: 40px;
|
||||
flex-shrink: 0;
|
||||
background: var(--bg-secondary, #151517);
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
font-size: 13px;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.editor-topbar-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--text-3, #777);
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
.editor-topbar-back:hover {
|
||||
color: var(--text, #eee);
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.editor-topbar-sep {
|
||||
width: 1px;
|
||||
height: 18px;
|
||||
background: var(--border, #2a2a2e);
|
||||
}
|
||||
|
||||
.editor-topbar-name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
/* ── Workspace Selector ────────────────────── */
|
||||
|
||||
.editor-ws-selector {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editor-ws-selector-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
color: var(--text, #eee);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s, background 0.15s;
|
||||
}
|
||||
|
||||
.editor-ws-selector-btn:hover {
|
||||
border-color: var(--border, #2a2a2e);
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.editor-ws-dropdown {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
margin-top: 4px;
|
||||
background: var(--bg-secondary, #1a1a1e);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 8px;
|
||||
min-width: 220px;
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.editor-ws-dropdown.open { display: block; }
|
||||
|
||||
.editor-ws-list {
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.editor-ws-dropdown-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text, #eee);
|
||||
font-size: 12px;
|
||||
font-family: inherit;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: background 0.1s;
|
||||
}
|
||||
|
||||
.editor-ws-dropdown-item:hover {
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.editor-ws-dropdown-item.active {
|
||||
color: var(--accent, #b38a4e);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.editor-ws-dropdown-divider {
|
||||
height: 1px;
|
||||
background: var(--border, #2a2a2e);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.editor-ws-new {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
.editor-topbar-branch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: var(--purple-dim, rgba(160, 120, 255, 0.1));
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.editor-topbar-branch-text {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--purple, #a078ff);
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
}
|
||||
|
||||
/* ── Body ──────────────────────────────────── */
|
||||
|
||||
.editor-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ── Bootstrap (no workspace) ──────────────── */
|
||||
|
||||
.editor-bootstrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.editor-bootstrap-card {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
background: var(--bg-secondary, #151517);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 12px;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
.editor-bootstrap-input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background: var(--bg, #0e0e10);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 6px;
|
||||
color: var(--text, #eee);
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
margin-bottom: 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.editor-bootstrap-input:focus {
|
||||
border-color: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
.editor-bootstrap-btn {
|
||||
width: 100%;
|
||||
padding: 10px 16px;
|
||||
background: var(--accent, #b38a4e);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
.editor-bootstrap-btn:hover { opacity: 0.9; }
|
||||
.editor-bootstrap-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
/* Workspace list in bootstrap */
|
||||
.editor-bootstrap-ws-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
background: var(--bg, #0e0e10);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 6px;
|
||||
color: var(--text, #eee);
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s, background 0.15s;
|
||||
margin-bottom: 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.editor-bootstrap-ws-item:hover {
|
||||
border-color: var(--accent, #b38a4e);
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.editor-bootstrap-ws-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.editor-bootstrap-ws-date {
|
||||
font-size: 11px;
|
||||
color: var(--text-3, #777);
|
||||
}
|
||||
|
||||
/* User menu in editor topbar — uses user-menu.css base styles.
|
||||
No overrides needed: user-menu.css defaults to drop-down (topbar) mode.
|
||||
Sidebar context flipped via .sidebar parent selector in user-menu.css. */
|
||||
|
||||
/* ── FileTree overrides (in editor context) ── */
|
||||
|
||||
.surface-editor .file-tree {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid var(--border, #2a2a2e);
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-title {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--text-2, #999);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.4px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-items {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 3px 8px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: var(--text-2, #999);
|
||||
transition: background 0.1s;
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-row:hover {
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-row.active {
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.15));
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-arrow {
|
||||
width: 12px;
|
||||
font-size: 10px;
|
||||
color: var(--text-3, #555);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-icon {
|
||||
font-size: 13px;
|
||||
width: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.surface-editor .file-tree-name {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Git status indicators */
|
||||
.surface-editor .file-tree-row.git-modified .file-tree-name { color: var(--warning, #e5a842); }
|
||||
.surface-editor .file-tree-row.git-added .file-tree-name { color: var(--success, #4caf50); }
|
||||
.surface-editor .file-tree-row.git-untracked .file-tree-name { color: var(--text-3, #555); font-style: italic; }
|
||||
.surface-editor .file-tree-row.git-deleted .file-tree-name { color: var(--danger, #f44336); text-decoration: line-through; }
|
||||
|
||||
/* Context menu */
|
||||
.file-tree-ctx-menu {
|
||||
position: fixed;
|
||||
background: var(--bg-secondary, #1a1a1e);
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
min-width: 120px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.file-tree-ctx-item {
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text, #eee);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-tree-ctx-item:hover {
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
/* ── CodeEditor overrides ──────────────────── */
|
||||
|
||||
.surface-editor .code-editor {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
background: var(--bg-secondary, #151517);
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
height: 32px;
|
||||
overflow-x: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-tabs::-webkit-scrollbar { height: 0; }
|
||||
|
||||
.surface-editor .code-editor-tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 0 12px;
|
||||
height: 100%;
|
||||
font-size: 12px;
|
||||
color: var(--text-3, #777);
|
||||
cursor: pointer;
|
||||
border-right: 1px solid var(--border, #2a2a2e);
|
||||
transition: background 0.1s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-tab:hover { background: var(--bg-tertiary, #1e1e22); }
|
||||
.surface-editor .code-editor-tab.active { color: var(--text, #eee); background: var(--bg, #0e0e10); }
|
||||
.surface-editor .code-editor-tab.modified .code-editor-tab-modified { color: var(--warning, #e5a842); }
|
||||
|
||||
.surface-editor .code-editor-tab-icon { font-size: 12px; }
|
||||
.surface-editor .code-editor-tab-modified { font-size: 10px; color: var(--text-3); }
|
||||
|
||||
.surface-editor .code-editor-tab-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-3, #555);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
padding: 0 2px;
|
||||
margin-left: 4px;
|
||||
border-radius: 2px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-tab-close:hover {
|
||||
background: var(--danger-dim, rgba(244, 67, 54, 0.15));
|
||||
color: var(--danger, #f44336);
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-welcome {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-cm-wrap {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-cm-wrap .cm-editor {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-statusbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 0 12px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
background: var(--bg-secondary, #151517);
|
||||
border-top: 1px solid var(--border, #2a2a2e);
|
||||
font-size: 11px;
|
||||
color: var(--text-3, #777);
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
}
|
||||
|
||||
.surface-editor .code-editor-textarea-fallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--bg, #0e0e10);
|
||||
color: var(--text, #eee);
|
||||
border: none;
|
||||
padding: 12px;
|
||||
font-family: var(--mono, 'SF Mono', monospace);
|
||||
font-size: 13px;
|
||||
resize: none;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ── Tabbed assist pane overrides ──────────── */
|
||||
|
||||
.surface-editor .pane-tabbed {
|
||||
border-left: 1px solid var(--border, #2a2a2e);
|
||||
}
|
||||
|
||||
/* ChatPane in editor tabbed pane */
|
||||
.surface-editor .chat-pane {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
/* Notes in editor pane */
|
||||
.surface-editor .note-editor {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.surface-editor .note-editor-list-view {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.surface-editor .notes-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Compact notes toolbar for narrow pane */
|
||||
.surface-editor .notes-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
padding: 6px 8px;
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
}
|
||||
|
||||
.surface-editor .notes-toolbar .btn-small {
|
||||
font-size: 11px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.surface-editor .notes-search-row {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.surface-editor .notes-filter-row {
|
||||
padding: 2px 8px 4px;
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.surface-editor .notes-filter-select {
|
||||
font-size: 11px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
167
src/css/pane-container.css
Normal file
167
src/css/pane-container.css
Normal file
@@ -0,0 +1,167 @@
|
||||
/* ==========================================
|
||||
Chat Switchboard — Pane Container
|
||||
==========================================
|
||||
v0.25.0: Styles for the multi-pane layout system.
|
||||
Covers: pane container, leaf panes, tabbed panes,
|
||||
drag handles, and tab bars.
|
||||
========================================== */
|
||||
|
||||
/* ── Container ─────────────────────────────── */
|
||||
|
||||
.pane-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ── Split ─────────────────────────────────── */
|
||||
|
||||
.pane-split--horizontal {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pane-split--vertical {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ── Leaf Pane ─────────────────────────────── */
|
||||
|
||||
.pane-leaf {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pane-minimized {
|
||||
max-width: 0 !important;
|
||||
max-height: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* ── Tabbed Pane ───────────────────────────── */
|
||||
|
||||
.pane-tabbed {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Tab Bar */
|
||||
.pane-tab-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
background: var(--bg-secondary, #1a1a1e);
|
||||
border-bottom: 1px solid var(--border, #2a2a2e);
|
||||
flex-shrink: 0;
|
||||
height: 32px;
|
||||
padding: 0 4px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.pane-tab-bar::-webkit-scrollbar { height: 0; }
|
||||
|
||||
.pane-tab-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-3, #777);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: color 0.15s, border-color 0.15s;
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.pane-tab-btn:hover {
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
.pane-tab-btn--active {
|
||||
color: var(--accent, #b38a4e);
|
||||
border-bottom-color: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
/* Tab Content */
|
||||
.pane-tab-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pane-tab-panel {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* When panel is hidden (inactive tab), override absolute positioning */
|
||||
.pane-tab-panel[style*="display: none"] {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* ── Drag Handle ───────────────────────────── */
|
||||
|
||||
.pane-handle {
|
||||
flex-shrink: 0;
|
||||
background: var(--border, #2a2a2e);
|
||||
transition: background 0.15s;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.pane-handle--horizontal {
|
||||
width: 4px;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.pane-handle--vertical {
|
||||
height: 4px;
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
.pane-handle:hover,
|
||||
.pane-handle--active {
|
||||
background: var(--accent, #b38a4e);
|
||||
}
|
||||
|
||||
/* ── Responsive ────────────────────────────── */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
/* On mobile, splits collapse to vertical stack */
|
||||
.pane-split--horizontal {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.pane-handle--horizontal {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
/* Hide non-primary panes on mobile */
|
||||
.pane-split--horizontal > .pane:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
.pane-split--horizontal > .pane-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
41
src/css/tool-grants.css
Normal file
41
src/css/tool-grants.css
Normal file
@@ -0,0 +1,41 @@
|
||||
/* v0.25.0: Tool grants section in persona form */
|
||||
.tool-grants-list {
|
||||
border: 1px solid var(--border, #2a2a2e);
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
background: var(--bg, #0e0e10);
|
||||
}
|
||||
|
||||
.tool-grants-category {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--text-3, #777);
|
||||
padding: 6px 0 2px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.tool-grants-category:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.tool-grants-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 3px 4px;
|
||||
font-size: 12px;
|
||||
color: var(--text, #eee);
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tool-grants-item:hover {
|
||||
background: var(--bg-tertiary, #1e1e22);
|
||||
}
|
||||
|
||||
.tool-grants-item input[type="checkbox"] {
|
||||
margin: 0;
|
||||
}
|
||||
162
src/css/user-menu.css
Normal file
162
src/css/user-menu.css
Normal file
@@ -0,0 +1,162 @@
|
||||
/* ==========================================
|
||||
Chat Switchboard — UserMenu Component CSS
|
||||
==========================================
|
||||
v0.25.0-cs11.1: Self-contained styles for the UserMenu
|
||||
component. Works in two contexts:
|
||||
1. Sidebar (flyout pops UP) — default in .sidebar
|
||||
2. Topbar (flyout drops DOWN) — default standalone
|
||||
========================================== */
|
||||
|
||||
/* ── Wrapper ───────────────────────────────── */
|
||||
|
||||
.user-menu-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ── Trigger Button ────────────────────────── */
|
||||
|
||||
.user-menu-wrap .user-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
border-radius: var(--radius, 6px);
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text, #eee);
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.user-menu-wrap .user-btn:hover {
|
||||
background: var(--bg-hover, rgba(255,255,255,0.06));
|
||||
}
|
||||
|
||||
/* ── Avatar ────────────────────────────────── */
|
||||
|
||||
.user-menu-wrap .user-avatar {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent-dim, rgba(179, 138, 78, 0.2));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--accent, #b38a4e);
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-menu-wrap .user-avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-menu-wrap .sb-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ── Flyout (default: drops DOWN for topbar) ─ */
|
||||
|
||||
.user-menu-wrap .user-flyout {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 4px;
|
||||
background: var(--bg-raised, #1a1a1e);
|
||||
border: 1px solid var(--border-light, #333);
|
||||
border-radius: var(--radius-lg, 8px);
|
||||
padding: 4px;
|
||||
min-width: 170px;
|
||||
z-index: 200;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.user-menu-wrap .user-flyout.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ── Flyout Items ──────────────────────────── */
|
||||
|
||||
.user-menu-wrap .flyout-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 12px;
|
||||
border-radius: var(--radius, 6px);
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-2, #999);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-family: inherit;
|
||||
width: 100%;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.user-menu-wrap .flyout-item:hover {
|
||||
background: var(--bg-hover, rgba(255,255,255,0.06));
|
||||
color: var(--text, #eee);
|
||||
}
|
||||
|
||||
.user-menu-wrap .flyout-item svg {
|
||||
flex-shrink: 0;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.user-menu-wrap .flyout-danger {
|
||||
color: var(--danger, #f44336);
|
||||
}
|
||||
|
||||
.user-menu-wrap .flyout-danger:hover {
|
||||
background: var(--danger-dim, rgba(244, 67, 54, 0.1));
|
||||
color: var(--danger, #f44336);
|
||||
}
|
||||
|
||||
.user-menu-wrap .flyout-divider {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: var(--border, #2a2a2e);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* ── Sidebar Context (flyout pops UP) ──────── */
|
||||
/* When user-menu is inside .sidebar, flip the flyout direction */
|
||||
|
||||
.sidebar .user-menu-wrap .user-flyout {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: 4px;
|
||||
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Sidebar collapsed: hide label, center avatar */
|
||||
.sidebar.collapsed .user-menu-wrap .user-btn {
|
||||
justify-content: center;
|
||||
padding: 6px 0;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .user-menu-wrap .sb-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar.collapsed .user-menu-wrap .user-flyout {
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
Reference in New Issue
Block a user