Files
KeepItGoingServer/static/css/app.css
T
Keith SmithandClaude Sonnet 4.5 f836769ad7 CRITICAL FIX: Move base CSS before media queries
The sidebar-toggle and mobile-overlay base definitions were placed
AFTER the media queries, causing them to override the responsive
styles. This prevented the hamburger menu from showing and broke
the sidebar drawer functionality.

Fixed by moving base definitions before the Mobile Responsive section.

CSS order is now correct:
1. Base styles (display: none for sidebar-toggle)
2. Media queries (display: flex at 768px)

This allows the media query to properly override the base style.

Updated cache version to v=4.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 21:18:14 -07:00

1166 lines
24 KiB
CSS

/* KeepItGoing - Material Design Stylesheet */
/* Matches desktop QML Theme.qml */
/* ============================================
CSS Variables (Theme)
============================================ */
:root {
/* Light theme colors (default) */
--bg: #ffffff;
--surface: #f9fafb;
--surface-hover: #f3f4f6;
--surface-selected: #dbeafe;
--text-primary: #111827;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--text-on-accent: #ffffff;
--border: #e5e7eb;
--border-light: #f3f4f6;
/* Brand/Accent */
--accent: #3b82f6;
--accent-hover: #2563eb;
--accent-pressed: #1d4ed8;
--accent-light: #dbeafe;
/* Semantic */
--success: #10b981;
--success-hover: #059669;
--warning: #f59e0b;
--warning-hover: #d97706;
--danger: #ef4444;
--danger-hover: #dc2626;
/* Priority colors */
--priority-urgent: #ef4444;
--priority-high: #f59e0b;
--priority-medium: #3b82f6;
--priority-low: #6b7280;
/* Spacing */
--space-xs: 4px;
--space-sm: 8px;
--space-md: 12px;
--space-lg: 16px;
--space-xl: 24px;
--space-xxl: 32px;
/* Border radius */
--radius-xs: 2px;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Font sizes */
--font-xs: 10px;
--font-sm: 12px;
--font-md: 14px;
--font-lg: 16px;
--font-xl: 18px;
--font-xxl: 20px;
--font-title: 24px;
/* Layout sizes */
--sidebar-width: 220px;
--detail-panel-width: 350px;
--header-height: 56px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
/* Transitions */
--anim-fast: 100ms;
--anim-normal: 150ms;
--anim-slow: 250ms;
}
/* Dark theme */
[data-theme="dark"] {
--bg: #1f2937;
--surface: #374151;
--surface-hover: #4b5563;
--surface-selected: #1e40af;
--text-primary: #f9fafb;
--text-secondary: #9ca3af;
--text-muted: #6b7280;
--border: #4b5563;
--border-light: #374151;
--accent-light: #1e3a5f;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
}
/* ============================================
Reset & Base
============================================ */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
font-size: var(--font-md);
line-height: 1.5;
color: var(--text-primary);
background-color: var(--bg);
}
a {
color: var(--accent);
text-decoration: none;
transition: color var(--anim-fast);
}
a:hover {
color: var(--accent-hover);
}
/* ============================================
App Layout (3-pane)
============================================ */
.app-layout {
display: grid;
grid-template-rows: var(--header-height) 1fr;
grid-template-columns: var(--sidebar-width) 1fr var(--detail-panel-width);
height: 100vh;
overflow: hidden;
}
.app-layout.detail-closed {
grid-template-columns: var(--sidebar-width) 1fr 0;
}
/* Header spans full width */
.app-header {
grid-column: 1 / -1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--space-lg);
background-color: var(--surface);
border-bottom: 1px solid var(--border);
z-index: 100;
}
.app-brand {
font-size: var(--font-xl);
font-weight: 700;
color: var(--accent);
}
.app-header-actions {
display: flex;
align-items: center;
gap: var(--space-md);
}
.header-user {
display: flex;
align-items: center;
gap: var(--space-sm);
color: var(--text-secondary);
font-size: var(--font-sm);
}
/* Theme toggle button */
.theme-toggle {
background: none;
border: none;
padding: var(--space-sm);
cursor: pointer;
color: var(--text-secondary);
border-radius: var(--radius-sm);
transition: background-color var(--anim-fast), color var(--anim-fast);
}
.theme-toggle:hover {
background-color: var(--surface-hover);
color: var(--text-primary);
}
.theme-toggle svg {
width: 20px;
height: 20px;
}
/* ============================================
Sidebar
============================================ */
.app-sidebar {
background-color: var(--surface);
border-right: 1px solid var(--border);
padding: var(--space-lg);
overflow-y: auto;
}
.sidebar-section {
margin-bottom: var(--space-xl);
}
.sidebar-section-title {
font-size: var(--font-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-bottom: var(--space-sm);
}
.sidebar-nav {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.sidebar-item {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-md);
border-radius: var(--radius-sm);
color: var(--text-secondary);
font-size: var(--font-md);
cursor: pointer;
transition: background-color var(--anim-fast), color var(--anim-fast);
}
.sidebar-item:hover {
background-color: var(--surface-hover);
color: var(--text-primary);
}
.sidebar-item.active {
background-color: var(--accent-light);
color: var(--accent);
font-weight: 500;
}
.sidebar-item-icon {
width: 16px;
height: 16px;
opacity: 0.7;
}
.sidebar-item-count {
margin-left: auto;
font-size: var(--font-xs);
color: var(--text-muted);
background-color: var(--border-light);
padding: 2px 6px;
border-radius: 10px;
}
/* Group items with color indicator */
.sidebar-group-item {
display: flex;
align-items: center;
gap: var(--space-sm);
}
.group-color-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
/* Group row with edit button */
.sidebar-group-row {
display: flex;
align-items: center;
gap: var(--space-xs);
}
.sidebar-group-row .sidebar-group-item {
flex: 1;
min-width: 0;
}
.sidebar-group-edit {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: var(--space-xs);
color: var(--text-muted);
background: none;
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
transition: background-color var(--anim-fast), color var(--anim-fast);
flex-shrink: 0;
}
.sidebar-group-edit:hover {
background-color: var(--surface-hover);
color: var(--accent);
}
.sidebar-group-edit svg {
width: 14px;
height: 14px;
}
.sidebar-add-btn {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-md);
color: var(--text-muted);
font-size: var(--font-sm);
font-family: inherit;
cursor: pointer;
border: none;
background: none;
border-radius: var(--radius-sm);
transition: background-color var(--anim-fast), color var(--anim-fast);
width: 100%;
text-align: left;
}
.sidebar-add-btn:hover {
background-color: var(--surface-hover);
color: var(--accent);
}
/* ============================================
Task List (center pane)
============================================ */
.task-pane {
background-color: var(--bg);
padding: var(--space-lg);
overflow-y: auto;
}
.task-pane-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-lg);
}
.task-pane-title {
font-size: var(--font-xxl);
font-weight: 700;
color: var(--text-primary);
}
.task-count {
font-size: var(--font-md);
color: var(--text-secondary);
}
/* Quick Add */
.quick-add {
display: flex;
gap: var(--space-sm);
margin-bottom: var(--space-lg);
}
.quick-add-input {
flex: 1;
padding: var(--space-sm) var(--space-md);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
font-size: var(--font-md);
background-color: var(--surface);
color: var(--text-primary);
transition: border-color var(--anim-fast), box-shadow var(--anim-fast);
}
.quick-add-input::placeholder {
color: var(--text-muted);
}
.quick-add-input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Task List */
.task-list {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
/* Task Item */
.task-item {
display: flex;
align-items: center;
gap: var(--space-md);
padding: var(--space-md);
background-color: var(--surface);
border-radius: var(--radius-sm);
border: 1px solid var(--border);
cursor: pointer;
transition: background-color var(--anim-fast), border-color var(--anim-fast);
position: relative;
}
.task-item:hover {
background-color: var(--surface-hover);
}
.task-item.selected {
background-color: var(--surface-selected);
border-color: var(--accent);
}
.task-item.overdue {
background-color: rgba(239, 68, 68, 0.1);
}
/* Priority bar on left */
.task-item::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
border-radius: var(--radius-sm) 0 0 var(--radius-sm);
background-color: var(--priority-low);
}
.task-item.priority-urgent::before { background-color: var(--priority-urgent); }
.task-item.priority-high::before { background-color: var(--priority-high); }
.task-item.priority-medium::before { background-color: var(--priority-medium); }
.task-item.priority-low::before { background-color: var(--priority-low); }
/* Checkbox */
.task-checkbox {
width: 20px;
height: 20px;
border: 2px solid var(--border);
border-radius: var(--radius-xs);
background: transparent;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: background-color var(--anim-fast), border-color var(--anim-fast);
}
.task-checkbox:hover {
border-color: var(--accent);
}
.task-checkbox.checked {
background-color: var(--accent);
border-color: var(--accent);
color: var(--text-on-accent);
}
.task-checkbox svg {
width: 12px;
height: 12px;
}
/* Task content */
.task-content {
flex: 1;
min-width: 0;
}
.task-title {
font-size: var(--font-md);
font-weight: 500;
color: var(--text-primary);
margin-bottom: var(--space-xs);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.task-item.completed .task-title {
text-decoration: line-through;
color: var(--text-muted);
}
.task-meta {
display: flex;
align-items: center;
gap: var(--space-sm);
font-size: var(--font-sm);
}
.task-due {
color: var(--text-secondary);
}
.task-due.overdue {
color: var(--danger);
font-weight: 500;
}
.task-group-label {
padding: 2px var(--space-sm);
border-radius: 10px;
font-size: var(--font-xs);
}
.task-meta-separator {
color: var(--text-muted);
}
/* Priority badge */
.priority-badge {
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-xs);
font-size: var(--font-xs);
font-weight: 600;
text-transform: uppercase;
}
.priority-badge.urgent {
background-color: rgba(239, 68, 68, 0.2);
color: var(--priority-urgent);
}
.priority-badge.high {
background-color: rgba(245, 158, 11, 0.2);
color: var(--priority-high);
}
.priority-badge.medium {
background-color: rgba(59, 130, 246, 0.2);
color: var(--priority-medium);
}
.priority-badge.low {
background-color: rgba(107, 114, 128, 0.2);
color: var(--priority-low);
}
/* Empty state */
.empty-state {
text-align: center;
padding: var(--space-xxl);
color: var(--text-muted);
}
/* ============================================
Task Detail Panel (right pane)
============================================ */
.detail-pane {
background-color: var(--surface);
border-left: 1px solid var(--border);
padding: var(--space-lg);
overflow-y: auto;
transition: width var(--anim-normal);
}
.detail-pane.hidden {
display: none;
}
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-lg);
}
.detail-close {
background: none;
border: none;
padding: var(--space-sm);
cursor: pointer;
color: var(--text-secondary);
border-radius: var(--radius-sm);
transition: background-color var(--anim-fast);
}
.detail-close:hover {
background-color: var(--surface-hover);
}
/* Form elements */
.form-group {
margin-bottom: var(--space-lg);
}
.form-label {
display: block;
font-size: var(--font-sm);
font-weight: 500;
color: var(--text-secondary);
margin-bottom: var(--space-xs);
}
.form-input,
.form-select,
.form-textarea {
width: 100%;
padding: var(--space-sm) var(--space-md);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
font-size: var(--font-md);
background-color: var(--bg);
color: var(--text-primary);
transition: border-color var(--anim-fast), box-shadow var(--anim-fast);
}
.form-input:focus,
.form-select:focus,
.form-textarea:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.form-textarea {
resize: vertical;
min-height: 100px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
}
/* Time tracker */
.time-tracker {
background-color: var(--bg);
border-radius: var(--radius-sm);
padding: var(--space-md);
margin-bottom: var(--space-lg);
}
.time-tracker-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-sm);
}
.time-tracker-label {
font-size: var(--font-sm);
color: var(--text-secondary);
}
.time-tracker-total {
font-size: var(--font-lg);
font-weight: 600;
font-family: monospace;
color: var(--text-primary);
}
/* Detail actions */
.detail-actions {
display: flex;
gap: var(--space-sm);
margin-top: var(--space-xl);
}
/* ============================================
Buttons
============================================ */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-lg);
border-radius: var(--radius-sm);
font-size: var(--font-md);
font-weight: 500;
cursor: pointer;
border: none;
transition: background-color var(--anim-fast), color var(--anim-fast);
}
.btn-primary {
background-color: var(--accent);
color: var(--text-on-accent);
}
.btn-primary:hover {
background-color: var(--accent-hover);
}
.btn-secondary {
background-color: var(--surface-hover);
color: var(--text-primary);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background-color: var(--border-light);
}
.btn-danger {
background-color: var(--danger);
color: var(--text-on-accent);
}
.btn-danger:hover {
background-color: var(--danger-hover);
}
.btn-sm {
padding: var(--space-xs) var(--space-sm);
font-size: var(--font-sm);
}
.btn-full {
width: 100%;
}
/* ============================================
Alerts/Messages
============================================ */
.alert {
padding: var(--space-md);
border-radius: var(--radius-sm);
margin-bottom: var(--space-md);
}
.alert-success {
background-color: rgba(16, 185, 129, 0.1);
color: var(--success);
border: 1px solid var(--success);
}
.alert-error {
background-color: rgba(239, 68, 68, 0.1);
color: var(--danger);
border: 1px solid var(--danger);
}
/* ============================================
Auth Pages
============================================ */
.auth-layout {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: var(--bg);
}
.auth-card {
background-color: var(--surface);
border-radius: var(--radius-lg);
padding: var(--space-xxl);
width: 100%;
max-width: 400px;
box-shadow: var(--shadow-md);
}
.auth-title {
font-size: var(--font-title);
font-weight: 700;
text-align: center;
margin-bottom: var(--space-xl);
color: var(--text-primary);
}
.auth-footer {
text-align: center;
margin-top: var(--space-xl);
color: var(--text-secondary);
font-size: var(--font-sm);
}
/* ============================================
Dialogs/Modals
============================================ */
.modal-backdrop {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: opacity var(--anim-normal), visibility var(--anim-normal);
}
.modal-backdrop.open {
opacity: 1;
visibility: visible;
}
.modal {
background-color: var(--surface);
border-radius: var(--radius-lg);
padding: var(--space-xl);
width: 100%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
transform: scale(0.95);
transition: transform var(--anim-normal);
}
.modal-backdrop.open .modal {
transform: scale(1);
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-lg);
}
.modal-title {
font-size: var(--font-xl);
font-weight: 600;
}
.modal-close {
background: none;
border: none;
padding: var(--space-sm);
cursor: pointer;
color: var(--text-secondary);
}
.modal-actions {
display: flex;
gap: var(--space-sm);
justify-content: flex-end;
margin-top: var(--space-xl);
}
/* ============================================
Footer
============================================ */
.app-footer {
display: none; /* Hidden in app layout */
}
/* Footer for auth pages */
.auth-layout .footer {
position: fixed;
bottom: var(--space-lg);
left: 0;
right: 0;
text-align: center;
color: var(--text-muted);
font-size: var(--font-sm);
}
/* Sidebar toggle button (hidden on desktop, shown on mobile) */
.sidebar-toggle {
display: none;
background: none;
border: none;
padding: var(--space-sm);
cursor: pointer;
color: var(--text-secondary);
}
.sidebar-toggle svg {
width: 24px;
height: 24px;
}
/* Mobile overlay */
.mobile-overlay {
display: none;
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 40;
}
.mobile-overlay.visible {
display: block;
}
/* ============================================
Mobile Responsive
============================================ */
@media (max-width: 1024px) {
.app-layout {
grid-template-columns: var(--sidebar-width) 1fr;
}
.detail-pane {
position: fixed;
right: 0;
top: var(--header-height);
bottom: 0;
width: var(--detail-panel-width);
z-index: 50;
transform: translateX(100%);
transition: transform var(--anim-normal);
}
.detail-pane.open {
transform: translateX(0);
}
}
@media (max-width: 768px) {
:root {
--sidebar-width: 0;
}
.app-layout {
grid-template-columns: 1fr;
}
/* Header mobile optimization */
.app-header {
padding: var(--space-sm) var(--space-md);
}
.header-user span {
display: none; /* Hide email on mobile */
}
.app-header-actions {
gap: var(--space-xs);
}
.app-brand {
font-size: 1.1rem; /* Slightly smaller on mobile */
}
/* Sidebar drawer - improved positioning */
.app-sidebar {
position: fixed;
left: 0;
top: var(--header-height);
bottom: 0;
width: 280px; /* Slightly wider for touch targets */
z-index: 100; /* Higher z-index */
transform: translateX(-100%);
transition: transform 0.3s ease-in-out;
background: var(--bg-primary);
box-shadow: var(--shadow-lg);
overflow-y: auto;
}
.app-sidebar.open {
transform: translateX(0);
}
.sidebar-toggle {
display: flex;
}
/* Detail pane mobile */
.detail-pane {
width: 100%;
max-width: 100vw;
padding: var(--space-md);
}
/* Forms */
.form-row {
grid-template-columns: 1fr;
}
.form-group {
margin-bottom: var(--space-md);
}
/* Task list mobile optimization */
.task-item {
padding: var(--space-sm);
}
.task-meta {
flex-wrap: wrap;
gap: var(--space-xs);
font-size: 0.75rem;
}
.priority-badge {
font-size: 0.7rem;
padding: 2px 6px;
}
.tag {
font-size: 0.7rem;
padding: 2px 6px;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
}
/* Touch targets - 44px minimum */
.task-item-checkbox {
width: 24px;
height: 24px;
}
.btn {
min-height: 44px;
padding: var(--space-sm) var(--space-md);
}
.sidebar-toggle {
min-width: 44px;
min-height: 44px;
padding: var(--space-sm);
}
.theme-toggle {
min-width: 44px;
min-height: 44px;
}
/* Modal on mobile */
.modal {
width: 95%;
max-width: 400px;
max-height: 90vh;
overflow-y: auto;
}
/* Mobile utility classes */
.mobile-only {
display: block;
}
.desktop-only {
display: none !important;
}
.mobile-full-width {
width: 100% !important;
}
}
/* Very small phones breakpoint */
@media (max-width: 480px) {
.app-header {
padding: var(--space-xs) var(--space-sm);
}
.app-brand {
font-size: 0.9rem;
}
.app-sidebar {
width: 260px; /* Narrower on very small screens */
}
/* Smaller buttons on very small screens */
.header-user .btn {
font-size: 0.75rem;
padding: var(--space-xs) var(--space-sm);
min-height: 36px;
}
.theme-toggle {
min-width: 40px;
min-height: 40px;
}
.sidebar-toggle {
min-width: 40px;
min-height: 40px;
}
}
/* Mobile utility classes base definitions */
.mobile-only {
display: none;
}
.desktop-only {
display: block;
}
/* ============================================
Color Presets (Group Modal)
============================================ */
.color-presets {
display: flex;
gap: var(--space-sm);
flex-wrap: wrap;
margin-bottom: var(--space-md);
}
.color-preset {
width: 32px;
height: 32px;
border-radius: 50%;
border: 3px solid transparent;
cursor: pointer;
transition: border-color var(--anim-fast), transform var(--anim-fast);
}
.color-preset:hover {
transform: scale(1.1);
}
.color-preset.selected {
border-color: var(--text-primary);
}
.color-custom-row {
display: flex;
align-items: center;
gap: var(--space-sm);
}
.color-custom-label {
font-size: var(--font-sm);
color: var(--text-secondary);
}
.color-custom-input {
width: 48px;
height: 32px;
padding: 2px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
background: var(--bg);
}
/* Group Preview */
.group-preview {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-md);
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.group-preview-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--accent);
}
.group-preview-name {
font-size: var(--font-md);
color: var(--text-primary);
}
/* ============================================
Utility Classes
============================================ */
.hidden { display: none !important; }
.text-muted { color: var(--text-muted); }
.text-danger { color: var(--danger); }
.text-success { color: var(--success); }
.mt-lg { margin-top: var(--space-lg); }
.mb-lg { margin-bottom: var(--space-lg); }