Dateien
TaskMate/frontend/css/assistant.css
Server Deploy c4304a4f88 Feature: Claude Assistent Chat in TaskMate
Neuer Tab "Assistent" mit interaktiver Claude Code Session:
- Chat-UI mit Session-Verwaltung (History, neue/alte Sessions)
- Claude CLI als Child-Process auf dem Host (interaktiv, mit Rueckfragen)
- Streaming-Output per Socket.io
- Nur fuer autorisierte User (Hendrik, Monami)
- 30 Min Inaktivitaets-Timeout
- Task-Uebergabe: Button im Task-Modal sendet Aufgabe an Assistenten
- Chat-Verlauf wird in DB gespeichert

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:04:49 +01:00

435 Zeilen
8.0 KiB
CSS

/**
* TASKMATE - Assistant View Styles
* =================================
* Claude Assistant Chat Interface
*/
/* Layout */
.assistant-layout {
display: grid;
grid-template-columns: 280px 1fr;
height: calc(100vh - 120px);
overflow: hidden;
}
/* ===================== */
/* SIDEBAR */
/* ===================== */
.assistant-sidebar {
background: var(--bg-card);
border-right: 1px solid var(--border-default);
display: flex;
flex-direction: column;
overflow: hidden;
}
.assistant-sidebar-header {
padding: 16px;
border-bottom: 1px solid var(--border-light);
}
.assistant-sidebar-header .btn-block {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.assistant-sessions-list {
flex: 1;
overflow-y: auto;
padding: 8px;
}
.assistant-session-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
border-radius: 8px;
cursor: pointer;
transition: background 0.15s;
margin-bottom: 2px;
}
.assistant-session-item:hover {
background: var(--bg-main);
}
.assistant-session-item.active {
background: var(--primary-light);
border-left: 3px solid var(--primary);
}
.assistant-session-info {
flex: 1;
min-width: 0;
}
.assistant-session-title {
font-size: var(--text-sm);
font-weight: 500;
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.assistant-session-meta {
font-size: var(--text-xs);
color: var(--text-muted);
margin-top: 2px;
}
.assistant-session-delete {
background: none;
border: none;
cursor: pointer;
color: var(--text-muted);
padding: 4px;
border-radius: 4px;
opacity: 0;
transition: opacity 0.15s, color 0.15s;
flex-shrink: 0;
}
.assistant-session-item:hover .assistant-session-delete {
opacity: 1;
}
.assistant-session-delete:hover {
color: var(--danger);
}
/* ===================== */
/* CHAT AREA */
/* ===================== */
.assistant-chat {
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
background: var(--bg-main);
}
.assistant-chat-header {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 20px;
background: var(--bg-card);
border-bottom: 1px solid var(--border-default);
flex-shrink: 0;
}
.assistant-chat-header h3 {
margin: 0;
font-size: var(--text-base);
font-weight: 600;
color: var(--text-primary);
}
/* Status Badges */
.assistant-status-badge {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: var(--text-xs);
font-weight: 500;
padding: 2px 10px;
border-radius: 12px;
}
.assistant-status-badge:empty {
display: none;
}
.assistant-status-badge::before {
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
}
.assistant-status-badge.status-running {
background: rgba(34, 197, 94, 0.1);
color: #16a34a;
}
.assistant-status-badge.status-running::before {
background: #22c55e;
}
.assistant-status-badge.status-thinking {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.assistant-status-badge.status-thinking::before {
background: #f59e0b;
animation: pulse-dot 1.5s infinite;
}
.assistant-status-badge.status-ended,
.assistant-status-badge.status-stopped {
background: rgba(100, 116, 139, 0.1);
color: var(--text-secondary);
}
.assistant-status-badge.status-ended::before,
.assistant-status-badge.status-stopped::before {
background: #94a3b8;
}
.assistant-status-badge.status-error {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.assistant-status-badge.status-error::before {
background: #ef4444;
}
@keyframes pulse-dot {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
/* Messages Area */
.assistant-messages {
flex: 1;
overflow-y: auto;
padding: 20px;
display: flex;
flex-direction: column;
gap: 12px;
}
/* Message Bubbles */
.assistant-message {
max-width: 80%;
padding: 12px 16px;
border-radius: 12px;
font-size: var(--text-sm);
line-height: 1.6;
word-wrap: break-word;
}
.assistant-message.user {
align-self: flex-end;
background: var(--primary);
color: var(--text-inverse);
border-bottom-right-radius: 4px;
}
.assistant-message.assistant {
align-self: flex-start;
background: var(--bg-card);
color: var(--text-primary);
border: 1px solid var(--border-default);
border-bottom-left-radius: 4px;
}
/* Markdown in assistant messages */
.assistant-message.assistant code {
background: rgba(0, 0, 0, 0.06);
padding: 2px 6px;
border-radius: 4px;
font-size: 0.85em;
font-family: 'Courier New', monospace;
}
.assistant-message.assistant pre {
background: #1e293b;
color: #e2e8f0;
padding: 12px 16px;
border-radius: 8px;
overflow-x: auto;
margin: 8px 0;
}
.assistant-message.assistant pre code {
background: none;
padding: 0;
color: inherit;
font-size: 0.85em;
}
.assistant-message.assistant ul,
.assistant-message.assistant ol {
margin: 4px 0;
padding-left: 20px;
}
.assistant-message.assistant li {
margin-bottom: 2px;
}
.assistant-message.assistant h1,
.assistant-message.assistant h2,
.assistant-message.assistant h3,
.assistant-message.assistant h4 {
margin: 8px 0 4px;
font-weight: 600;
}
.assistant-message.assistant h1 { font-size: 1.2em; }
.assistant-message.assistant h2 { font-size: 1.1em; }
.assistant-message.assistant h3 { font-size: 1.05em; }
.assistant-message.assistant a {
color: var(--primary);
text-decoration: underline;
}
.assistant-message.assistant blockquote {
border-left: 3px solid var(--border-default);
margin: 8px 0;
padding: 4px 12px;
color: var(--text-secondary);
}
.assistant-message .message-time {
font-size: var(--text-xs);
opacity: 0.6;
margin-top: 4px;
display: block;
}
/* Streaming cursor */
.assistant-message.streaming::after {
content: '';
display: inline-block;
width: 8px;
height: 16px;
background: var(--text-secondary);
margin-left: 2px;
vertical-align: text-bottom;
animation: blink-cursor 0.8s infinite;
}
@keyframes blink-cursor {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* Input Bar */
.assistant-input-bar {
display: flex;
align-items: flex-end;
gap: 8px;
padding: 12px 20px;
background: var(--bg-card);
border-top: 1px solid var(--border-default);
flex-shrink: 0;
}
.assistant-input {
flex: 1;
border: 1px solid var(--border-default);
border-radius: 12px;
padding: 10px 16px;
font-size: var(--text-sm);
font-family: 'Poppins', sans-serif;
resize: none;
max-height: 150px;
line-height: 1.5;
background: var(--bg-main);
color: var(--text-primary);
transition: border-color 0.15s;
}
.assistant-input:focus {
outline: none;
border-color: var(--primary);
}
.assistant-input::placeholder {
color: var(--text-placeholder);
}
.assistant-send-btn {
width: 40px;
height: 40px;
min-width: 40px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
flex-shrink: 0;
}
/* Empty State */
.assistant-empty {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: var(--text-muted);
pointer-events: none;
}
.assistant-empty-icon {
margin-bottom: 16px;
opacity: 0.3;
}
.assistant-empty h3 {
margin: 0 0 8px;
font-size: var(--text-lg);
color: var(--text-secondary);
}
.assistant-empty p {
margin: 0;
font-size: var(--text-sm);
}
/* Hide empty state when messages present */
.assistant-messages:not(:empty) ~ .assistant-empty {
display: none;
}
/* Hide input bar when no session */
.assistant-chat.no-session .assistant-input-bar {
display: none;
}
/* ===================== */
/* RESPONSIVE */
/* ===================== */
@media (max-width: 768px) {
.assistant-layout {
grid-template-columns: 1fr;
height: calc(100vh - 60px);
}
.assistant-sidebar {
display: none;
}
.assistant-sidebar.mobile-visible {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
.assistant-message {
max-width: 90%;
}
.assistant-input-bar {
padding: 8px 12px;
}
}