diff --git a/static/css/app.css b/static/css/app.css index 6b91d1f..bb9f3de 100644 --- a/static/css/app.css +++ b/static/css/app.css @@ -1576,6 +1576,7 @@ body.dnd-mode .timer-display { flex: 1; overflow-y: scroll; overflow-x: auto; + position: relative; padding: 24px 16px; line-height: 1.8; font-family: Georgia, 'Times New Roman', serif; @@ -1690,6 +1691,26 @@ body.reader-immersive.reader-show-bottom .reader-overlay { bottom: var(--bar-h) .reader-content.pdf-paginated { overflow:hidden !important; display:flex; align-items:center; justify-content:center; } .pdf-paginated .pdf-page-wrapper { margin:0; } +/* PDF loading overlay */ +.pdf-loading-overlay { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + background: var(--bg, #000); + z-index: 10; +} +.pdf-loading-spinner { + width: 36px; + height: 36px; + border: 3px solid #333; + border-top-color: var(--accent, #e63946); + border-radius: 50%; + animation: pdf-spin 0.7s linear infinite; +} +@keyframes pdf-spin { to { transform: rotate(360deg); } } + /* PDF two-page spread */ .pdf-spread-wrapper { display:flex; flex-direction:row; gap:8px; justify-content:center; margin-bottom:1rem; } .pdf-spread-wrapper .pdf-page-wrapper { margin:0; } diff --git a/static/js/app.js b/static/js/app.js index 4230479..1449eb8 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -3127,6 +3127,7 @@ async function openBook(bookId) { if (isPdfBook) { currentPdfDoc = null; // reset so renderPdf creates fresh doc + contentEl.innerHTML = '
'; const result = await renderPdf(plain, contentEl); title = result.title || title; author = result.author || author;