From dc097811b9c1b250e2b66d3eabfa70e3565f6c23 Mon Sep 17 00:00:00 2001 From: tusuii Date: Sun, 15 Feb 2026 12:10:40 +0530 Subject: [PATCH] feat: add comprehensive user management for authorities USER MANAGEMENT (CTO/Manager only): - Department overview chips with click-to-filter - Search by name or email - Filter by role dropdown - Table/Grid view toggle TABLE VIEW: - Inline role dropdown (color-coded per role) - Inline department dropdown - Task progress bars (done/total) - Active/Inactive status dots - Edit, Deactivate, Delete action buttons - Expandable rows with task stats (total/completed/in-progress/overdue) GRID VIEW: - Member cards with avatar, badges, and stats - Task completion progress bars - Deactivate/Reactivate buttons MODALS: - Add Member: name, email, role, dept, password with validation - Edit Member: update all fields (role changes CTO-only) - Confirmation dialog for deactivate/reactivate/delete ROLE-BASED ACCESS: - CTO can change anyone's role - Manager can edit users but not change roles - Employee has read-only access (no action buttons) - Users cannot deactivate/delete themselves TEAM TASKS ENHANCEMENT: - Added group-by-department option with toggle buttons --- src/App.tsx | 8 +- src/Pages.tsx | 617 +++++++++++-- src/index.css | 2366 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 2664 insertions(+), 327 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 31d595f..cb43468 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { SEED_TASKS } from './data'; +import { SEED_TASKS, USERS } from './data'; import type { Task, User, Status } from './data'; import { LoginPage } from './Login'; import { Sidebar } from './Sidebar'; @@ -25,6 +25,9 @@ export default function App() { const now = new Date(); const [currentUser, setCurrentUser] = useState(null); const [tasks, setTasks] = useState(SEED_TASKS); + const [managedUsers, setManagedUsers] = useState(() => + USERS.map(u => ({ ...u, active: true, joinedDate: '2025-12-01' })) + ); const [activePage, setActivePage] = useState('calendar'); const [activeView, setActiveView] = useState('calendar'); const [activeTask, setActiveTask] = useState(null); @@ -113,7 +116,8 @@ export default function App() { )} {displayPage === 'teamtasks' && } {displayPage === 'reports' && } - {displayPage === 'members' && } + {displayPage === 'members' && } diff --git a/src/Pages.tsx b/src/Pages.tsx index 805dbde..cae6a27 100644 --- a/src/Pages.tsx +++ b/src/Pages.tsx @@ -1,109 +1,432 @@ import React, { useState } from 'react'; import type { Task, User } from './data'; import { USERS, PRIORITY_COLORS } from './data'; -import { Avatar, StatusBadge } from './Shared'; +import { Avatar, StatusBadge, RoleBadge } from './Shared'; +/* ── Team Tasks Page ── */ export function TeamTasksPage({ tasks }: { tasks: Task[]; currentUser: User }) { const [expanded, setExpanded] = useState>({}); + const [groupBy, setGroupBy] = useState<'member' | 'dept'>('member'); const members = USERS; + const departments = [...new Set(USERS.map(u => u.dept))]; + return (
-

Team Tasks

- {members.map(m => { - const mTasks = tasks.filter(t => t.assignee === m.id); - const isOpen = expanded[m.id] !== false; - return ( -
-
setExpanded(e => ({ ...e, [m.id]: !isOpen }))}> - - {m.name} - ({mTasks.length} tasks) - {isOpen ? '▼' : '▶'} -
- {isOpen && ( -
- {mTasks.map(t => ( -
- - {t.title} - - - {new Date(t.dueDate + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} - - {t.subtasks.length > 0 && 📋 {t.subtasks.filter(s => s.done).length}/{t.subtasks.length}} -
- ))} +
+

Team Tasks

+
+ + +
+
+ {groupBy === 'member' ? ( + members.map(m => { + const mTasks = tasks.filter(t => t.assignee === m.id); + const isOpen = expanded[m.id] !== false; + return ( +
+
setExpanded(e => ({ ...e, [m.id]: !isOpen }))}> + + {m.name} + + ({mTasks.length} tasks) + {isOpen ? '▼' : '▶'}
- )} -
- ); - })} + {isOpen && ( +
+ {mTasks.map(t => ( +
+ + {t.title} + + + {new Date(t.dueDate + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} + + {t.subtasks.length > 0 && 📋 {t.subtasks.filter(s => s.done).length}/{t.subtasks.length}} +
+ ))} + {mTasks.length === 0 && No tasks assigned} +
+ )} +
+ ); + }) + ) : ( + departments.map(dept => { + const deptMembers = members.filter(m => m.dept === dept); + const deptTasks = tasks.filter(t => deptMembers.some(m => m.id === t.assignee)); + const isOpen = expanded[dept] !== false; + return ( +
+
setExpanded(e => ({ ...e, [dept]: !isOpen }))}> + 🏢 + {dept} + {deptMembers.length} members + ({deptTasks.length} tasks) + {isOpen ? '▼' : '▶'} +
+ {isOpen && ( +
+ {deptMembers.map(m => { + const mTasks = tasks.filter(t => t.assignee === m.id); + return ( +
+
+ + {m.name} + {mTasks.length} tasks +
+ {mTasks.map(t => ( +
+ + {t.title} + +
+ ))} +
+ ); + })} +
+ )} +
+ ); + }) + )}
); } -export function MembersPage({ tasks }: { tasks: Task[] }) { - const [expanded, setExpanded] = useState(null); - const [showInvite, setShowInvite] = useState(false); +/* ── TYPES ── */ +interface ManagedUser { + id: string; name: string; role: string; email: string; + pass: string; color: string; avatar: string; dept: string; + active: boolean; joinedDate: string; +} + +const ROLE_OPTIONS = ['employee', 'manager', 'cto'] as const; +const DEPT_OPTIONS = ['Leadership', 'DevOps', 'Backend', 'Frontend', 'QA', 'Design', 'Data', 'Security']; +const ROLE_COLORS: Record = { cto: '#818cf8', manager: '#fb923c', employee: '#22c55e' }; + +/* ── Members Page with full user management ── */ +export function MembersPage({ tasks, currentUser, users, onUpdateUsers }: { + tasks: Task[]; + currentUser: User; + users: ManagedUser[]; + onUpdateUsers: (users: ManagedUser[]) => void; +}) { + const [expandedId, setExpandedId] = useState(null); + const [showAdd, setShowAdd] = useState(false); + const [editUser, setEditUser] = useState(null); + const [confirmAction, setConfirmAction] = useState<{ userId: string; action: 'deactivate' | 'reactivate' | 'delete' } | null>(null); + const [searchQ, setSearchQ] = useState(''); + const [filterRole, setFilterRole] = useState('all'); + const [filterDept, setFilterDept] = useState('all'); + const [view, setView] = useState<'table' | 'grid'>('table'); + + const isAuthority = currentUser.role === 'cto' || currentUser.role === 'manager'; + + // filter users + let filtered = users; + if (searchQ) filtered = filtered.filter(u => u.name.toLowerCase().includes(searchQ.toLowerCase()) || u.email.toLowerCase().includes(searchQ.toLowerCase())); + if (filterRole !== 'all') filtered = filtered.filter(u => u.role === filterRole); + if (filterDept !== 'all') filtered = filtered.filter(u => u.dept === filterDept); + + const departments = [...new Set(users.map(u => u.dept))]; + const activeCount = users.filter(u => u.active).length; + const deptStats = departments.map(d => ({ dept: d, count: users.filter(u => u.dept === d && u.active).length })); + + const handleAddUser = (newUser: Omit) => { + const u: ManagedUser = { + ...newUser, + id: `u${Date.now()}`, + avatar: newUser.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2), + active: true, + joinedDate: new Date().toISOString().split('T')[0], + }; + onUpdateUsers([...users, u]); + setShowAdd(false); + }; + + const handleEditUser = (updated: ManagedUser) => { + onUpdateUsers(users.map(u => u.id === updated.id ? updated : u)); + setEditUser(null); + }; + + const handleToggleActive = (userId: string) => { + onUpdateUsers(users.map(u => u.id === userId ? { ...u, active: !u.active } : u)); + setConfirmAction(null); + }; + + const handleDeleteUser = (userId: string) => { + onUpdateUsers(users.filter(u => u.id !== userId)); + setConfirmAction(null); + }; + + const handleChangeRole = (userId: string, newRole: string) => { + onUpdateUsers(users.map(u => u.id === userId ? { ...u, role: newRole } : u)); + }; + + const handleChangeDept = (userId: string, newDept: string) => { + onUpdateUsers(users.map(u => u.id === userId ? { ...u, dept: newDept } : u)); + }; return (
+ {/* HEADER */}
-

Team Members

- +
+

User Management

+ {activeCount} active · {users.length - activeCount} inactive · {departments.length} departments +
+
+ {isAuthority && } +
- - - - {USERS.map(u => { + + {/* DEPARTMENT OVERVIEW */} +
+ {deptStats.map(d => ( +
setFilterDept(filterDept === d.dept ? 'all' : d.dept)}> + 🏢 + {d.dept} + {d.count} +
+ ))} +
+ + {/* TOOLBAR */} +
+
+ 🔍 + setSearchQ(e.target.value)} /> +
+ +
+ + +
+
+ + {/* TABLE VIEW */} + {view === 'table' && ( +
AvatarFull NameRoleDeptAssignedDoneActive
+ + + + + + + + + + {isAuthority && } + + + + {filtered.map(u => { + const ut = tasks.filter(t => t.assignee === u.id); + const done = ut.filter(t => t.status === 'done').length; + const isExpanded = expandedId === u.id; + const isSelf = u.id === currentUser.id; + return ( + + setExpandedId(isExpanded ? null : u.id)} + style={{ opacity: u.active ? 1 : 0.5 }}> + + + + + + + + {isAuthority && ( + + )} + + {isExpanded && ( + + )} + + ); + })} + +
NameEmailRoleDepartmentTasksStatusActions
+
{u.name}
+ {!u.active && DEACTIVATED} +
{u.email} + {isAuthority && !isSelf ? ( + + ) : ( + + {u.role.toUpperCase()} + + )} + + {isAuthority && !isSelf ? ( + + ) : ( + {u.dept} + )} + + {done}/{ut.length} + {ut.length > 0 && ( +
+
+
+ )} +
+ + {u.active ? 'Active' : 'Inactive'} + + e.stopPropagation()}> +
+ + {!isSelf && ( + <> + + + + )} +
+
+
+
+
+ {ut.length} + Total Tasks +
+
+ {done} + Completed +
+
+ {ut.filter(t => t.status === 'inprogress').length} + In Progress +
+
+ + {ut.filter(t => new Date(t.dueDate + 'T00:00:00') < new Date() && t.status !== 'done').length} + + Overdue +
+
+ {ut.map(t => ( +
+ + {t.title} + + + {new Date(t.dueDate + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} + +
+ ))} + {ut.length === 0 && No tasks assigned} +
+
+ )} + + {/* GRID VIEW */} + {view === 'grid' && ( +
+ {filtered.map(u => { const ut = tasks.filter(t => t.assignee === u.id); const done = ut.filter(t => t.status === 'done').length; - const active = ut.filter(t => t.status !== 'done').length; - const roleColors: Record = { cto: '#818cf8', manager: '#fb923c', employee: '#22c55e' }; return ( - - setExpanded(expanded === u.id ? null : u.id)}> - - {u.name} - {u.role.toUpperCase()} - {u.dept} - {ut.length} - {done} - {active} - - {expanded === u.id && ( - -
- {ut.map(t => ( -
- - {t.title} - -
- ))} - {ut.length === 0 && No tasks assigned} -
- +
+
+ +
+
{u.name}
+
{u.email}
+
+ {isAuthority && u.id !== currentUser.id && ( + + )} +
+
+ + {u.dept} + + {u.active ? 'Active' : 'Inactive'} + +
+
+
{ut.length} tasks
+
{done} done
+
{ut.length - done} active
+
+ {ut.length > 0 && ( +
+
+
)} - + {isAuthority && u.id !== currentUser.id && ( +
+ +
+ )} +
); })} - - +
+ )} - {showInvite && ( -
setShowInvite(false)}> -
e.stopPropagation()}> -

Invite Member

-
-
-
- - -
+ {/* ADD USER MODAL */} + {showAdd && setShowAdd(false)} onAdd={handleAddUser} />} + + {/* EDIT USER MODAL */} + {editUser && setEditUser(null)} onSave={handleEditUser} isCTO={currentUser.role === 'cto'} />} + + {/* CONFIRM DIALOG */} + {confirmAction && ( +
setConfirmAction(null)}> +
e.stopPropagation()}> +
+

{confirmAction.action === 'delete' ? '🗑️ Delete User' : confirmAction.action === 'deactivate' ? '🚫 Deactivate User' : '✅ Reactivate User'}

+ +
+
+

+ {confirmAction.action === 'delete' + ? `Are you sure you want to permanently delete ${users.find(u => u.id === confirmAction.userId)?.name}? This action cannot be undone.` + : confirmAction.action === 'deactivate' + ? `Are you sure you want to deactivate ${users.find(u => u.id === confirmAction.userId)?.name}? They will lose access but their data will be preserved.` + : `Reactivate ${users.find(u => u.id === confirmAction.userId)?.name} and restore their access?` + } +

+
+
+ +
-
)} @@ -111,3 +434,141 @@ export function MembersPage({ tasks }: { tasks: Task[] }) { ); } +/* ── Add User Modal ── */ +function AddUserModal({ onClose, onAdd }: { + onClose: () => void; + onAdd: (u: Omit) => void; +}) { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [role, setRole] = useState('employee'); + const [dept, setDept] = useState('DevOps'); + const [pass, setPass] = useState(''); + const [errors, setErrors] = useState>({}); + + const AVATAR_COLORS = ['#818cf8', '#f59e0b', '#34d399', '#f472b6', '#fb923c', '#6366f1', '#ec4899', '#14b8a6']; + + const validate = () => { + const errs: Record = {}; + if (!name.trim()) errs.name = true; + if (!email.trim() || !email.includes('@')) errs.email = true; + if (!pass.trim() || pass.length < 4) errs.pass = true; + setErrors(errs); + return Object.keys(errs).length === 0; + }; + + const handleSubmit = () => { + if (!validate()) return; + onAdd({ + name: name.trim(), email: email.trim(), role, dept, pass, + color: AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)], + }); + }; + + return ( +
+
e.stopPropagation()}> +
+

👤 Add Team Member

+ +
+
+
+ + setName(e.target.value)} /> +
+
+ + setEmail(e.target.value)} /> +
+
+
+ + +
+
+ + +
+
+
+ + setPass(e.target.value)} /> +
+
+
+ + +
+
+
+ ); +} + +/* ── Edit User Modal ── */ +function EditUserModal({ user, onClose, onSave, isCTO }: { + user: ManagedUser; onClose: () => void; onSave: (u: ManagedUser) => void; isCTO: boolean; +}) { + const [name, setName] = useState(user.name); + const [email, setEmail] = useState(user.email); + const [role, setRole] = useState(user.role); + const [dept, setDept] = useState(user.dept); + + const handleSave = () => { + onSave({ + ...user, name: name.trim(), email: email.trim(), role, dept, + avatar: name.trim().split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2), + }); + }; + + return ( +
+
e.stopPropagation()}> +
+

✏️ Edit Member

+ +
+
+
+ +
+
{user.name}
+
Joined {user.joinedDate || 'N/A'}
+
+
+
+ + setName(e.target.value)} /> +
+
+ + setEmail(e.target.value)} /> +
+
+
+ + + {!isCTO && Only CTO can change roles} +
+
+ + +
+
+
+
+ + +
+
+
+ ); +} diff --git a/src/index.css b/src/index.css index ce55f13..8f23f9b 100644 --- a/src/index.css +++ b/src/index.css @@ -11,19 +11,29 @@ --text-secondary: #94a3b8; --accent: #6366f1; --accent-hover: #4f46e5; - --accent-glow: rgba(99,102,241,0.3); - --accent-bg: rgba(99,102,241,0.15); - --critical: #ef4444; --critical-bg: rgba(239,68,68,0.13); - --high: #f97316; --high-bg: rgba(249,115,22,0.13); - --medium: #eab308; --medium-bg: rgba(234,179,8,0.13); - --low: #22c55e; --low-bg: rgba(34,197,94,0.13); + --accent-glow: rgba(99, 102, 241, 0.3); + --accent-bg: rgba(99, 102, 241, 0.15); + --critical: #ef4444; + --critical-bg: rgba(239, 68, 68, 0.13); + --high: #f97316; + --high-bg: rgba(249, 115, 22, 0.13); + --medium: #eab308; + --medium-bg: rgba(234, 179, 8, 0.13); + --low: #22c55e; + --low-bg: rgba(34, 197, 94, 0.13); --status-todo: #64748b; --status-inprogress: #818cf8; --status-review: #f59e0b; --status-done: #22c55e; } -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} body { font-family: 'DM Sans', sans-serif; @@ -33,285 +43,2147 @@ body { -webkit-font-smoothing: antialiased; } -::-webkit-scrollbar { width: 6px; height: 6px; } -::-webkit-scrollbar-track { background: var(--bg-surface); } -::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; } +::-webkit-scrollbar { + width: 6px; + height: 6px; +} -@keyframes slideIn { from { transform: translateX(40px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } -@keyframes fadeUp { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } -@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } +::-webkit-scrollbar-track { + background: var(--bg-surface); +} + +::-webkit-scrollbar-thumb { + background: var(--border); + border-radius: 3px; +} + +@keyframes slideIn { + from { + transform: translateX(40px); + opacity: 0; + } + + to { + transform: translateX(0); + opacity: 1; + } +} + +@keyframes fadeUp { + from { + transform: translateY(24px); + opacity: 0; + } + + to { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} /* LOGIN */ -.login-bg { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: radial-gradient(ellipse at center, #0d1a3a 0%, #060b18 70%); } -.login-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 16px; padding: 40px; width: 400px; animation: fadeUp 0.4s ease; } -.login-logo { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 8px; } -.login-logo-icon { width: 44px; height: 44px; background: var(--accent); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 22px; } -.login-title { font-size: 22px; font-weight: 800; } -.login-tagline { text-align: center; color: var(--text-muted); font-size: 13px; margin-bottom: 20px; } -.login-divider { height: 1px; background: var(--border); margin: 16px 0; } -.login-label { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; display: block; } -.login-input-wrap { position: relative; margin-bottom: 16px; } -.login-input { width: 100%; padding: 10px 14px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; color: var(--text-primary); font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.15s; } -.login-input:focus { border-color: var(--accent); } -.login-input.error { border-color: var(--critical); } -.login-eye { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; } -.login-btn { width: 100%; padding: 12px; background: var(--accent); color: #fff; border: none; border-radius: 10px; font-size: 14px; font-weight: 700; font-family: inherit; cursor: pointer; box-shadow: 0 0 20px var(--accent-glow); transition: background 0.15s; } -.login-btn:hover { background: var(--accent-hover); } -.login-hint { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 10px 14px; font-size: 12px; color: var(--text-muted); margin-top: 16px; text-align: center; } -.login-error { color: var(--critical); font-size: 12px; margin-top: 8px; text-align: center; } +.login-bg { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: radial-gradient(ellipse at center, #0d1a3a 0%, #060b18 70%); +} + +.login-card { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 16px; + padding: 40px; + width: 400px; + animation: fadeUp 0.4s ease; +} + +.login-logo { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin-bottom: 8px; +} + +.login-logo-icon { + width: 44px; + height: 44px; + background: var(--accent); + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-size: 22px; +} + +.login-title { + font-size: 22px; + font-weight: 800; +} + +.login-tagline { + text-align: center; + color: var(--text-muted); + font-size: 13px; + margin-bottom: 20px; +} + +.login-divider { + height: 1px; + background: var(--border); + margin: 16px 0; +} + +.login-label { + font-size: 13px; + font-weight: 600; + color: var(--text-secondary); + margin-bottom: 6px; + display: block; +} + +.login-input-wrap { + position: relative; + margin-bottom: 16px; +} + +.login-input { + width: 100%; + padding: 10px 14px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 14px; + font-family: inherit; + outline: none; + transition: border-color 0.15s; +} + +.login-input:focus { + border-color: var(--accent); +} + +.login-input.error { + border-color: var(--critical); +} + +.login-eye { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + font-size: 16px; +} + +.login-btn { + width: 100%; + padding: 12px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 10px; + font-size: 14px; + font-weight: 700; + font-family: inherit; + cursor: pointer; + box-shadow: 0 0 20px var(--accent-glow); + transition: background 0.15s; +} + +.login-btn:hover { + background: var(--accent-hover); +} + +.login-hint { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + padding: 10px 14px; + font-size: 12px; + color: var(--text-muted); + margin-top: 16px; + text-align: center; +} + +.login-error { + color: var(--critical); + font-size: 12px; + margin-top: 8px; + text-align: center; +} /* APP SHELL */ -.app-shell { display: flex; flex-direction: column; height: 100vh; background: var(--bg-base); } -.app-body { display: flex; flex: 1; overflow: hidden; } -.main-content { flex: 1; overflow-y: auto; padding: 0; } +.app-shell { + display: flex; + flex-direction: column; + height: 100vh; + background: var(--bg-base); +} + +.app-body { + display: flex; + flex: 1; + overflow: hidden; +} + +.main-content { + flex: 1; + overflow-y: auto; + padding: 0; +} /* SIDEBAR */ -.sidebar { width: 240px; min-width: 240px; background: var(--bg-surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; height: 100%; } -.sidebar-logo { padding: 16px 20px; display: flex; align-items: center; gap: 10px; } -.sidebar-logo-icon { width: 32px; height: 32px; background: var(--accent); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; } -.sidebar-logo-text { font-size: 16px; font-weight: 800; } -.sidebar-divider { height: 1px; background: var(--border); margin: 0 16px; } -.sidebar-section-label { font-size: 10px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.1em; padding: 16px 20px 8px; } -.sidebar-nav { flex: 1; display: flex; flex-direction: column; } -.sidebar-item { display: flex; align-items: center; gap: 10px; padding: 10px 16px; margin: 2px 8px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-muted); transition: all 0.15s; border-left: 3px solid transparent; text-decoration: none; } -.sidebar-item:hover { color: #e2e8f0; background: rgba(255,255,255,0.04); } -.sidebar-item.active { background: var(--accent-bg); color: #818cf8; border-left-color: var(--accent); } -.sidebar-item-icon { font-size: 18px; width: 20px; text-align: center; } -.sidebar-profile { padding: 16px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 10px; } -.sidebar-profile-info { flex: 1; } -.sidebar-profile-name { font-size: 13px; font-weight: 600; color: #e2e8f0; } -.sidebar-signout { background: none; border: none; color: var(--text-muted); font-size: 11px; cursor: pointer; font-family: inherit; padding: 0; transition: color 0.15s; } -.sidebar-signout:hover { color: var(--critical); } +.sidebar { + width: 240px; + min-width: 240px; + background: var(--bg-surface); + border-right: 1px solid var(--border); + display: flex; + flex-direction: column; + height: 100%; +} + +.sidebar-logo { + padding: 16px 20px; + display: flex; + align-items: center; + gap: 10px; +} + +.sidebar-logo-icon { + width: 32px; + height: 32px; + background: var(--accent); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; +} + +.sidebar-logo-text { + font-size: 16px; + font-weight: 800; +} + +.sidebar-divider { + height: 1px; + background: var(--border); + margin: 0 16px; +} + +.sidebar-section-label { + font-size: 10px; + font-weight: 700; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.1em; + padding: 16px 20px 8px; +} + +.sidebar-nav { + flex: 1; + display: flex; + flex-direction: column; +} + +.sidebar-item { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 16px; + margin: 2px 8px; + border-radius: 8px; + cursor: pointer; + font-size: 13px; + font-weight: 600; + color: var(--text-muted); + transition: all 0.15s; + border-left: 3px solid transparent; + text-decoration: none; +} + +.sidebar-item:hover { + color: #e2e8f0; + background: rgba(255, 255, 255, 0.04); +} + +.sidebar-item.active { + background: var(--accent-bg); + color: #818cf8; + border-left-color: var(--accent); +} + +.sidebar-item-icon { + font-size: 18px; + width: 20px; + text-align: center; +} + +.sidebar-profile { + padding: 16px; + border-top: 1px solid var(--border); + display: flex; + align-items: center; + gap: 10px; +} + +.sidebar-profile-info { + flex: 1; +} + +.sidebar-profile-name { + font-size: 13px; + font-weight: 600; + color: #e2e8f0; +} + +.sidebar-signout { + background: none; + border: none; + color: var(--text-muted); + font-size: 11px; + cursor: pointer; + font-family: inherit; + padding: 0; + transition: color 0.15s; +} + +.sidebar-signout:hover { + color: var(--critical); +} /* NAVBAR */ -.top-navbar { height: 56px; min-height: 56px; background: var(--bg-surface); border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 20px; gap: 16px; position: sticky; top: 0; z-index: 50; } -.navbar-title { font-size: 16px; font-weight: 700; white-space: nowrap; } -.navbar-search { flex: 0 0 220px; margin: 0 auto; position: relative; } -.navbar-search input { width: 100%; padding: 7px 12px 7px 32px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; color: var(--text-primary); font-size: 12px; font-family: inherit; outline: none; } -.navbar-search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-muted); font-size: 13px; } -.navbar-right { display: flex; align-items: center; gap: 12px; margin-left: auto; } -.filter-chips { display: flex; align-items: center; gap: 6px; } -.filter-chip { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 9px; font-weight: 700; cursor: pointer; border: 2px solid transparent; transition: all 0.15s; } -.filter-chip.active { box-shadow: 0 0 0 2px var(--accent); } -.filter-chip-all { padding: 4px 12px; border-radius: 14px; font-size: 11px; font-weight: 600; cursor: pointer; background: var(--bg-card); border: 1px solid var(--border); color: var(--text-muted); transition: all 0.15s; width: auto; height: auto; } -.filter-chip-all.active { background: var(--accent-bg); color: var(--accent); border-color: var(--accent); } -.notif-btn { position: relative; background: none; border: none; color: var(--text-muted); font-size: 18px; cursor: pointer; transition: color 0.15s; } -.notif-btn:hover { color: var(--text-primary); } -.notif-badge { position: absolute; top: -4px; right: -6px; background: var(--critical); color: #fff; font-size: 9px; font-weight: 700; width: 16px; height: 16px; border-radius: 50%; display: flex; align-items: center; justify-content: center; } -.new-task-btn { padding: 8px 16px; background: var(--accent); color: #fff; border: none; border-radius: 8px; font-size: 13px; font-weight: 700; font-family: inherit; cursor: pointer; box-shadow: 0 0 20px var(--accent-glow); transition: background 0.15s; white-space: nowrap; } -.new-task-btn:hover { background: var(--accent-hover); } +.top-navbar { + height: 56px; + min-height: 56px; + background: var(--bg-surface); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + padding: 0 20px; + gap: 16px; + position: sticky; + top: 0; + z-index: 50; +} + +.navbar-title { + font-size: 16px; + font-weight: 700; + white-space: nowrap; +} + +.navbar-search { + flex: 0 0 220px; + margin: 0 auto; + position: relative; +} + +.navbar-search input { + width: 100%; + padding: 7px 12px 7px 32px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 12px; + font-family: inherit; + outline: none; +} + +.navbar-search-icon { + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + color: var(--text-muted); + font-size: 13px; +} + +.navbar-right { + display: flex; + align-items: center; + gap: 12px; + margin-left: auto; +} + +.filter-chips { + display: flex; + align-items: center; + gap: 6px; +} + +.filter-chip { + width: 28px; + height: 28px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 9px; + font-weight: 700; + cursor: pointer; + border: 2px solid transparent; + transition: all 0.15s; +} + +.filter-chip.active { + box-shadow: 0 0 0 2px var(--accent); +} + +.filter-chip-all { + padding: 4px 12px; + border-radius: 14px; + font-size: 11px; + font-weight: 600; + cursor: pointer; + background: var(--bg-card); + border: 1px solid var(--border); + color: var(--text-muted); + transition: all 0.15s; + width: auto; + height: auto; +} + +.filter-chip-all.active { + background: var(--accent-bg); + color: var(--accent); + border-color: var(--accent); +} + +.notif-btn { + position: relative; + background: none; + border: none; + color: var(--text-muted); + font-size: 18px; + cursor: pointer; + transition: color 0.15s; +} + +.notif-btn:hover { + color: var(--text-primary); +} + +.notif-badge { + position: absolute; + top: -4px; + right: -6px; + background: var(--critical); + color: #fff; + font-size: 9px; + font-weight: 700; + width: 16px; + height: 16px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.new-task-btn { + padding: 8px 16px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 8px; + font-size: 13px; + font-weight: 700; + font-family: inherit; + cursor: pointer; + box-shadow: 0 0 20px var(--accent-glow); + transition: background 0.15s; + white-space: nowrap; +} + +.new-task-btn:hover { + background: var(--accent-hover); +} /* BOTTOM TOGGLE */ -.bottom-bar { height: 48px; min-height: 48px; background: var(--bg-surface); border-top: 1px solid var(--border); display: flex; align-items: center; justify-content: center; } -.toggle-pill { display: flex; background: var(--bg-card); border: 1px solid var(--border); border-radius: 40px; padding: 4px; } -.toggle-btn { width: 120px; height: 40px; border: none; border-radius: 36px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; cursor: pointer; font-family: inherit; transition: all 0.15s; background: transparent; color: var(--text-muted); display: flex; align-items: center; justify-content: center; gap: 6px; } -.toggle-btn.active { background: var(--accent); color: #fff; box-shadow: 0 0 16px rgba(99,102,241,0.4); } -.toggle-btn:not(.active):hover { color: #e2e8f0; } +.bottom-bar { + height: 48px; + min-height: 48px; + background: var(--bg-surface); + border-top: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: center; +} + +.toggle-pill { + display: flex; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 40px; + padding: 4px; +} + +.toggle-btn { + width: 120px; + height: 40px; + border: none; + border-radius: 36px; + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + cursor: pointer; + font-family: inherit; + transition: all 0.15s; + background: transparent; + color: var(--text-muted); + display: flex; + align-items: center; + justify-content: center; + gap: 6px; +} + +.toggle-btn.active { + background: var(--accent); + color: #fff; + box-shadow: 0 0 16px rgba(99, 102, 241, 0.4); +} + +.toggle-btn:not(.active):hover { + color: #e2e8f0; +} /* AVATAR */ -.avatar { border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; color: #fff; flex-shrink: 0; } +.avatar { + border-radius: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + font-weight: 700; + color: #fff; + flex-shrink: 0; +} /* BADGES */ -.priority-badge, .status-badge { padding: 2px 8px; border-radius: 10px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; display: inline-flex; align-items: center; gap: 4px; } -.role-badge { padding: 2px 8px; border-radius: 10px; font-size: 10px; font-weight: 600; } -.tag-pill { padding: 2px 8px; border-radius: 6px; font-size: 10px; background: var(--bg-card); border: 1px solid var(--border); color: var(--text-secondary); } +.priority-badge, +.status-badge { + padding: 2px 8px; + border-radius: 10px; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.role-badge { + padding: 2px 8px; + border-radius: 10px; + font-size: 10px; + font-weight: 600; +} + +.tag-pill { + padding: 2px 8px; + border-radius: 6px; + font-size: 10px; + background: var(--bg-card); + border: 1px solid var(--border); + color: var(--text-secondary); +} /* CALENDAR */ -.calendar-toolbar { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; } -.cal-nav { display: flex; align-items: center; gap: 12px; } -.cal-nav-btn { background: none; border: 1px solid var(--border-muted); color: var(--text-secondary); width: 32px; height: 32px; border-radius: 8px; cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; } -.cal-nav-btn:hover { border-color: var(--accent); color: var(--accent); } -.cal-month-label { font-size: 18px; font-weight: 700; min-width: 180px; text-align: center; } -.cal-today-btn { padding: 6px 14px; background: none; border: 1px solid var(--border-muted); color: var(--text-secondary); border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; } -.cal-today-btn:hover { border-color: var(--accent); color: var(--accent); } -.cal-view-toggle { display: flex; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; } -.cal-view-btn { padding: 6px 14px; background: none; border: none; color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; } -.cal-view-btn.active { background: var(--accent); color: #fff; } -.month-grid { display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; } -.month-grid-header { font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: #475569; text-align: center; padding: 8px; border-bottom: 1px solid var(--border); } -.day-cell { background: var(--bg-surface); border: 1px solid var(--border); min-height: 120px; padding: 4px; cursor: pointer; transition: background 0.15s; position: relative; } -.day-cell:hover { background: #0d1629; } -.day-number { font-size: 13px; padding: 4px 8px; color: var(--text-secondary); } -.day-number.today { background: var(--accent); color: #fff; font-weight: 700; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; padding: 0; } -.day-number.other-month { color: var(--border); } -.day-tasks { display: flex; flex-direction: column; gap: 3px; padding: 2px 4px; } +.calendar-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; +} + +.cal-nav { + display: flex; + align-items: center; + gap: 12px; +} + +.cal-nav-btn { + background: none; + border: 1px solid var(--border-muted); + color: var(--text-secondary); + width: 32px; + height: 32px; + border-radius: 8px; + cursor: pointer; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.15s; +} + +.cal-nav-btn:hover { + border-color: var(--accent); + color: var(--accent); +} + +.cal-month-label { + font-size: 18px; + font-weight: 700; + min-width: 180px; + text-align: center; +} + +.cal-today-btn { + padding: 6px 14px; + background: none; + border: 1px solid var(--border-muted); + color: var(--text-secondary); + border-radius: 8px; + font-size: 12px; + font-weight: 600; + cursor: pointer; + font-family: inherit; + transition: all 0.15s; +} + +.cal-today-btn:hover { + border-color: var(--accent); + color: var(--accent); +} + +.cal-view-toggle { + display: flex; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; +} + +.cal-view-btn { + padding: 6px 14px; + background: none; + border: none; + color: var(--text-muted); + font-size: 12px; + font-weight: 600; + cursor: pointer; + font-family: inherit; + transition: all 0.15s; +} + +.cal-view-btn.active { + background: var(--accent); + color: #fff; +} + +.month-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + flex: 1; +} + +.month-grid-header { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.1em; + color: #475569; + text-align: center; + padding: 8px; + border-bottom: 1px solid var(--border); +} + +.day-cell { + background: var(--bg-surface); + border: 1px solid var(--border); + min-height: 120px; + padding: 4px; + cursor: pointer; + transition: background 0.15s; + position: relative; +} + +.day-cell:hover { + background: #0d1629; +} + +.day-number { + font-size: 13px; + padding: 4px 8px; + color: var(--text-secondary); +} + +.day-number.today { + background: var(--accent); + color: #fff; + font-weight: 700; + width: 26px; + height: 26px; + border-radius: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; +} + +.day-number.other-month { + color: var(--border); +} + +.day-tasks { + display: flex; + flex-direction: column; + gap: 3px; + padding: 2px 4px; +} /* TASK CHIP */ -.task-chip { height: 22px; border-radius: 4px; padding: 0 8px; display: flex; align-items: center; gap: 6px; cursor: pointer; transition: all 0.15s; animation: fadeIn 0.15s ease; border-left: 3px solid; } -.task-chip:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.4); filter: brightness(1.2); } -.task-chip-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; } -.task-chip-title { font-size: 11px; color: #e2e8f0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; } -.task-chip-avatar { width: 14px; height: 14px; font-size: 6px; flex-shrink: 0; } -.more-tasks-link { font-size: 11px; color: var(--accent); cursor: pointer; padding: 2px 8px; } -.more-tasks-link:hover { text-decoration: underline; } +.task-chip { + height: 22px; + border-radius: 4px; + padding: 0 8px; + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; + transition: all 0.15s; + animation: fadeIn 0.15s ease; + border-left: 3px solid; +} + +.task-chip:hover { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); + filter: brightness(1.2); +} + +.task-chip-dot { + width: 6px; + height: 6px; + border-radius: 50%; + flex-shrink: 0; +} + +.task-chip-title { + font-size: 11px; + color: #e2e8f0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; +} + +.task-chip-avatar { + width: 14px; + height: 14px; + font-size: 6px; + flex-shrink: 0; +} + +.more-tasks-link { + font-size: 11px; + color: var(--accent); + cursor: pointer; + padding: 2px 8px; +} + +.more-tasks-link:hover { + text-decoration: underline; +} /* QUICK ADD */ -.quick-add-panel { position: absolute; z-index: 200; background: var(--bg-card); border: 1px solid var(--border-muted); border-radius: 12px; padding: 16px; width: 320px; box-shadow: 0 12px 40px rgba(0,0,0,0.6); animation: fadeUp 0.15s ease; } -.quick-add-header { font-size: 12px; color: var(--text-muted); margin-bottom: 10px; } -.quick-add-close { position: absolute; top: 8px; right: 8px; background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; } -.quick-add-input { width: 100%; padding: 8px 10px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-size: 13px; font-family: inherit; outline: none; margin-bottom: 10px; } -.quick-add-row { display: flex; gap: 8px; margin-bottom: 10px; } -.quick-add-select { flex: 1; padding: 6px 8px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-size: 11px; font-family: inherit; } -.quick-add-actions { display: flex; align-items: center; gap: 10px; } -.quick-add-submit { padding: 6px 14px; background: var(--accent); color: #fff; border: none; border-radius: 6px; font-size: 12px; font-weight: 700; cursor: pointer; font-family: inherit; } -.quick-add-link { font-size: 11px; color: var(--accent); cursor: pointer; background: none; border: none; font-family: inherit; } +.quick-add-panel { + position: absolute; + z-index: 200; + background: var(--bg-card); + border: 1px solid var(--border-muted); + border-radius: 12px; + padding: 16px; + width: 320px; + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6); + animation: fadeUp 0.15s ease; +} + +.quick-add-header { + font-size: 12px; + color: var(--text-muted); + margin-bottom: 10px; +} + +.quick-add-close { + position: absolute; + top: 8px; + right: 8px; + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + font-size: 16px; +} + +.quick-add-input { + width: 100%; + padding: 8px 10px; + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-primary); + font-size: 13px; + font-family: inherit; + outline: none; + margin-bottom: 10px; +} + +.quick-add-row { + display: flex; + gap: 8px; + margin-bottom: 10px; +} + +.quick-add-select { + flex: 1; + padding: 6px 8px; + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-primary); + font-size: 11px; + font-family: inherit; +} + +.quick-add-actions { + display: flex; + align-items: center; + gap: 10px; +} + +.quick-add-submit { + padding: 6px 14px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 6px; + font-size: 12px; + font-weight: 700; + cursor: pointer; + font-family: inherit; +} + +.quick-add-link { + font-size: 11px; + color: var(--accent); + cursor: pointer; + background: none; + border: none; + font-family: inherit; +} /* WEEK VIEW */ -.week-grid { display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; } -.week-header-cell { text-align: center; padding: 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: #475569; border-bottom: 1px solid var(--border); } -.week-header-cell.today { background: var(--accent); color: #fff; border-radius: 8px 8px 0 0; } -.week-day-cell { background: var(--bg-surface); border: 1px solid var(--border); min-height: 200px; padding: 8px; cursor: pointer; transition: background 0.15s; position: relative; } -.week-day-cell:hover { background: #0d1629; } -.week-chip { height: 28px; border-radius: 4px; padding: 4px 8px; display: flex; align-items: center; gap: 6px; cursor: pointer; transition: all 0.15s; border-left: 3px solid; margin-bottom: 4px; } +.week-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + flex: 1; +} + +.week-header-cell { + text-align: center; + padding: 8px; + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.1em; + color: #475569; + border-bottom: 1px solid var(--border); +} + +.week-header-cell.today { + background: var(--accent); + color: #fff; + border-radius: 8px 8px 0 0; +} + +.week-day-cell { + background: var(--bg-surface); + border: 1px solid var(--border); + min-height: 200px; + padding: 8px; + cursor: pointer; + transition: background 0.15s; + position: relative; +} + +.week-day-cell:hover { + background: #0d1629; +} + +.week-chip { + height: 28px; + border-radius: 4px; + padding: 4px 8px; + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; + transition: all 0.15s; + border-left: 3px solid; + margin-bottom: 4px; +} /* KANBAN */ -.kanban-board { display: flex; gap: 16px; padding: 16px 20px; flex: 1; overflow-x: auto; } -.kanban-column { flex: 1; min-width: 260px; background: var(--bg-surface); border-radius: 12px; border: 1px solid var(--border); display: flex; flex-direction: column; } -.kanban-col-header { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--border); } -.kanban-col-dot { width: 8px; height: 8px; border-radius: 50%; } -.kanban-col-label { font-size: 12px; font-weight: 700; text-transform: uppercase; flex: 1; } -.kanban-col-count { font-size: 11px; color: var(--text-muted); background: var(--bg-card); padding: 1px 8px; border-radius: 10px; } -.kanban-col-add { background: none; border: 1px solid var(--border); color: var(--text-muted); width: 24px; height: 24px; border-radius: 6px; cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; } -.kanban-col-add:hover { border-color: var(--accent); color: var(--accent); } -.kanban-col-body { padding: 10px; flex: 1; overflow-y: auto; } -.kanban-empty { border: 1px dashed var(--border-muted); border-radius: 8px; padding: 20px; text-align: center; color: var(--text-muted); font-size: 12px; } +.kanban-board { + display: flex; + gap: 16px; + padding: 16px 20px; + flex: 1; + overflow-x: auto; +} + +.kanban-column { + flex: 1; + min-width: 260px; + background: var(--bg-surface); + border-radius: 12px; + border: 1px solid var(--border); + display: flex; + flex-direction: column; +} + +.kanban-col-header { + display: flex; + align-items: center; + gap: 8px; + padding: 14px 16px; + border-bottom: 1px solid var(--border); +} + +.kanban-col-dot { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.kanban-col-label { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + flex: 1; +} + +.kanban-col-count { + font-size: 11px; + color: var(--text-muted); + background: var(--bg-card); + padding: 1px 8px; + border-radius: 10px; +} + +.kanban-col-add { + background: none; + border: 1px solid var(--border); + color: var(--text-muted); + width: 24px; + height: 24px; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.15s; +} + +.kanban-col-add:hover { + border-color: var(--accent); + color: var(--accent); +} + +.kanban-col-body { + padding: 10px; + flex: 1; + overflow-y: auto; +} + +.kanban-empty { + border: 1px dashed var(--border-muted); + border-radius: 8px; + padding: 20px; + text-align: center; + color: var(--text-muted); + font-size: 12px; +} /* TASK CARD */ -.task-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; margin-bottom: 10px; cursor: pointer; transition: all 0.15s; border-left: 3px solid; } -.task-card:hover { background: var(--border); transform: translateY(-1px); box-shadow: 0 6px 24px rgba(0,0,0,0.4); } -.task-card-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } -.task-card-title { font-size: 13px; font-weight: 600; color: #e2e8f0; flex: 1; } -.task-card-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; } -.task-card-meta { display: flex; align-items: center; gap: 10px; font-size: 11px; color: var(--text-muted); } -.task-card-overdue { color: var(--critical); } -.progress-bar-wrap { margin-bottom: 4px; } -.progress-bar-text { font-size: 10px; color: var(--text-muted); margin-bottom: 2px; } -.progress-bar { height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; } -.progress-bar-fill { height: 100%; border-radius: 2px; transition: width 0.3s; } +.task-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 10px; + padding: 14px 16px; + margin-bottom: 10px; + cursor: pointer; + transition: all 0.15s; + border-left: 3px solid; +} + +.task-card:hover { + background: var(--border); + transform: translateY(-1px); + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4); +} + +.task-card-row { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 6px; +} + +.task-card-title { + font-size: 13px; + font-weight: 600; + color: #e2e8f0; + flex: 1; +} + +.task-card-badges { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-bottom: 6px; +} + +.task-card-meta { + display: flex; + align-items: center; + gap: 10px; + font-size: 11px; + color: var(--text-muted); +} + +.task-card-overdue { + color: var(--critical); +} + +.progress-bar-wrap { + margin-bottom: 4px; +} + +.progress-bar-text { + font-size: 10px; + color: var(--text-muted); + margin-bottom: 2px; +} + +.progress-bar { + height: 4px; + background: var(--border); + border-radius: 2px; + overflow: hidden; +} + +.progress-bar-fill { + height: 100%; + border-radius: 2px; + transition: width 0.3s; +} /* LIST VIEW */ -.list-view { padding: 16px 20px; } -.list-sort-row { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; font-size: 12px; color: var(--text-muted); } -.list-sort-btn { padding: 4px 10px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; color: var(--text-muted); font-size: 11px; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; } -.list-sort-btn.active { border-color: var(--accent); color: var(--accent); } -.list-table { width: 100%; border-collapse: collapse; } -.list-table th { background: var(--bg-card); border-bottom: 1px solid var(--border); padding: 10px 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); text-align: left; position: sticky; top: 0; } -.list-table td { padding: 10px 12px; font-size: 13px; border-bottom: 1px solid var(--border); } -.list-table tr:nth-child(odd) td { background: var(--bg-surface); } -.list-table tr:nth-child(even) td { background: #0d1120; } -.list-table tr:hover td { background: var(--border) !important; cursor: pointer; } -.list-actions-btn { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; position: relative; } -.list-dropdown { position: absolute; right: 0; top: 100%; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 4px; min-width: 120px; z-index: 100; box-shadow: 0 8px 24px rgba(0,0,0,0.4); } -.list-dropdown-item { display: block; width: 100%; padding: 6px 12px; background: none; border: none; color: var(--text-secondary); font-size: 12px; text-align: left; cursor: pointer; border-radius: 4px; font-family: inherit; } -.list-dropdown-item:hover { background: var(--accent-bg); color: var(--accent); } +.list-view { + padding: 16px 20px; +} + +.list-sort-row { + display: flex; + gap: 8px; + margin-bottom: 12px; + align-items: center; + font-size: 12px; + color: var(--text-muted); +} + +.list-sort-btn { + padding: 4px 10px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-muted); + font-size: 11px; + font-weight: 600; + cursor: pointer; + font-family: inherit; + transition: all 0.15s; +} + +.list-sort-btn.active { + border-color: var(--accent); + color: var(--accent); +} + +.list-table { + width: 100%; + border-collapse: collapse; +} + +.list-table th { + background: var(--bg-card); + border-bottom: 1px solid var(--border); + padding: 10px 12px; + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + color: var(--text-muted); + text-align: left; + position: sticky; + top: 0; +} + +.list-table td { + padding: 10px 12px; + font-size: 13px; + border-bottom: 1px solid var(--border); +} + +.list-table tr:nth-child(odd) td { + background: var(--bg-surface); +} + +.list-table tr:nth-child(even) td { + background: #0d1120; +} + +.list-table tr:hover td { + background: var(--border) !important; + cursor: pointer; +} + +.list-actions-btn { + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + font-size: 16px; + position: relative; +} + +.list-dropdown { + position: absolute; + right: 0; + top: 100%; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + padding: 4px; + min-width: 120px; + z-index: 100; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); +} + +.list-dropdown-item { + display: block; + width: 100%; + padding: 6px 12px; + background: none; + border: none; + color: var(--text-secondary); + font-size: 12px; + text-align: left; + cursor: pointer; + border-radius: 4px; + font-family: inherit; +} + +.list-dropdown-item:hover { + background: var(--accent-bg); + color: var(--accent); +} /* DRAWER */ -.drawer-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.5); backdrop-filter: blur(4px); z-index: 100; animation: fadeIn 0.15s; } -.drawer { position: fixed; right: 0; top: 0; bottom: 0; width: 520px; background: var(--bg-surface); border-left: 1px solid var(--border); z-index: 101; animation: slideIn 0.2s ease; overflow-y: auto; display: flex; flex-direction: column; } -.drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border); } -.drawer-header-label { font-size: 11px; text-transform: uppercase; color: var(--text-muted); letter-spacing: 0.05em; } -.drawer-close { background: var(--border); border: none; color: var(--text-secondary); width: 28px; height: 28px; border-radius: 6px; cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; } -.drawer-body { padding: 20px; flex: 1; } -.drawer-title { font-size: 18px; font-weight: 700; margin-bottom: 6px; } -.drawer-desc { font-size: 13px; color: var(--text-muted); line-height: 1.6; margin-bottom: 16px; } -.drawer-meta { background: var(--bg-card); border-radius: 10px; padding: 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; } -.drawer-meta-label { font-size: 10px; text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px; } -.drawer-meta-val { font-size: 13px; display: flex; align-items: center; gap: 6px; } -.drawer-select { padding: 4px 8px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-family: inherit; } -.drawer-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; } -.drawer-section { margin-bottom: 20px; } -.drawer-section-title { font-size: 13px; font-weight: 700; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; } -.subtask-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; cursor: pointer; transition: background 0.15s; border-radius: 4px; } -.subtask-row:hover { background: rgba(255,255,255,0.03); } -.subtask-checkbox { width: 16px; height: 16px; border: 1.5px solid var(--border-muted); border-radius: 4px; cursor: pointer; accent-color: var(--status-done); } -.subtask-text { font-size: 13px; } -.subtask-text.done { text-decoration: line-through; color: var(--text-muted); } -.subtask-add { display: flex; gap: 8px; margin-top: 8px; } -.subtask-add input { flex: 1; padding: 6px 10px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-family: inherit; outline: none; } -.subtask-add button { padding: 6px 12px; background: var(--accent); color: #fff; border: none; border-radius: 6px; font-size: 11px; font-weight: 700; cursor: pointer; font-family: inherit; } -.comment-item { display: flex; gap: 10px; margin-bottom: 14px; } -.comment-bubble { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; flex: 1; } -.comment-header { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; } -.comment-name { font-size: 12px; font-weight: 700; } -.comment-time { font-size: 10px; color: var(--text-muted); } -.comment-text { font-size: 12px; color: var(--text-secondary); } -.comment-input-row { display: flex; gap: 8px; align-items: center; } -.comment-input-row input { flex: 1; padding: 8px 10px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-family: inherit; outline: none; } -.comment-input-row button { padding: 8px 14px; background: var(--accent); color: #fff; border: none; border-radius: 6px; font-size: 12px; font-weight: 700; cursor: pointer; font-family: inherit; } -.activity-item { display: flex; gap: 10px; position: relative; padding-left: 16px; margin-bottom: 10px; } -.activity-item::before { content: ''; position: absolute; left: 3px; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--border-muted); } -.activity-item::after { content: ''; position: absolute; left: 5px; top: 16px; width: 2px; height: calc(100% + 4px); background: var(--border); } -.activity-item:last-child::after { display: none; } -.activity-text { font-size: 11px; color: #475569; } +.drawer-backdrop { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(4px); + z-index: 100; + animation: fadeIn 0.15s; +} + +.drawer { + position: fixed; + right: 0; + top: 0; + bottom: 0; + width: 520px; + background: var(--bg-surface); + border-left: 1px solid var(--border); + z-index: 101; + animation: slideIn 0.2s ease; + overflow-y: auto; + display: flex; + flex-direction: column; +} + +.drawer-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + border-bottom: 1px solid var(--border); +} + +.drawer-header-label { + font-size: 11px; + text-transform: uppercase; + color: var(--text-muted); + letter-spacing: 0.05em; +} + +.drawer-close { + background: var(--border); + border: none; + color: var(--text-secondary); + width: 28px; + height: 28px; + border-radius: 6px; + cursor: pointer; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; +} + +.drawer-body { + padding: 20px; + flex: 1; +} + +.drawer-title { + font-size: 18px; + font-weight: 700; + margin-bottom: 6px; +} + +.drawer-desc { + font-size: 13px; + color: var(--text-muted); + line-height: 1.6; + margin-bottom: 16px; +} + +.drawer-meta { + background: var(--bg-card); + border-radius: 10px; + padding: 16px; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 14px; + margin-bottom: 16px; +} + +.drawer-meta-label { + font-size: 10px; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 4px; +} + +.drawer-meta-val { + font-size: 13px; + display: flex; + align-items: center; + gap: 6px; +} + +.drawer-select { + padding: 4px 8px; + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-primary); + font-size: 12px; + font-family: inherit; +} + +.drawer-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 16px; +} + +.drawer-section { + margin-bottom: 20px; +} + +.drawer-section-title { + font-size: 13px; + font-weight: 700; + margin-bottom: 10px; + display: flex; + align-items: center; + gap: 8px; +} + +.subtask-row { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 0; + cursor: pointer; + transition: background 0.15s; + border-radius: 4px; +} + +.subtask-row:hover { + background: rgba(255, 255, 255, 0.03); +} + +.subtask-checkbox { + width: 16px; + height: 16px; + border: 1.5px solid var(--border-muted); + border-radius: 4px; + cursor: pointer; + accent-color: var(--status-done); +} + +.subtask-text { + font-size: 13px; +} + +.subtask-text.done { + text-decoration: line-through; + color: var(--text-muted); +} + +.subtask-add { + display: flex; + gap: 8px; + margin-top: 8px; +} + +.subtask-add input { + flex: 1; + padding: 6px 10px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-primary); + font-size: 12px; + font-family: inherit; + outline: none; +} + +.subtask-add button { + padding: 6px 12px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 6px; + font-size: 11px; + font-weight: 700; + cursor: pointer; + font-family: inherit; +} + +.comment-item { + display: flex; + gap: 10px; + margin-bottom: 14px; +} + +.comment-bubble { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + padding: 8px 12px; + flex: 1; +} + +.comment-header { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 4px; +} + +.comment-name { + font-size: 12px; + font-weight: 700; +} + +.comment-time { + font-size: 10px; + color: var(--text-muted); +} + +.comment-text { + font-size: 12px; + color: var(--text-secondary); +} + +.comment-input-row { + display: flex; + gap: 8px; + align-items: center; +} + +.comment-input-row input { + flex: 1; + padding: 8px 10px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 6px; + color: var(--text-primary); + font-size: 12px; + font-family: inherit; + outline: none; +} + +.comment-input-row button { + padding: 8px 14px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 6px; + font-size: 12px; + font-weight: 700; + cursor: pointer; + font-family: inherit; +} + +.activity-item { + display: flex; + gap: 10px; + position: relative; + padding-left: 16px; + margin-bottom: 10px; +} + +.activity-item::before { + content: ''; + position: absolute; + left: 3px; + top: 8px; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--border-muted); +} + +.activity-item::after { + content: ''; + position: absolute; + left: 5px; + top: 16px; + width: 2px; + height: calc(100% + 4px); + background: var(--border); +} + +.activity-item:last-child::after { + display: none; +} + +.activity-text { + font-size: 11px; + color: #475569; +} /* MODAL */ -.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.6); backdrop-filter: blur(4px); z-index: 200; display: flex; align-items: center; justify-content: center; animation: fadeIn 0.15s; } -.modal { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 16px; width: 480px; max-height: 90vh; overflow-y: auto; animation: fadeUp 0.2s ease; } -.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--border); } -.modal-header h2 { font-size: 16px; font-weight: 700; } -.modal-body { padding: 24px; } -.modal-field { margin-bottom: 14px; } -.modal-field label { font-size: 12px; font-weight: 600; color: var(--text-secondary); display: block; margin-bottom: 4px; } -.modal-input { width: 100%; padding: 8px 12px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; color: var(--text-primary); font-size: 13px; font-family: inherit; outline: none; } -.modal-input:focus { border-color: var(--accent); } -.modal-input.error { border-color: var(--critical); } -.modal-input-textarea { resize: vertical; min-height: 60px; } -.modal-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; } -.modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 24px; border-top: 1px solid var(--border); } -.btn-ghost { padding: 8px 18px; background: none; border: 1px solid var(--border); border-radius: 8px; color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit; transition: all 0.15s; } -.btn-ghost:hover { border-color: var(--text-muted); } -.btn-primary { padding: 8px 18px; background: var(--accent); border: none; border-radius: 8px; color: #fff; font-size: 13px; font-weight: 700; cursor: pointer; font-family: inherit; box-shadow: 0 0 16px var(--accent-glow); transition: background 0.15s; } -.btn-primary:hover { background: var(--accent-hover); } +.modal-backdrop { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(4px); + z-index: 200; + display: flex; + align-items: center; + justify-content: center; + animation: fadeIn 0.15s; +} + +.modal { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 16px; + width: 480px; + max-height: 90vh; + overflow-y: auto; + animation: fadeUp 0.2s ease; +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + border-bottom: 1px solid var(--border); +} + +.modal-header h2 { + font-size: 16px; + font-weight: 700; +} + +.modal-body { + padding: 24px; +} + +.modal-field { + margin-bottom: 14px; +} + +.modal-field label { + font-size: 12px; + font-weight: 600; + color: var(--text-secondary); + display: block; + margin-bottom: 4px; +} + +.modal-input { + width: 100%; + padding: 8px 12px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 13px; + font-family: inherit; + outline: none; +} + +.modal-input:focus { + border-color: var(--accent); +} + +.modal-input.error { + border-color: var(--critical); +} + +.modal-input-textarea { + resize: vertical; + min-height: 60px; +} + +.modal-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 14px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; + padding: 16px 24px; + border-top: 1px solid var(--border); +} + +.btn-ghost { + padding: 8px 18px; + background: none; + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-secondary); + font-size: 13px; + font-weight: 600; + cursor: pointer; + font-family: inherit; + transition: all 0.15s; +} + +.btn-ghost:hover { + border-color: var(--text-muted); +} + +.btn-primary { + padding: 8px 18px; + background: var(--accent); + border: none; + border-radius: 8px; + color: #fff; + font-size: 13px; + font-weight: 700; + cursor: pointer; + font-family: inherit; + box-shadow: 0 0 16px var(--accent-glow); + transition: background 0.15s; +} + +.btn-primary:hover { + background: var(--accent-hover); +} /* DASHBOARD */ -.dashboard { padding: 20px; } -.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; } -.stat-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 12px; padding: 20px; } -.stat-card-num { font-size: 32px; font-weight: 800; } -.stat-card-label { font-size: 11px; text-transform: uppercase; color: var(--text-muted); margin-top: 4px; } -.workload-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 12px; padding: 20px; margin-bottom: 16px; } -.workload-card-title { font-size: 14px; font-weight: 700; margin-bottom: 16px; } -.workload-row { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); } -.workload-row:last-child { border-bottom: none; } -.workload-name { font-size: 13px; font-weight: 600; min-width: 120px; } -.workload-dept { font-size: 11px; color: var(--text-muted); min-width: 80px; } -.workload-bar { flex: 1; } -.workload-badges { display: flex; gap: 4px; } -.priority-bar-wrap { margin-bottom: 8px; } -.priority-bar { height: 24px; border-radius: 6px; display: flex; overflow: hidden; } -.priority-segment { display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; color: #fff; } -.deadline-item { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); } -.deadline-item.overdue { background: rgba(239,68,68,0.08); border-radius: 6px; padding: 8px; } -.progress-ring { margin: 20px auto; display: block; } +.dashboard { + padding: 20px; +} + +.stats-row { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; + margin-bottom: 24px; +} + +.stat-card { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 12px; + padding: 20px; +} + +.stat-card-num { + font-size: 32px; + font-weight: 800; +} + +.stat-card-label { + font-size: 11px; + text-transform: uppercase; + color: var(--text-muted); + margin-top: 4px; +} + +.workload-card { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 12px; + padding: 20px; + margin-bottom: 16px; +} + +.workload-card-title { + font-size: 14px; + font-weight: 700; + margin-bottom: 16px; +} + +.workload-row { + display: flex; + align-items: center; + gap: 12px; + padding: 8px 0; + border-bottom: 1px solid var(--border); +} + +.workload-row:last-child { + border-bottom: none; +} + +.workload-name { + font-size: 13px; + font-weight: 600; + min-width: 120px; +} + +.workload-dept { + font-size: 11px; + color: var(--text-muted); + min-width: 80px; +} + +.workload-bar { + flex: 1; +} + +.workload-badges { + display: flex; + gap: 4px; +} + +.priority-bar-wrap { + margin-bottom: 8px; +} + +.priority-bar { + height: 24px; + border-radius: 6px; + display: flex; + overflow: hidden; +} + +.priority-segment { + display: flex; + align-items: center; + justify-content: center; + font-size: 10px; + font-weight: 700; + color: #fff; +} + +.deadline-item { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 0; + border-bottom: 1px solid var(--border); +} + +.deadline-item.overdue { + background: rgba(239, 68, 68, 0.08); + border-radius: 6px; + padding: 8px; +} + +.progress-ring { + margin: 20px auto; + display: block; +} /* TEAM TASKS */ -.team-tasks { padding: 20px; } -.team-group { margin-bottom: 16px; } -.team-group-header { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: 8px; cursor: pointer; transition: background 0.15s; } -.team-group-header:hover { background: var(--bg-card); } -.team-group-name { font-size: 14px; font-weight: 600; flex: 1; } -.team-group-count { font-size: 12px; color: var(--text-muted); } -.team-group-tasks { padding: 8px 0 8px 42px; } -.team-task-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; } -.team-task-title { font-size: 13px; flex: 1; } +.team-tasks { + padding: 20px; +} + +.team-group { + margin-bottom: 16px; +} + +.team-group-header { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 12px; + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 8px; + cursor: pointer; + transition: background 0.15s; +} + +.team-group-header:hover { + background: var(--bg-card); +} + +.team-group-name { + font-size: 14px; + font-weight: 600; + flex: 1; +} + +.team-group-count { + font-size: 12px; + color: var(--text-muted); +} + +.team-group-tasks { + padding: 8px 0 8px 42px; +} + +.team-task-row { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 0; +} + +.team-task-title { + font-size: 13px; + flex: 1; +} /* REPORTS */ -.reports { padding: 20px; } -.charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } -.chart-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 12px; padding: 20px; } -.chart-card-title { font-size: 14px; font-weight: 700; margin-bottom: 16px; } +.reports { + padding: 20px; +} -/* MEMBERS */ -.members-page { padding: 20px; } -.members-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; } -.members-header h2 { font-size: 18px; font-weight: 700; } -.members-table { width: 100%; border-collapse: collapse; } -.members-table th { background: var(--bg-card); border-bottom: 1px solid var(--border); padding: 10px 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); text-align: left; } -.members-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); font-size: 13px; } -.members-table tr:hover td { background: var(--bg-card); cursor: pointer; } -.member-expand { padding: 12px 16px; background: var(--bg-card); } -.invite-modal { width: 380px; } +.charts-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; +} + +.chart-card { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 12px; + padding: 20px; +} + +.chart-card-title { + font-size: 14px; + font-weight: 700; + margin-bottom: 16px; +} + +/* MEMBERS / USER MANAGEMENT */ +.members-page { + padding: 20px; +} + +.members-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; +} + +.members-header h2 { + font-size: 18px; + font-weight: 700; + margin: 0; +} + +/* Department overview chips */ +.dept-overview { + display: flex; + gap: 8px; + margin-bottom: 16px; + flex-wrap: wrap; +} + +.dept-chip { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 14px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 10px; + cursor: pointer; + transition: all 0.15s; + font-size: 12px; + color: #e2e8f0; +} + +.dept-chip:hover { + border-color: var(--accent); + background: rgba(99, 102, 241, 0.04); +} + +.dept-chip.active { + border-color: var(--accent); + background: rgba(99, 102, 241, 0.08); + color: var(--accent); +} + +.dept-chip-count { + background: var(--bg-surface); + padding: 1px 7px; + border-radius: 10px; + font-size: 10px; + font-weight: 700; + color: var(--accent); +} + +/* Toolbar */ +.members-toolbar { + display: flex; + gap: 10px; + margin-bottom: 16px; + align-items: center; +} + +.members-search { + display: flex; + align-items: center; + gap: 6px; + flex: 1; + max-width: 320px; + padding: 6px 12px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + font-size: 12px; +} + +.members-search input { + background: none; + border: none; + color: #e2e8f0; + outline: none; + width: 100%; + font-size: 12px; +} + +.members-filter-select { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + padding: 6px 10px; + font-size: 12px; + color: #e2e8f0; + cursor: pointer; +} + +.view-toggle { + display: flex; + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; +} + +.view-toggle button { + background: var(--bg-card); + border: none; + padding: 6px 10px; + color: #64748b; + cursor: pointer; + font-size: 14px; + transition: all 0.15s; +} + +.view-toggle button.active { + background: var(--accent); + color: white; +} + +/* Table */ +.members-table { + width: 100%; + border-collapse: collapse; +} + +.members-table th { + background: var(--bg-card); + border-bottom: 1px solid var(--border); + padding: 10px 12px; + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + color: var(--text-muted); + text-align: left; +} + +.members-table td { + padding: 10px 12px; + border-bottom: 1px solid var(--border); + font-size: 13px; +} + +.members-table tr:hover td { + background: var(--bg-card); + cursor: pointer; +} + +/* Inline select for role/dept editing */ +.inline-select { + background: transparent; + border: 1px solid var(--border); + border-radius: 6px; + padding: 2px 6px; + font-size: 11px; + font-weight: 600; + cursor: pointer; + color: inherit; + outline: none; + transition: border-color 0.15s; +} + +.inline-select:hover { + border-color: var(--accent); +} + +.inline-select:focus { + border-color: var(--accent); + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.15); +} + +/* Action icon buttons */ +.action-icon-btn { + background: none; + border: 1px solid transparent; + border-radius: 6px; + padding: 4px 6px; + cursor: pointer; + font-size: 12px; + transition: all 0.15s; + color: #94a3b8; +} + +.action-icon-btn:hover { + background: var(--bg-card); + border-color: var(--border); +} + +/* Status dots */ +.status-dot { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 10px; + font-weight: 600; +} + +.status-dot::before { + content: ''; + width: 6px; + height: 6px; + border-radius: 50%; +} + +.status-dot-active { + color: #22c55e; +} + +.status-dot-active::before { + background: #22c55e; +} + +.status-dot-inactive { + color: #ef4444; +} + +.status-dot-inactive::before { + background: #ef4444; +} + +/* Expanded row */ +.member-expand { + padding: 12px 16px; + background: var(--bg-card); + border-radius: 8px; +} + +.member-expand-header { + display: flex; + gap: 24px; + margin-bottom: 12px; + padding-bottom: 12px; + border-bottom: 1px solid var(--border); +} + +.member-expand-stat { + display: flex; + flex-direction: column; + align-items: center; +} + +.stat-num { + font-size: 18px; + font-weight: 800; +} + +.stat-label { + font-size: 10px; + color: #64748b; + text-transform: uppercase; + font-weight: 600; +} + +/* Grid view */ +.members-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 14px; +} + +.member-card { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: 12px; + padding: 16px; + transition: all 0.15s; +} + +.member-card:hover { + border-color: var(--accent); + box-shadow: 0 0 12px rgba(99, 102, 241, 0.06); +} + +.member-card-inactive { + opacity: 0.5; +} + +.member-card-top { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; +} + +.member-card-badges { + display: flex; + gap: 6px; + flex-wrap: wrap; + margin-bottom: 12px; +} + +.member-card-stats { + display: flex; + justify-content: space-around; + padding: 10px 0; + margin-bottom: 10px; + border-top: 1px solid var(--border); + font-size: 12px; + color: #94a3b8; +} + +.member-card-actions { + display: flex; + gap: 6px; + padding-top: 10px; + border-top: 1px solid var(--border); +} + +/* Danger button */ +.btn-danger { + background: #ef4444; + color: white; + border: none; + border-radius: 8px; + padding: 8px 16px; + font-size: 12px; + font-weight: 600; + cursor: pointer; + transition: all 0.15s; +} + +.btn-danger:hover { + background: #dc2626; +} + +/* Modal grid (side by side fields) */ +.modal-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +/* Error states */ +.modal-input.error { + border-color: #ef4444; + box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.15); +} + +/* Role badge */ +.role-badge { + padding: 2px 8px; + border-radius: 10px; + font-size: 10px; + font-weight: 700; +} /* MORE TASKS POPOVER */ -.more-popover { position: absolute; z-index: 150; background: var(--bg-card); border: 1px solid var(--border-muted); border-radius: 10px; padding: 10px; width: 260px; box-shadow: 0 8px 32px rgba(0,0,0,0.5); animation: fadeUp 0.15s ease; } -.more-popover-title { font-size: 11px; color: var(--text-muted); margin-bottom: 8px; font-weight: 600; } +.more-popover { + position: absolute; + z-index: 150; + background: var(--bg-card); + border: 1px solid var(--border-muted); + border-radius: 10px; + padding: 10px; + width: 260px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + animation: fadeUp 0.15s ease; +} + +.more-popover-title { + font-size: 11px; + color: var(--text-muted); + margin-bottom: 8px; + font-weight: 600; +} \ No newline at end of file