From 176209ff767a970947db8fbecd41671b42b75594 Mon Sep 17 00:00:00 2001 From: Antigravity Date: Mon, 11 May 2026 18:08:18 +0000 Subject: [PATCH] style: add prefers-reduced-motion support for accessibility in ingestion modal --- .../Organisms/BookIngestionModal.razor.css | 298 ++++++++---------- 1 file changed, 127 insertions(+), 171 deletions(-) diff --git a/src/NexusReader.UI.Shared/Components/Organisms/BookIngestionModal.razor.css b/src/NexusReader.UI.Shared/Components/Organisms/BookIngestionModal.razor.css index 3304004..f161ac1 100644 --- a/src/NexusReader.UI.Shared/Components/Organisms/BookIngestionModal.razor.css +++ b/src/NexusReader.UI.Shared/Components/Organisms/BookIngestionModal.razor.css @@ -1,211 +1,167 @@ -.modal-backdrop { +.ingestion-modal { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; - background-color: rgba(0, 0, 0, 0.6); - backdrop-filter: blur(8px); display: flex; - justify-content: center; align-items: center; + justify-content: center; z-index: 1000; - animation: fadeIn 0.3s ease-out; -} - -.modal-content { - background-color: #121212; - border: 1px solid rgba(var(--nexus-accent-rgb, 0, 255, 170), 0.3); - box-shadow: 0 0 20px rgba(var(--nexus-accent-rgb, 0, 255, 170), 0.1); - border-radius: 12px; - width: 90%; - max-width: 600px; - padding: 2rem; - display: flex; - flex-direction: column; - gap: 1.5rem; - position: relative; - overflow: hidden; -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.modal-header h2 { - margin: 0; - font-family: var(--nexus-font-sans); - color: var(--nexus-text); - font-size: 1.5rem; -} - -.close-btn { - background: none; - border: none; - color: var(--nexus-text-muted, #888); - cursor: pointer; - transition: color 0.2s; -} - -.close-btn:hover { - color: var(--nexus-accent, #00ffaa); -} - -.modal-body { - min-height: 250px; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* Upload State */ -.upload-state { - flex: 1; - display: flex; -} - -.drop-zone { - flex: 1; - border: 2px dashed rgba(255, 255, 255, 0.1); - border-radius: 8px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - cursor: pointer; - transition: all 0.3s ease; - background: rgba(255, 255, 255, 0.02); - position: relative; -} - -.drop-zone:hover, .upload-state.drag-over .drop-zone { - border-color: var(--nexus-accent, #00ffaa); - background: rgba(var(--nexus-accent-rgb, 0, 255, 170), 0.05); -} - -.drop-zone-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; - color: var(--nexus-text-muted, #888); + opacity: 0; pointer-events: none; + transition: opacity 0.3s ease; } -.drop-zone-content svg { - color: var(--nexus-accent, #00ffaa); - opacity: 0.8; +.ingestion-modal.visible { + opacity: 1; + pointer-events: auto; } -.drop-zone-content p { - margin: 0; - font-size: 1.1rem; - color: var(--nexus-text); -} - -.drop-zone ::deep .file-input-cover { +.modal-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; - opacity: 0; - cursor: pointer; - z-index: 10; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(8px); } -/* Parsing State */ -.parsing-state { - flex: 1; - display: flex; - justify-content: center; - align-items: center; - border-radius: 8px; - background: rgba(255, 255, 255, 0.03); +.modal-container { position: relative; - overflow: hidden; + width: 100%; + max-width: 500px; + background: var(--surface-card); + border: 1px solid var(--border-subtle); + border-radius: 24px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4); + padding: 32px; + transform: translateY(20px); + transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1); } -.shimmer::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 50%; - height: 100%; - background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.05), transparent); - animation: shimmer 2s infinite; +.ingestion-modal.visible .modal-container { + transform: translateY(0); } -.shimmer-content { +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24px; +} + +.upload-zone { + border: 2px dashed var(--border-subtle); + border-radius: 20px; + padding: 48px 24px; display: flex; flex-direction: column; align-items: center; - gap: 1rem; + gap: 16px; + text-align: center; + transition: all 0.2s ease; + background: rgba(255, 255, 255, 0.02); +} + +.upload-zone.dragging { + border-color: var(--accent-primary); + background: rgba(var(--accent-primary-rgb), 0.05); +} + +.file-input-label { + margin-top: 12px; + padding: 10px 24px; + background: var(--accent-primary); + color: white; + border-radius: 12px; + cursor: pointer; + font-weight: 500; + transition: transform 0.2s ease; +} + +.file-input-label:hover { + transform: scale(1.05); +} + +.file-input-label input { + display: none; +} + +.parsing-state { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + padding: 40px 0; } .spinner { width: 40px; height: 40px; - border: 3px solid rgba(var(--nexus-accent-rgb, 0, 255, 170), 0.2); - border-top-color: var(--nexus-accent, #00ffaa); + border: 3px solid rgba(var(--accent-primary-rgb), 0.1); + border-top-color: var(--accent-primary); border-radius: 50%; animation: spin 1s linear infinite; } -.parsing-state p { - color: var(--nexus-text); - font-family: var(--nexus-font-mono, monospace); - font-size: 0.9rem; - letter-spacing: 1px; -} - -/* Metadata State */ -.metadata-state { - display: flex; - flex-direction: column; - gap: 2rem; -} - -.metadata-info { - text-align: center; -} - -.metadata-info h3 { - margin: 0 0 0.5rem 0; - color: var(--nexus-text); - font-size: 1.25rem; -} - -.metadata-info .author { - margin: 0; - color: var(--nexus-text-muted, #888); -} - -.actions { - display: flex; - gap: 1rem; - justify-content: center; -} - -.error-message { - margin-top: 1rem; - color: #ff5555; - text-align: center; - font-size: 0.9rem; -} - -@keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } -} - -@keyframes shimmer { - 100% { left: 200%; } -} - @keyframes spin { to { transform: rotate(360deg); } } + +.metadata-preview { + display: flex; + gap: 24px; + padding: 16px; + background: rgba(255, 255, 255, 0.03); + border-radius: 16px; + border: 1px solid var(--border-subtle); +} + +.cover-wrapper { + width: 120px; + height: 180px; + border-radius: 8px; + overflow: hidden; + background: var(--surface-elevated); + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); +} + +.cover-wrapper img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.metadata-info { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + gap: 8px; +} + +.actions { + margin-top: 24px; + display: flex; + flex-direction: column; + gap: 12px; +} + +/* Accessibility: Support reduced motion */ +@media (prefers-reduced-motion: reduce) { + .ingestion-modal, + .modal-container, + .file-input-label, + .upload-zone { + transition: none; + } + + .spinner { + animation-duration: 0s; + } +}