fix: restore chat layout and file tree
This commit is contained in:
parent
a6da8280ff
commit
bfa7b540cb
1093
static/src/App.vue
Normal file
1093
static/src/App.vue
Normal file
File diff suppressed because it is too large
Load Diff
2139
static/src/app.ts
Normal file
2139
static/src/app.ts
Normal file
File diff suppressed because it is too large
Load Diff
203
static/src/stores/file.ts
Normal file
203
static/src/stores/file.ts
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
|
interface FileNode {
|
||||||
|
type: 'folder' | 'file';
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
annotation?: string;
|
||||||
|
children?: FileNode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TodoTask {
|
||||||
|
index: number;
|
||||||
|
title: string;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TodoList {
|
||||||
|
instruction?: string;
|
||||||
|
tasks?: TodoTask[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ContextMenuState {
|
||||||
|
visible: boolean;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
node: FileNode | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FileState {
|
||||||
|
fileTree: FileNode[];
|
||||||
|
expandedFolders: Record<string, boolean>;
|
||||||
|
todoList: TodoList | null;
|
||||||
|
contextMenu: ContextMenuState;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildNodes(treeMap: Record<string, any> | undefined): FileNode[] {
|
||||||
|
if (!treeMap) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const entries = Object.keys(treeMap).map(name => {
|
||||||
|
const node = treeMap[name] || {};
|
||||||
|
if (node.type === 'folder') {
|
||||||
|
return {
|
||||||
|
type: 'folder' as const,
|
||||||
|
name,
|
||||||
|
path: node.path || name,
|
||||||
|
children: buildNodes(node.children)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'file' as const,
|
||||||
|
name,
|
||||||
|
path: node.path || name,
|
||||||
|
annotation: node.annotation || ''
|
||||||
|
};
|
||||||
|
});
|
||||||
|
entries.sort((a, b) => {
|
||||||
|
if (a.type !== b.type) {
|
||||||
|
return a.type === 'folder' ? -1 : 1;
|
||||||
|
}
|
||||||
|
return a.name.localeCompare(b.name, 'zh-CN');
|
||||||
|
});
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFileStore = defineStore('file', {
|
||||||
|
state: (): FileState => ({
|
||||||
|
fileTree: [],
|
||||||
|
expandedFolders: {},
|
||||||
|
todoList: null,
|
||||||
|
contextMenu: {
|
||||||
|
visible: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
node: null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async fetchFileTree() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/files');
|
||||||
|
const data = await response.json();
|
||||||
|
console.log('[FileTree] fetch result', data);
|
||||||
|
this.setFileTreeFromResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取文件树失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setFileTreeFromResponse(payload: any) {
|
||||||
|
if (!payload) {
|
||||||
|
console.warn('[FileTree] 空 payload');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const structure = payload.structure || payload;
|
||||||
|
if (!structure || !structure.tree) {
|
||||||
|
console.warn('[FileTree] 缺少 structure.tree', structure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const nodes = buildNodes(structure.tree);
|
||||||
|
const expanded = { ...this.expandedFolders };
|
||||||
|
const validFolderPaths = new Set<string>();
|
||||||
|
|
||||||
|
const ensureExpansion = (list: FileNode[]) => {
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.type === 'folder') {
|
||||||
|
validFolderPaths.add(item.path);
|
||||||
|
if (expanded[item.path] === undefined) {
|
||||||
|
expanded[item.path] = false;
|
||||||
|
}
|
||||||
|
ensureExpansion(item.children || []);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ensureExpansion(nodes);
|
||||||
|
Object.keys(expanded).forEach(path => {
|
||||||
|
if (!validFolderPaths.has(path)) {
|
||||||
|
delete expanded[path];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.expandedFolders = expanded;
|
||||||
|
this.fileTree = nodes;
|
||||||
|
},
|
||||||
|
toggleFolder(path: string) {
|
||||||
|
if (!path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const current = !!this.expandedFolders[path];
|
||||||
|
this.expandedFolders = {
|
||||||
|
...this.expandedFolders,
|
||||||
|
[path]: !current
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async fetchTodoList() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/todo-list');
|
||||||
|
const data = await response.json();
|
||||||
|
if (data && data.success) {
|
||||||
|
this.todoList = data.data || null;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取待办列表失败:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTodoList(payload: TodoList | null) {
|
||||||
|
this.todoList = payload;
|
||||||
|
},
|
||||||
|
showContextMenu(payload: { node: FileNode; event: MouseEvent }) {
|
||||||
|
if (!payload || !payload.node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { node, event } = payload;
|
||||||
|
if (!node.path && node.path !== '') {
|
||||||
|
this.hideContextMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node.type !== 'file' && node.type !== 'folder') {
|
||||||
|
this.hideContextMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event && typeof event.preventDefault === 'function') {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
if (event && typeof event.stopPropagation === 'function') {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuWidth = 200;
|
||||||
|
const menuHeight = 50;
|
||||||
|
const viewportWidth = window.innerWidth;
|
||||||
|
const viewportHeight = window.innerHeight;
|
||||||
|
let x = (event && event.clientX) || 0;
|
||||||
|
let y = (event && event.clientY) || 0;
|
||||||
|
|
||||||
|
if (x + menuWidth > viewportWidth) {
|
||||||
|
x = viewportWidth - menuWidth - 8;
|
||||||
|
}
|
||||||
|
if (y + menuHeight > viewportHeight) {
|
||||||
|
y = viewportHeight - menuHeight - 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contextMenu = {
|
||||||
|
visible: true,
|
||||||
|
x: Math.max(8, x),
|
||||||
|
y: Math.max(8, y),
|
||||||
|
node
|
||||||
|
};
|
||||||
|
},
|
||||||
|
hideContextMenu() {
|
||||||
|
if (!this.contextMenu.visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.contextMenu = {
|
||||||
|
visible: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
node: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
369
static/src/styles/components/chat/_chat-area.scss
Normal file
369
static/src/styles/components/chat/_chat-area.scss
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
/* 聊天容器整体布局,保证聊天区可见并支持上下滚动 */
|
||||||
|
.chat-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 核心聊天区样式,确保对话内容在主面板中可见 */
|
||||||
|
.messages-area {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 24px;
|
||||||
|
padding-bottom: calc(220px + var(--app-bottom-inset, 0px));
|
||||||
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-area::-webkit-scrollbar,
|
||||||
|
.sidebar::-webkit-scrollbar,
|
||||||
|
.conversation-list::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-area::-webkit-scrollbar-track,
|
||||||
|
.sidebar::-webkit-scrollbar-track,
|
||||||
|
.conversation-list::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-area::-webkit-scrollbar-thumb,
|
||||||
|
.sidebar::-webkit-scrollbar-thumb,
|
||||||
|
.conversation-list::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(121, 109, 94, 0.4);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-toggle {
|
||||||
|
position: absolute;
|
||||||
|
right: 28px;
|
||||||
|
bottom: 200px;
|
||||||
|
z-index: 25;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-btn {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid var(--claude-border);
|
||||||
|
background: rgba(255, 255, 255, 0.92);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: 0 6px 16px rgba(61, 57, 41, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 9px 20px rgba(61, 57, 41, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-toggle.locked .scroll-lock-btn {
|
||||||
|
border-color: rgba(218, 119, 86, 0.32);
|
||||||
|
box-shadow: 0 0 10px rgba(218, 119, 86, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-btn svg {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
stroke: var(--claude-text);
|
||||||
|
stroke-width: 1.8;
|
||||||
|
fill: none;
|
||||||
|
transition: stroke 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-lock-toggle.locked .scroll-lock-btn svg {
|
||||||
|
stroke: var(--claude-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-block {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-message .message-header,
|
||||||
|
.assistant-message .message-header {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--claude-text);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-message .message-text,
|
||||||
|
.assistant-message .message-text {
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-radius: 18px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.6;
|
||||||
|
box-shadow: 0 12px 28px rgba(61, 57, 41, 0.08);
|
||||||
|
color: var(--claude-text);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-message .message-text {
|
||||||
|
background: rgba(255, 255, 255, 0.88);
|
||||||
|
}
|
||||||
|
|
||||||
|
.assistant-message .message-text {
|
||||||
|
background: rgba(218, 119, 86, 0.12);
|
||||||
|
border-left: 4px solid var(--claude-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thinking-content {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--claude-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-block {
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--claude-border);
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
box-shadow: 0 12px 28px rgba(61, 57, 41, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-header {
|
||||||
|
padding: 14px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
user-select: none;
|
||||||
|
background: rgba(255, 255, 255, 0.72);
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-header:hover {
|
||||||
|
background: rgba(218, 119, 86, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
color: var(--claude-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow::before {
|
||||||
|
content: '›';
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-block.expanded .arrow {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.captured-status {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--claude-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-content {
|
||||||
|
max-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-block.expanded .collapsible-content {
|
||||||
|
max-height: 600px;
|
||||||
|
overflow-y: auto;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-inner {
|
||||||
|
padding: 20px 20px 20px 56px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--claude-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item {
|
||||||
|
animation: slideInFade 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item.streaming-content,
|
||||||
|
.action-item.immediate-show {
|
||||||
|
animation: quickFadeIn 0.2s ease-out both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item.completed-tool {
|
||||||
|
animation: slideInFade 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
|
||||||
|
animation-delay: 100ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInFade {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes quickFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(5px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-output {
|
||||||
|
margin: 16px 0;
|
||||||
|
color: var(--claude-text);
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-output .text-content {
|
||||||
|
padding: 0 20px 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-action {
|
||||||
|
margin: 12px 0;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(59, 130, 246, 0.08));
|
||||||
|
border-left: 4px solid rgba(79, 70, 229, 0.6);
|
||||||
|
color: var(--claude-text);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-action-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.append-block,
|
||||||
|
.append-placeholder {
|
||||||
|
margin: 12px 0;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.82);
|
||||||
|
border-left: 4px solid rgba(218, 119, 86, 0.32);
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(218, 119, 86, 0.05);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--claude-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.append-block.append-error,
|
||||||
|
.append-placeholder.append-error {
|
||||||
|
background: rgba(255, 244, 242, 0.85);
|
||||||
|
border-left-color: rgba(216, 90, 66, 0.38);
|
||||||
|
}
|
||||||
|
|
||||||
|
.append-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-wrapper {
|
||||||
|
border: 2px solid rgba(118, 103, 84, 0.25);
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 16px 0;
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
min-height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-header {
|
||||||
|
background: rgba(218, 119, 86, 0.08);
|
||||||
|
padding: 10px 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid rgba(118, 103, 84, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-language {
|
||||||
|
color: var(--claude-text-secondary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-code-btn {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--claude-text-secondary);
|
||||||
|
border: 1px solid rgba(121, 109, 94, 0.35);
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-code-btn:hover {
|
||||||
|
background: rgba(218, 119, 86, 0.12);
|
||||||
|
color: var(--claude-accent-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-code-btn.copied {
|
||||||
|
background: var(--claude-success);
|
||||||
|
border-color: var(--claude-success);
|
||||||
|
color: #f6fff8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-wrapper pre {
|
||||||
|
background: #ffffff !important;
|
||||||
|
padding: 16px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-wrapper pre code {
|
||||||
|
background: transparent !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.streaming-text {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-blink {
|
||||||
|
animation: blink 1s steps(1) infinite;
|
||||||
|
color: var(--claude-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
15
static/src/styles/layout/_app-shell.scss
Normal file
15
static/src/styles/layout/_app-shell.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* 主体容器,让三栏布局占满视口 */
|
||||||
|
.main-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
min-height: var(--app-viewport, 100vh);
|
||||||
|
background: var(--claude-bg);
|
||||||
|
color: var(--claude-text);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
min-height: var(--app-viewport, 100vh);
|
||||||
|
background: var(--claude-bg);
|
||||||
|
}
|
||||||
3495
static/style.css
3495
static/style.css
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user