diff --git a/frontend/src/App.css b/frontend/src/App.css deleted file mode 100644 index 289cd5d..0000000 --- a/frontend/src/App.css +++ /dev/null @@ -1,495 +0,0 @@ -/* - * TaskFlow base styles: reset, shared primitives and design tokens. - * Palette follows the approved mockups. Two swaps were made for WCAG 2.1 AA: - * the mockup accent #3b82f6 only reaches 3.7:1 behind white text, so filled - * buttons use #2563eb (5.2:1) and accent text uses #1d4ed8 (6.4:1). - */ - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, - sans-serif; - background-color: #f8fafc; - color: #1e293b; - line-height: 1.6; -} - -/* Visible only to screen readers. */ -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; -} - -/* Keyboard users can jump straight to the task list. */ -.skip-link { - position: absolute; - left: -9999px; - top: 0; - z-index: 100; - padding: 0.75rem 1rem; - background-color: #1e293b; - color: white; - border-radius: 0 0 0.375rem 0; - text-decoration: none; -} - -.skip-link:focus { - left: 0; -} - -/* Page-level loading and error states */ -.app-loading, -.app-error { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 100vh; - padding: 2rem; - text-align: center; - gap: 0.5rem; -} - -.loading-spinner { - border: 4px solid #e2e8f0; - border-left-color: #2563eb; - border-radius: 50%; - width: 40px; - height: 40px; - animation: spin 1s linear infinite; - margin-bottom: 1rem; -} - -@keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -.app-error h1 { - color: #b91c1c; - font-size: 1.5rem; - margin-bottom: 0.5rem; -} - -.app-error p { - color: #475569; - max-width: 34rem; -} - -.retry-button { - margin-top: 1rem; -} - -/* Inline notices (save confirmations, failed updates) */ -.app-notice-region { - min-height: 0; -} - -.app-notice { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - padding: 0.75rem 1rem; - margin-bottom: 1rem; - border-radius: 0.5rem; - border: 1px solid transparent; - animation: notice-in 0.2s ease-out; -} - -@keyframes notice-in { - from { - opacity: 0; - transform: translateY(-4px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.app-notice.info { - background-color: #eff6ff; - border-color: #bfdbfe; - color: #1e40af; -} - -.app-notice.error { - background-color: #fef2f2; - border-color: #fecaca; - color: #b91c1c; -} - -.notice-dismiss { - background: none; - border: none; - cursor: pointer; - color: inherit; - font-size: 1rem; - line-height: 1; - min-width: 44px; - min-height: 44px; - border-radius: 0.375rem; -} - -.notice-dismiss:hover { - background-color: rgba(0, 0, 0, 0.05); -} - -/* Buttons */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - padding: 0.5rem 1rem; - border: 1px solid transparent; - border-radius: 0.5rem; - font-size: 0.875rem; - font-weight: 500; - font-family: inherit; - cursor: pointer; - transition: background-color 0.2s, box-shadow 0.2s; - text-decoration: none; - min-height: 44px; /* WCAG 2.5.5 touch target */ -} - -.btn:disabled { - opacity: 0.6; - cursor: not-allowed; -} - -.btn-primary { - background-color: #2563eb; - color: white; -} - -.btn-primary:hover:not(:disabled) { - background-color: #1d4ed8; -} - -.btn-secondary { - background-color: white; - color: #334155; - border-color: #cbd5e1; -} - -.btn-secondary:hover:not(:disabled) { - background-color: #f1f5f9; -} - -.btn-danger { - background-color: #b91c1c; - color: white; -} - -.btn-danger:hover:not(:disabled) { - background-color: #991b1b; -} - -.create-task-btn { - flex: none; - white-space: nowrap; -} - -.create-icon { - font-size: 1.125rem; - font-weight: 400; - line-height: 1; -} - -/* Icon-only actions keep a 44px hit area even though the glyph is small. */ -.btn-action { - background: none; - border: none; - cursor: pointer; - border-radius: 0.375rem; - transition: background-color 0.2s; - min-width: 44px; - min-height: 44px; - display: inline-flex; - align-items: center; - justify-content: center; - font-size: 1rem; - color: #475569; -} - -.btn-action:hover:not(:disabled) { - background-color: #f1f5f9; -} - -.btn-action.delete:hover:not(:disabled) { - background-color: #fef2f2; - color: #b91c1c; -} - -.btn-action:disabled { - opacity: 0.5; - cursor: not-allowed; -} - -/* One consistent, always-visible focus indicator */ -:focus-visible { - outline: 2px solid #2563eb; - outline-offset: 2px; -} - -/* Avatars */ -.user-avatar { - width: 32px; - height: 32px; - border-radius: 50%; - background-color: #e2e8f0; - display: inline-flex; - align-items: center; - justify-content: center; - font-weight: 600; - font-size: 0.75rem; - color: #334155; - flex: none; -} - -.user-avatar.sm { - width: 24px; - height: 24px; - font-size: 0.625rem; -} - -.user-avatar.lg { - width: 40px; - height: 40px; - font-size: 0.875rem; -} - -/* Priority: coloured dot plus label, as in the dashboard mockup */ -.priority-indicator { - display: inline-flex; - align-items: center; - gap: 0.5rem; - font-size: 0.875rem; - font-weight: 600; -} - -.priority-dot { - width: 10px; - height: 10px; - border-radius: 50%; - flex: none; -} - -.priority-indicator.low { - color: #1d4ed8; -} - -.priority-indicator.low .priority-dot { - background-color: #2563eb; -} - -.priority-indicator.medium { - color: #b45309; -} - -.priority-indicator.medium .priority-dot { - background-color: #f59e0b; -} - -.priority-indicator.high { - color: #b91c1c; -} - -.priority-indicator.high .priority-dot { - background-color: #ef4444; -} - -/* Status pill, doubling as the status control */ -.status-badge, -.status-select { - display: inline-flex; - align-items: center; - padding: 0.375rem 0.75rem; - border-radius: 9999px; - border: 1px solid transparent; - font-size: 0.8125rem; - font-weight: 500; - font-family: inherit; -} - -.status-select { - appearance: none; - -webkit-appearance: none; - cursor: pointer; - min-height: 32px; - padding-right: 1.75rem; - background-repeat: no-repeat; - background-position: right 0.5rem center; - background-size: 8px; - background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath fill='%23334155' d='M0 0h8L4 5z'/%3E%3C/svg%3E"); -} - -.status-select:disabled { - opacity: 0.6; - cursor: progress; -} - -.status-badge.open, -.status-select.open { - background-color: #dbeafe; - color: #1d4ed8; -} - -.status-badge.in_progress, -.status-select.in_progress { - background-color: #fef3c7; - color: #92400e; -} - -.status-badge.blocked, -.status-select.blocked { - background-color: #fee2e2; - color: #b91c1c; -} - -/* Assignee */ -.assignee-info { - display: inline-flex; - align-items: center; - gap: 0.5rem; -} - -.assignee-name { - font-size: 0.875rem; - font-weight: 500; - color: #334155; -} - -.unassigned { - font-size: 0.875rem; - color: #6b7280; - font-style: italic; -} - -/* Due dates */ -.due-date { - font-size: 0.875rem; - color: #475569; -} - -.due-date.none { - color: #6b7280; - font-style: italic; -} - -.due-date.overdue { - color: #b91c1c; - font-weight: 600; -} - -/* Form primitives (shared by the task dialog) */ -.form-group { - margin-bottom: 0.875rem; -} - -.form-label { - display: block; - font-weight: 500; - margin-bottom: 0.375rem; - color: #334155; - font-size: 0.9375rem; -} - -.form-label.required::after { - content: ' *'; - color: #b91c1c; - font-weight: 700; -} - -.form-input, -.form-select, -.form-textarea { - width: 100%; - padding: 0.625rem 0.75rem; - border: 1px solid #cbd5e1; - border-radius: 0.5rem; - font-size: 0.9375rem; - font-family: inherit; - color: #1e293b; - background-color: white; - min-height: 44px; -} - -.form-textarea { - resize: vertical; - min-height: 68px; -} - -.form-input::placeholder, -.form-textarea::placeholder { - color: #6b7280; -} - -.form-input:hover, -.form-select:hover, -.form-textarea:hover { - border-color: #94a3b8; -} - -.form-input[aria-invalid='true'], -.form-select[aria-invalid='true'], -.form-textarea[aria-invalid='true'] { - border-color: #b91c1c; - background-color: #fffbfb; -} - -.field-error { - margin-top: 0.375rem; - font-size: 0.8125rem; - font-weight: 500; - color: #b91c1c; -} - -.form-hint { - margin-top: 0.375rem; - font-size: 0.8125rem; - color: #6b7280; -} - -.required-marker { - color: #b91c1c; - font-weight: 700; -} - -.form-error-banner { - padding: 0.75rem 1rem; - margin-bottom: 1.25rem; - border-radius: 0.5rem; - background-color: #fef2f2; - border: 1px solid #fecaca; - color: #b91c1c; - font-size: 0.875rem; -} - -@media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } -}