/* PrimeVue Component Overrides - ROA2WEB */ /* Global customization of PrimeVue saga-blue theme */ /* ===== Input Components ===== */ .p-inputtext, .p-password input, .p-dropdown, .p-calendar input, .p-autocomplete input { border: 2px solid var(--color-border) !important; border-radius: var(--radius-md) !important; padding: var(--space-sm) var(--space-md) !important; font-size: var(--text-base) !important; font-family: inherit !important; color: var(--color-text) !important; background: var(--color-bg) !important; transition: all var(--transition-fast) !important; min-height: 44px !important; } /* ===== Focus States ===== */ .p-inputtext:focus, .p-password input:focus, .p-dropdown:focus, .p-calendar input:focus, .p-autocomplete input:focus { outline: none !important; border-color: var(--color-primary) !important; box-shadow: var(--focus-ring) !important; } /* ===== Hover States ===== */ .p-inputtext:hover:not(:disabled), .p-password input:hover:not(:disabled), .p-dropdown:hover:not(:disabled) { border-color: var(--color-border-dark, #d1d5db) !important; } /* ===== Disabled States ===== */ .p-inputtext:disabled, .p-password input:disabled, .p-dropdown:disabled { background: var(--color-bg-muted, #f3f4f6) !important; color: var(--color-text-muted, #9ca3af) !important; opacity: 0.6 !important; cursor: not-allowed !important; } /* ===== Validation States ===== */ .p-invalid.p-component, .p-inputtext.p-invalid, .p-password.p-invalid input { border-color: var(--color-error, #ef4444) !important; } /* ===== Button Overrides ===== */ .p-button { padding: var(--space-sm) var(--space-md) !important; font-size: var(--text-sm) !important; font-weight: var(--font-medium) !important; border-radius: var(--radius-md) !important; transition: all var(--transition-fast) !important; } .p-button:hover { transform: translateY(-1px) !important; box-shadow: var(--shadow-md) !important; } /* ===== DataTable ===== */ .p-datatable .p-datatable-thead > tr > th { background: var(--color-bg-muted, #f9fafb) !important; color: var(--color-text) !important; font-weight: var(--font-semibold) !important; border-bottom: 2px solid var(--color-border) !important; padding: var(--space-md) var(--space-lg) !important; } .p-datatable .p-datatable-tbody > tr { transition: background-color var(--transition-fast) !important; } /* DataTable Striped Rows - Global Pattern (Dark Mode Compatible) */ .p-datatable .p-datatable-tbody > tr:nth-child(odd) { background-color: var(--surface-card) !important; } .p-datatable .p-datatable-tbody > tr:nth-child(even) { background-color: var(--surface-ground) !important; } .p-datatable .p-datatable-tbody > tr:hover { background-color: var(--surface-hover) !important; cursor: pointer; } /* Compact DataTable variant (p-datatable-sm) */ .p-datatable-sm .p-datatable-thead > tr > th { padding: 0.5rem 0.75rem !important; font-weight: 600 !important; white-space: nowrap !important; } .p-datatable-sm .p-datatable-tbody > tr > td { padding: 0.4rem 0.75rem !important; } /* DataTable font size for compact tables */ .p-datatable-sm { font-size: 0.875rem !important; } /* ===== Card ===== */ .p-card { background: var(--surface-card) !important; box-shadow: var(--shadow-sm) !important; border: 1px solid var(--color-border) !important; border-radius: var(--card-radius, 8px) !important; } .p-card .p-card-header { background: var(--color-bg-secondary) !important; border-bottom: 1px solid var(--color-border) !important; padding: var(--space-lg) !important; } .p-card .p-card-body { padding: var(--space-lg) !important; background: var(--surface-card) !important; } .p-card .p-card-content { background: var(--surface-card) !important; } /* ===== Mobile Optimizations ===== */ @media (max-width: 768px) { .p-inputtext, .p-password input, .p-dropdown, .p-calendar input { font-size: 16px !important; /* Prevent iOS zoom */ } } /* ===== Compact DataTable (ReceiptsListView) ===== */ .compact-table .p-datatable-tbody > tr > td { padding: 0.5rem 0.5rem; font-size: 0.875rem; } .compact-table .p-datatable-thead > tr > th { padding: 0.5rem 0.5rem; font-size: 0.8rem; } .compact-table .p-paginator { padding: 0.5rem; } .compact-table .p-datatable-wrapper { overflow-x: auto; } /* ===== Receipt Form InputNumber (ReceiptCreateView) ===== */ .value-item-total .p-inputnumber { width: 100% !important; max-width: 130px !important; } .value-item-total .p-inputnumber-input { width: 100% !important; } .payment-method-item .p-inputnumber { width: 100% !important; max-width: 110px !important; } .payment-method-item .p-inputnumber-input { width: 100% !important; } .dropdown-payment { width: 100% !important; max-width: 190px !important; } .dropdown-payment .p-dropdown { width: 100% !important; } .input-tva { width: 110px !important; } .input-tva .p-inputnumber-input { width: 110px !important; } /* ===== Receipt Form Mobile (ReceiptCreateView) ===== */ @media (max-width: 768px) { .form-field .p-dropdown, .form-field .p-autocomplete, .form-field .p-calendar { width: 100% !important; } } /* ===== OCR Preview Mobile (OCRPreview) ===== */ @media (max-width: 768px) { .preview-actions .p-button { width: 100%; } } /* ===== OCR Engine Selector (OCRUploadZone) ===== */ .engine-selector .p-dropdown-label { padding: 0.5rem 0.75rem !important; font-size: 0.875rem; color: var(--text-color-secondary); } .engine-selector .p-dropdown-trigger { width: 2rem !important; } /* ===== Table Card Striped Rows (InvoicesView) ===== */ /* Note: Uses design tokens for dark mode compatibility */ .table-card .p-datatable .p-datatable-tbody > tr { transition: background-color 0.2s ease; } .table-card .p-datatable .p-datatable-tbody > tr:nth-child(odd) { background-color: var(--surface-card, #ffffff); } .table-card .p-datatable .p-datatable-tbody > tr:nth-child(even) { background-color: var(--surface-ground, #f8f9fa); } .table-card .p-datatable .p-datatable-tbody > tr:hover { background-color: var(--surface-hover, #e3f2fd) !important; cursor: pointer; } /* ===== US-010: Row Lock for Processing Receipts ===== */ /** * Processing row styling - visual indicator that the row is read-only. * Uses border-left accent and reduced opacity per acceptance criteria. */ .p-datatable .p-datatable-tbody > tr.row-processing { opacity: 0.7; border-left: 3px solid var(--blue-500); background-color: var(--blue-50) !important; transition: opacity var(--transition-fast, 150ms ease), background-color var(--transition-fast, 150ms ease); } /* Dark mode support for processing rows */ [data-theme="dark"] .p-datatable .p-datatable-tbody > tr.row-processing { background-color: color-mix(in srgb, var(--blue-500) 15%, var(--surface-card)) !important; } @media (prefers-color-scheme: dark) { :root:not([data-theme]) .p-datatable .p-datatable-tbody > tr.row-processing { background-color: color-mix(in srgb, var(--blue-500) 15%, var(--surface-card)) !important; } } /* Ensure hover doesn't override processing row styling too aggressively */ .p-datatable .p-datatable-tbody > tr.row-processing:hover { opacity: 0.8; } /* Disabled buttons in processing rows show not-allowed cursor */ .p-datatable .p-datatable-tbody > tr.row-processing .p-button:disabled { cursor: not-allowed; } /* ============ US-018: Failed Job Row Styling ============ */ /* Failed job row - red styling similar to processing but with red accent */ .p-datatable .p-datatable-tbody > tr.row-failed { opacity: 0.85; border-left: 3px solid var(--red-500); background-color: var(--red-50) !important; transition: opacity var(--transition-fast, 150ms ease), background-color var(--transition-fast, 150ms ease); } [data-theme="dark"] .p-datatable .p-datatable-tbody > tr.row-failed { background-color: color-mix(in srgb, var(--red-500) 15%, var(--surface-card)) !important; } @media (prefers-color-scheme: dark) { :root:not([data-theme]) .p-datatable .p-datatable-tbody > tr.row-failed { background-color: color-mix(in srgb, var(--red-500) 15%, var(--surface-card)) !important; } } /* Hover effect for failed rows */ .p-datatable .p-datatable-tbody > tr.row-failed:hover { opacity: 0.9; } /* ============ US-019: Status Change Animations ============ */ /** * Keyframe animations for row highlight on status change. * - highlightGreen: Plays when a job completes successfully (2s duration) * - highlightRed: Plays when a job fails (2s duration) * * The animations are subtle - starting with a colored background that * fades to transparent. Uses design tokens for colors. */ /* Success highlight animation - green fade */ @keyframes highlightGreen { 0% { background-color: var(--green-100); } 100% { background-color: transparent; } } /* Error highlight animation - red fade */ @keyframes highlightRed { 0% { background-color: var(--red-100); } 100% { background-color: transparent; } } /** * Row highlight class for completed status. * Applied when a row transitions to 'completed' status. * The animation runs once and fills forwards to stay at the end state. */ .p-datatable .p-datatable-tbody > tr.row-highlight-completed { animation: highlightGreen 2s ease-out forwards; } /** * Row highlight class for failed status. * Applied when a row transitions to 'failed' status. */ .p-datatable .p-datatable-tbody > tr.row-highlight-failed { animation: highlightRed 2s ease-out forwards; } /* Dark mode adjustments for highlight animations */ [data-theme="dark"] .p-datatable .p-datatable-tbody > tr.row-highlight-completed { animation-name: highlightGreenDark; } [data-theme="dark"] .p-datatable .p-datatable-tbody > tr.row-highlight-failed { animation-name: highlightRedDark; } @keyframes highlightGreenDark { 0% { background-color: color-mix(in srgb, var(--green-500) 25%, var(--surface-card)); } 100% { background-color: transparent; } } @keyframes highlightRedDark { 0% { background-color: color-mix(in srgb, var(--red-500) 25%, var(--surface-card)); } 100% { background-color: transparent; } } /* System preference dark mode animations */ @media (prefers-color-scheme: dark) { :root:not([data-theme]) .p-datatable .p-datatable-tbody > tr.row-highlight-completed { animation-name: highlightGreenDark; } :root:not([data-theme]) .p-datatable .p-datatable-tbody > tr.row-highlight-failed { animation-name: highlightRedDark; } } /** * US-019: Accessibility - Disable animations for users who prefer reduced motion. * This respects the prefers-reduced-motion media query as per acceptance criteria. */ @media (prefers-reduced-motion: reduce) { .p-datatable .p-datatable-tbody > tr.row-highlight-completed, .p-datatable .p-datatable-tbody > tr.row-highlight-failed { animation: none; } } /* ============ US-020: Cancel Job Row Animation ============ */ /** * Fade-out animation for job rows being cancelled. * Applied when user cancels a pending/processing file. * Animation runs for 300ms before row is removed from DOM. */ @keyframes rowFadeOut { 0% { opacity: 1; transform: translateX(0); } 100% { opacity: 0; transform: translateX(-10px); } } .p-datatable .p-datatable-tbody > tr.row-cancelling { animation: rowFadeOut 300ms ease-out forwards; pointer-events: none; /* Prevent interaction during animation */ } /** * US-020: Accessibility - simplified animation for reduced motion preference. */ @media (prefers-reduced-motion: reduce) { @keyframes rowFadeOut { 0% { opacity: 1; } 100% { opacity: 0; } } }