fix: dashboard readability + editable info panel + drag&drop visual feedback

This commit is contained in:
A0 Orchestrator
2026-07-03 18:05:56 +02:00
parent aae93fe36b
commit 061f862960
3 changed files with 249 additions and 127 deletions
+60 -13
View File
@@ -8,7 +8,7 @@ import { ShareDialog } from '../components/ShareDialog';
import TreeView from '../components/TreeView'; import TreeView from '../components/TreeView';
import type { TreeNode } from '../types/ui.types'; import type { TreeNode } from '../types/ui.types';
import { import {
getProjects, deleteProject, getProjects, deleteProject, updateProject,
getProjectFolders, createProjectFolder, renameProjectFolder, deleteProjectFolder, getProjectFolders, createProjectFolder, renameProjectFolder, deleteProjectFolder,
moveProjectToFolder, getProjectShares, moveProjectToFolder, getProjectShares,
type Project, type ProjectFolder, type ProjectShare, type Project, type ProjectFolder, type ProjectShare,
@@ -42,6 +42,10 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
const [showCreateFolder, setShowCreateFolder] = useState(false); const [showCreateFolder, setShowCreateFolder] = useState(false);
const [newFolderName, setNewFolderName] = useState(''); const [newFolderName, setNewFolderName] = useState('');
const [newFolderParent, setNewFolderParent] = useState<string | null>(null); const [newFolderParent, setNewFolderParent] = useState<string | null>(null);
const [editingProjectName, setEditingProjectName] = useState('');
const [editingProjectDesc, setEditingProjectDesc] = useState('');
const [savingProject, setSavingProject] = useState(false);
const [dragOverFolderId, setDragOverFolderId] = useState<string | null>(null);
const fetchAll = useCallback(async () => { const fetchAll = useCallback(async () => {
if (!token) return; if (!token) return;
@@ -91,6 +95,13 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
[allProjects, selectedProjectId], [allProjects, selectedProjectId],
); );
useEffect(() => {
if (selectedProject) {
setEditingProjectName(selectedProject.name);
setEditingProjectDesc(selectedProject.description ?? '');
}
}, [selectedProject]);
const treeNodes = useMemo((): TreeNode[] => { const treeNodes = useMemo((): TreeNode[] => {
const rootProjectsCount = allProjects.filter(p => p.folder_id === null).length; const rootProjectsCount = allProjects.filter(p => p.folder_id === null).length;
const root: TreeNode = { const root: TreeNode = {
@@ -213,21 +224,40 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
setSelectedProjectId(projectId); setSelectedProjectId(projectId);
}; };
const handleSaveProject = async () => {
if (!selectedProject || !token) return;
if (!editingProjectName.trim()) return;
setSavingProject(true);
try {
await updateProject(token, selectedProject.id, {
name: editingProjectName.trim(),
description: editingProjectDesc.trim() || null,
});
fetchAll();
} catch {
// ignore
} finally {
setSavingProject(false);
}
};
const handleProjectDragStart = (e: React.DragEvent, projectId: string) => { const handleProjectDragStart = (e: React.DragEvent, projectId: string) => {
setDraggedProjectId(projectId); setDraggedProjectId(projectId);
e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', `project:${projectId}`); e.dataTransfer.setData('text/plain', `project:${projectId}`);
}; };
const handleFolderDragOver = (e: React.DragEvent) => { const handleFolderDragOver = (e: React.DragEvent, folderId: string) => {
if (!draggedProjectId) return; if (!draggedProjectId) return;
e.preventDefault(); e.preventDefault();
e.dataTransfer.dropEffect = 'move'; e.dataTransfer.dropEffect = 'move';
(e.currentTarget as HTMLElement).classList.add('tree-drop-target'); setDragOverFolderId(folderId);
}; };
const handleFolderDragLeave = (e: React.DragEvent) => { const handleFolderDragLeave = (_e: React.DragEvent, folderId: string) => {
(e.currentTarget as HTMLElement).classList.remove('tree-drop-target'); if (dragOverFolderId === folderId) {
setDragOverFolderId(null);
}
}; };
const handleFolderDrop = async (e: React.DragEvent, folderId: string) => { const handleFolderDrop = async (e: React.DragEvent, folderId: string) => {
@@ -243,6 +273,7 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
// ignore // ignore
} finally { } finally {
setDraggedProjectId(null); setDraggedProjectId(null);
setDragOverFolderId(null);
} }
}; };
@@ -366,9 +397,9 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
{folders.map(folder => ( {folders.map(folder => (
<div <div
key={folder.id} key={folder.id}
className="treeview-drop-zone" className={`treeview-drop-zone${dragOverFolderId === folder.id ? ' drag-over' : ''}`}
onDragOver={handleFolderDragOver} onDragOver={(e) => handleFolderDragOver(e, folder.id)}
onDragLeave={handleFolderDragLeave} onDragLeave={(e) => handleFolderDragLeave(e, folder.id)}
onDrop={(e) => handleFolderDrop(e, folder.id)} onDrop={(e) => handleFolderDrop(e, folder.id)}
/> />
))} ))}
@@ -418,7 +449,7 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
onClick={() => handleProjectCardClick(project.id)} onClick={() => handleProjectCardClick(project.id)}
draggable draggable
onDragStart={(e) => handleProjectDragStart(e, project.id)} onDragStart={(e) => handleProjectDragStart(e, project.id)}
onDragEnd={() => setDraggedProjectId(null)} onDragEnd={() => { setDraggedProjectId(null); setDragOverFolderId(null); }}
> >
<h3>{project.name}</h3> <h3>{project.name}</h3>
{project.description && <p>{project.description}</p>} {project.description && <p>{project.description}</p>}
@@ -454,10 +485,26 @@ export function Dashboard({ onOpenProject }: DashboardProps) {
<div className="dashboard-info-panel"> <div className="dashboard-info-panel">
{selectedProject ? ( {selectedProject ? (
<> <>
<h3 className="info-panel-title">{selectedProject.name}</h3> <input
{selectedProject.description && ( className="info-panel-title-input"
<p className="info-panel-description">{selectedProject.description}</p> type="text"
)} value={editingProjectName}
onChange={(e) => setEditingProjectName(e.target.value)}
placeholder="Projektname"
/>
<textarea
className="info-panel-desc-textarea"
value={editingProjectDesc}
onChange={(e) => setEditingProjectDesc(e.target.value)}
placeholder="Beschreibung (optional)"
/>
<button
className="info-panel-save-btn"
onClick={handleSaveProject}
disabled={savingProject || !editingProjectName.trim()}
>
{savingProject ? 'Speichern...' : 'Speichern'}
</button>
<div className="info-panel-section"> <div className="info-panel-section">
<h4>Metadaten</h4> <h4>Metadaten</h4>
<dl className="info-panel-meta"> <dl className="info-panel-meta">
+10
View File
@@ -108,6 +108,16 @@ export async function deleteProject(token: string, id: string): Promise<void> {
}); });
} }
export async function updateProject(token: string, id: string, updates: { name?: string; description?: string | null }): Promise<Project> {
const res = await fetch(`${API_BASE}/api/projects/${id}`, {
method: 'PATCH',
headers: authHeaders(token),
body: JSON.stringify(updates),
});
if (!res.ok) throw new Error('Failed to update project');
return res.json();
}
// ─── Project Folders ───────────────────────────────────── // ─── Project Folders ─────────────────────────────────────
export interface ProjectFolder { export interface ProjectFolder {
id: string; id: string;
+179 -114
View File
@@ -6,14 +6,14 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 100vh; min-height: 100vh;
background: var(--bg-primary, #1a1a2e); background: var(--color-surface-2);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-family: 'Inter', system-ui, sans-serif; font-family: 'Inter', system-ui, sans-serif;
} }
.auth-card { .auth-card {
background: var(--bg-secondary, #16213e); background: var(--color-surface);
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 12px; border-radius: 12px;
padding: 2.5rem; padding: 2.5rem;
width: 100%; width: 100%;
@@ -26,12 +26,12 @@
font-weight: 700; font-weight: 700;
margin: 0 0 0.25rem 0; margin: 0 0 0.25rem 0;
text-align: center; text-align: center;
color: var(--accent-primary, #4a9eff); color: var(--color-primary);
} }
.auth-subtitle { .auth-subtitle {
font-size: 1rem; font-size: 1rem;
color: var(--text-secondary, #888); color: var(--color-text-muted);
text-align: center; text-align: center;
margin: 0 0 1.5rem 0; margin: 0 0 1.5rem 0;
} }
@@ -52,22 +52,22 @@
.auth-field label { .auth-field label {
font-size: 0.8125rem; font-size: 0.8125rem;
font-weight: 500; font-weight: 500;
color: var(--text-secondary, #888); color: var(--color-text-muted);
} }
.auth-field input { .auth-field input {
padding: 0.625rem 0.875rem; padding: 0.625rem 0.875rem;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 6px; border-radius: 6px;
background: var(--bg-input, #0f0f23); background: var(--color-surface-3);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.875rem; font-size: 0.875rem;
outline: none; outline: none;
transition: border-color 0.15s; transition: border-color 0.15s;
} }
.auth-field input:focus { .auth-field input:focus {
border-color: var(--accent-primary, #4a9eff); border-color: var(--color-primary);
} }
.auth-button { .auth-button {
@@ -75,7 +75,7 @@
padding: 0.625rem 1rem; padding: 0.625rem 1rem;
border: none; border: none;
border-radius: 6px; border-radius: 6px;
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: #fff; color: #fff;
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 600; font-weight: 600;
@@ -110,13 +110,13 @@
text-align: center; text-align: center;
margin-top: 1.5rem; margin-top: 1.5rem;
font-size: 0.8125rem; font-size: 0.8125rem;
color: var(--text-secondary, #888); color: var(--color-text-muted);
} }
.auth-link { .auth-link {
background: none; background: none;
border: none; border: none;
color: var(--accent-primary, #4a9eff); color: var(--color-primary);
cursor: pointer; cursor: pointer;
font-size: 0.8125rem; font-size: 0.8125rem;
font-weight: 500; font-weight: 500;
@@ -131,8 +131,8 @@
/* ─── Dashboard ────────────────────────────────────── */ /* ─── Dashboard ────────────────────────────────────── */
.dashboard-page { .dashboard-page {
min-height: 100vh; min-height: 100vh;
background: var(--bg-primary, #1a1a2e); background: var(--color-surface-2);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-family: 'Inter', system-ui, sans-serif; font-family: 'Inter', system-ui, sans-serif;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -143,20 +143,20 @@
grid-template-columns: 240px 1fr 300px; grid-template-columns: 240px 1fr 300px;
flex: 1; flex: 1;
gap: 1px; gap: 1px;
background: var(--border-color, #2a2a4a); background: var(--color-border);
overflow: hidden; overflow: hidden;
min-height: 0; min-height: 0;
} }
.dashboard-treeview { .dashboard-treeview {
background: var(--bg-secondary, #16213e); background: var(--color-surface);
overflow-y: auto; overflow-y: auto;
padding: 12px; padding: 12px;
position: relative; position: relative;
} }
.dashboard-info-panel { .dashboard-info-panel {
background: var(--bg-secondary, #16213e); background: var(--color-surface);
overflow-y: auto; overflow-y: auto;
padding: 16px; padding: 16px;
} }
@@ -169,14 +169,14 @@
} }
.treeview-header h3 { .treeview-header h3 {
font-size: 0.875rem; font-size: 14px;
font-weight: 600; font-weight: 600;
margin: 0; margin: 0;
color: var(--text-primary, #e0e0e0); color: var(--color-text);
} }
.treeview-add-folder-btn { .treeview-add-folder-btn {
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: white; color: white;
border: none; border: none;
border-radius: 4px; border-radius: 4px;
@@ -195,24 +195,24 @@
.folder-create-form { .folder-create-form {
margin-bottom: 8px; margin-bottom: 8px;
padding: 8px; padding: 8px;
background: var(--bg-input, #0f0f23); background: var(--color-surface-3);
border-radius: 6px; border-radius: 6px;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
} }
.folder-create-form input { .folder-create-form input {
width: 100%; width: 100%;
padding: 4px 8px; padding: 4px 8px;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 4px; border-radius: 4px;
background: var(--bg-primary, #1a1a2e); background: var(--color-surface-2);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.8125rem; font-size: 13px;
outline: none; outline: none;
box-sizing: border-box; box-sizing: border-box;
} }
.folder-create-form input:focus { border-color: var(--accent-primary, #4a9eff); } .folder-create-form input:focus { border-color: var(--color-primary); }
.folder-create-actions { .folder-create-actions {
display: flex; display: flex;
@@ -225,42 +225,42 @@
border: none; border: none;
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
font-size: 0.75rem; font-size: 12px;
font-weight: 600; font-weight: 600;
} }
.folder-create-actions button:first-child { .folder-create-actions button:first-child {
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: white; color: white;
} }
.folder-create-actions button:last-child { .folder-create-actions button:last-child {
background: transparent; background: transparent;
color: var(--text-secondary, #888); color: var(--color-text-muted);
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
} }
.folder-rename-form { .folder-rename-form {
margin-bottom: 8px; margin-bottom: 8px;
padding: 8px; padding: 8px;
background: var(--bg-input, #0f0f23); background: var(--color-surface-3);
border-radius: 6px; border-radius: 6px;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
} }
.folder-rename-form input { .folder-rename-form input {
width: 100%; width: 100%;
padding: 4px 8px; padding: 4px 8px;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 4px; border-radius: 4px;
background: var(--bg-primary, #1a1a2e); background: var(--color-surface-2);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.8125rem; font-size: 13px;
outline: none; outline: none;
box-sizing: border-box; box-sizing: border-box;
} }
.folder-rename-form input:focus { border-color: var(--accent-primary, #4a9eff); } .folder-rename-form input:focus { border-color: var(--color-primary); }
.folder-action-buttons { .folder-action-buttons {
display: inline-flex; display: inline-flex;
@@ -274,27 +274,26 @@
cursor: pointer; cursor: pointer;
padding: 2px 4px; padding: 2px 4px;
font-size: 12px; font-size: 12px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
border-radius: 3px; border-radius: 3px;
transition: color 0.15s, background 0.15s; transition: color 0.15s, background 0.15s;
} }
.folder-action-btn:hover { color: var(--accent-primary, #4a9eff); background: rgba(74, 158, 255, 0.1); } .folder-action-btn:hover { color: var(--color-primary); background: rgba(37, 99, 235, 0.1); }
.folder-action-btn.delete:hover { color: #e74c3c; background: rgba(231, 76, 60, 0.1); } .folder-action-btn.delete:hover { color: #e74c3c; background: rgba(231, 76, 60, 0.1); }
.tree-drop-target { /* Drag-over visual feedback on tree nodes */
background: rgba(74, 158, 255, 0.15) !important; .tree-node.drag-over {
outline: 2px dashed var(--accent-primary, #4a9eff); background: var(--color-primary) !important;
opacity: 0.7;
border: 2px dashed var(--color-primary);
border-radius: 4px;
} }
.treeview-drop-overlay { .treeview-drop-zone.drag-over {
position: absolute; background: rgba(37, 99, 235, 0.15);
top: 0; left: 0; right: 0; bottom: 0; outline: 2px dashed var(--color-primary);
pointer-events: none; border-radius: 4px;
}
.treeview-drop-zone {
pointer-events: auto;
} }
.context-menu-overlay { .context-menu-overlay {
@@ -306,8 +305,8 @@
.context-menu { .context-menu {
position: fixed; position: fixed;
z-index: 5001; z-index: 5001;
background: var(--bg-secondary, #16213e); background: var(--color-surface);
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 6px; border-radius: 6px;
box-shadow: 0 8px 24px rgba(0,0,0,0.4); box-shadow: 0 8px 24px rgba(0,0,0,0.4);
min-width: 160px; min-width: 160px;
@@ -322,24 +321,24 @@
background: none; background: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.8125rem; font-size: 13px;
transition: background 0.15s; transition: background 0.15s;
} }
.context-menu-item:hover { background: rgba(74, 158, 255, 0.1); } .context-menu-item:hover { background: rgba(37, 99, 235, 0.1); }
.context-menu-item.danger:hover { background: rgba(231, 76, 60, 0.1); color: #e74c3c; } .context-menu-item.danger:hover { background: rgba(231, 76, 60, 0.1); color: #e74c3c; }
.dashboard-project-card.selected { .dashboard-project-card.selected {
border-color: var(--accent-primary, #4a9eff); border-color: var(--color-primary);
box-shadow: 0 0 0 1px var(--accent-primary, #4a9eff); box-shadow: 0 0 0 1px var(--color-primary);
} }
.dashboard-open-btn { .dashboard-open-btn {
padding: 4px 10px; padding: 4px 10px;
border: 1px solid var(--accent-primary, #4a9eff); border: 1px solid var(--color-primary);
border-radius: 4px; border-radius: 4px;
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: white; color: white;
cursor: pointer; cursor: pointer;
font-size: 12px; font-size: 12px;
@@ -348,33 +347,75 @@
.dashboard-open-btn:hover { opacity: 0.85; } .dashboard-open-btn:hover { opacity: 0.85; }
/* ─── Info Panel ────────────────────────────────────── */
.info-panel-title { .info-panel-title {
font-size: 1.125rem; font-size: 18px;
font-weight: 700; font-weight: 700;
margin: 0 0 8px 0; margin: 0 0 8px 0;
color: var(--text-primary, #e0e0e0); color: var(--color-text);
}
.info-panel-title-input {
width: 100%;
font-size: 18px;
font-weight: 700;
margin: 0 0 8px 0;
color: var(--color-text);
background: var(--color-surface-3);
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 6px 8px;
outline: none;
box-sizing: border-box;
font-family: 'Inter', system-ui, sans-serif;
}
.info-panel-title-input:focus {
border-color: var(--color-primary);
} }
.info-panel-description { .info-panel-description {
font-size: 0.8125rem; font-size: 14px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
margin: 0 0 16px 0; margin: 0 0 16px 0;
line-height: 1.5; line-height: 1.5;
} }
.info-panel-desc-textarea {
width: 100%;
font-size: 14px;
color: var(--color-text-muted);
margin: 0 0 16px 0;
line-height: 1.5;
background: var(--color-surface-3);
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 8px;
outline: none;
box-sizing: border-box;
font-family: 'Inter', system-ui, sans-serif;
resize: vertical;
min-height: 60px;
}
.info-panel-desc-textarea:focus {
border-color: var(--color-primary);
}
.info-panel-section { .info-panel-section {
margin-bottom: 20px; margin-bottom: 20px;
} }
.info-panel-section h4 { .info-panel-section h4 {
font-size: 0.75rem; font-size: 12px;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.5px; letter-spacing: 0.5px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
margin: 0 0 8px 0; margin: 0 0 8px 0;
padding-bottom: 4px; padding-bottom: 4px;
border-bottom: 1px solid var(--border-color, #2a2a4a); border-bottom: 1px solid var(--color-border);
} }
.info-panel-meta { .info-panel-meta {
@@ -385,20 +426,20 @@
} }
.info-panel-meta dt { .info-panel-meta dt {
font-size: 0.75rem; font-size: 13px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
font-weight: 500; font-weight: 500;
} }
.info-panel-meta dd { .info-panel-meta dd {
font-size: 0.75rem; font-size: 13px;
color: var(--text-primary, #e0e0e0); color: var(--color-text);
margin: 0; margin: 0;
} }
.info-panel-loading, .info-panel-empty { .info-panel-loading, .info-panel-empty {
font-size: 0.75rem; font-size: 13px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
padding: 8px 0; padding: 8px 0;
} }
@@ -416,23 +457,23 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 6px 8px; padding: 6px 8px;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 4px; border-radius: 4px;
font-size: 0.75rem; font-size: 13px;
} }
.info-panel-share-email { .info-panel-share-email {
color: var(--text-primary, #e0e0e0); color: var(--color-text);
} }
.info-panel-share-perm { .info-panel-share-perm {
font-size: 0.6875rem; font-size: 11px;
text-transform: uppercase; text-transform: uppercase;
font-weight: 600; font-weight: 600;
padding: 1px 6px; padding: 1px 6px;
border-radius: 3px; border-radius: 3px;
background: var(--border-color, #2a2a4a); background: var(--color-border);
color: var(--text-secondary, #888); color: var(--color-text-muted);
} }
.info-panel-open-btn { .info-panel-open-btn {
@@ -440,9 +481,9 @@
padding: 10px; padding: 10px;
border: none; border: none;
border-radius: 6px; border-radius: 6px;
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: white; color: white;
font-size: 0.875rem; font-size: 14px;
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
margin-top: 8px; margin-top: 8px;
@@ -450,6 +491,30 @@
.info-panel-open-btn:hover { opacity: 0.85; } .info-panel-open-btn:hover { opacity: 0.85; }
.info-panel-save-btn {
width: 100%;
padding: 8px;
border: 1px solid var(--color-primary);
border-radius: 6px;
background: var(--color-surface);
color: var(--color-primary);
font-size: 13px;
font-weight: 600;
cursor: pointer;
margin-bottom: 8px;
transition: background 0.15s, color 0.15s;
}
.info-panel-save-btn:hover {
background: var(--color-primary);
color: white;
}
.info-panel-save-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.info-panel-placeholder { .info-panel-placeholder {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -459,8 +524,8 @@
} }
.info-panel-placeholder p { .info-panel-placeholder p {
color: var(--text-secondary, #888); color: var(--color-text-muted);
font-size: 0.875rem; font-size: 14px;
text-align: center; text-align: center;
} }
@@ -478,8 +543,8 @@
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 1rem 2rem; padding: 1rem 2rem;
border-bottom: 1px solid var(--border-color, #2a2a4a); border-bottom: 1px solid var(--color-border);
background: var(--bg-secondary, #16213e); background: var(--color-surface);
} }
.dashboard-brand { .dashboard-brand {
@@ -492,21 +557,21 @@
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 700; font-weight: 700;
margin: 0; margin: 0;
color: var(--accent-primary, #4a9eff); color: var(--color-primary);
} }
.dashboard-user { .dashboard-user {
font-size: 0.8125rem; font-size: 13px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
} }
.dashboard-logout { .dashboard-logout {
padding: 0.375rem 0.875rem; padding: 0.375rem 0.875rem;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 6px; border-radius: 6px;
background: transparent; background: transparent;
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.8125rem; font-size: 13px;
cursor: pointer; cursor: pointer;
transition: background 0.15s; transition: background 0.15s;
} }
@@ -518,7 +583,7 @@
.dashboard-content { .dashboard-content {
padding: 2rem; padding: 2rem;
overflow-y: auto; overflow-y: auto;
background: var(--bg-secondary, #16213e); background: var(--color-surface);
} }
.dashboard-section-header { .dashboard-section-header {
@@ -538,9 +603,9 @@
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
border: none; border: none;
border-radius: 6px; border-radius: 6px;
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: #fff; color: #fff;
font-size: 0.8125rem; font-size: 13px;
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
} }
@@ -556,16 +621,16 @@
flex: 1; flex: 1;
min-width: 150px; min-width: 150px;
padding: 0.5rem 0.75rem; padding: 0.5rem 0.75rem;
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 6px; border-radius: 6px;
background: var(--bg-input, #0f0f23); background: var(--color-surface-3);
color: var(--text-primary, #e0e0e0); color: var(--color-text);
font-size: 0.8125rem; font-size: 13px;
outline: none; outline: none;
} }
.dashboard-create-form input:focus { .dashboard-create-form input:focus {
border-color: var(--accent-primary, #4a9eff); border-color: var(--color-primary);
} }
.dashboard-create-form button { .dashboard-create-form button {
@@ -573,25 +638,25 @@
border: none; border: none;
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
font-size: 0.8125rem; font-size: 13px;
font-weight: 500; font-weight: 500;
} }
.dashboard-create-form button:first-of-type { .dashboard-create-form button:first-of-type {
background: var(--accent-primary, #4a9eff); background: var(--color-primary);
color: #fff; color: #fff;
} }
.dashboard-create-form button:last-of-type { .dashboard-create-form button:last-of-type {
background: transparent; background: transparent;
color: var(--text-secondary, #888); color: var(--color-text-muted);
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
} }
.dashboard-loading, .dashboard-loading,
.dashboard-empty { .dashboard-empty {
text-align: center; text-align: center;
color: var(--text-secondary, #888); color: var(--color-text-muted);
padding: 2rem; padding: 2rem;
} }
@@ -602,8 +667,8 @@
} }
.dashboard-project-card { .dashboard-project-card {
background: var(--bg-secondary, #16213e); background: var(--color-surface);
border: 1px solid var(--border-color, #2a2a4a); border: 1px solid var(--color-border);
border-radius: 8px; border-radius: 8px;
padding: 1.25rem; padding: 1.25rem;
cursor: pointer; cursor: pointer;
@@ -611,7 +676,7 @@
} }
.dashboard-project-card:hover { .dashboard-project-card:hover {
border-color: var(--accent-primary, #4a9eff); border-color: var(--color-primary);
transform: translateY(-2px); transform: translateY(-2px);
} }
@@ -622,8 +687,8 @@
} }
.dashboard-project-card p { .dashboard-project-card p {
font-size: 0.8125rem; font-size: 13px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
margin: 0 0 0.75rem 0; margin: 0 0 0.75rem 0;
} }
@@ -631,8 +696,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
font-size: 0.75rem; font-size: 12px;
color: var(--text-secondary, #888); color: var(--color-text-muted);
} }
.dashboard-delete-btn { .dashboard-delete-btn {
@@ -641,7 +706,7 @@
border-radius: 4px; border-radius: 4px;
background: transparent; background: transparent;
color: #ef4444; color: #ef4444;
font-size: 0.75rem; font-size: 12px;
cursor: pointer; cursor: pointer;
} }