diff options
| author | Paul Buetow <paul@buetow.org> | 2026-01-25 10:51:58 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-01-25 10:51:58 +0200 |
| commit | 3cf0ed0cba706c45833ad06bddfce2acefca6a37 (patch) | |
| tree | ea90532bb51b2d4bfff0f6a8e2f3c441b1b5707f /css | |
Add sci-fi book showcase with 54 books, covers, and summaries
Interactive HTML page featuring sci-fi book collection with:
- Responsive grid layout with book cover thumbnails
- Click-to-expand modal with cover, metadata, and summary
- Filter by author, format, and text search
- All 54 covers and summaries stored locally for offline use
- Authors include Brandhorst, Reynolds, Clarke, Banks, Simmons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'css')
| -rw-r--r-- | css/styles.css | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/css/styles.css b/css/styles.css new file mode 100644 index 0000000..2f7d8e5 --- /dev/null +++ b/css/styles.css @@ -0,0 +1,505 @@ +/* CSS Variables for theming */ +:root { + --bg-primary: #0a0a0f; + --bg-secondary: #12121a; + --bg-card: #1a1a24; + --bg-card-hover: #22222e; + --text-primary: #e8e8ed; + --text-secondary: #a0a0b0; + --accent: #6366f1; + --accent-hover: #818cf8; + --border-color: #2a2a3a; + --shadow: rgba(0, 0, 0, 0.4); + --overlay: rgba(0, 0, 0, 0.85); +} + +/* Reset and base styles */ +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + font-size: 16px; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; + background-color: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; + min-height: 100vh; +} + +/* Header */ +.header { + background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%); + padding: 2rem 1rem; + text-align: center; + border-bottom: 1px solid var(--border-color); +} + +.header h1 { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 0.5rem; + background: linear-gradient(135deg, var(--accent) 0%, #a78bfa 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.header p { + color: var(--text-secondary); + font-size: 1.1rem; +} + +/* Filter controls */ +.filters { + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; + padding: 1.5rem 1rem; + background-color: var(--bg-secondary); + border-bottom: 1px solid var(--border-color); +} + +.filter-group { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.filter-group label { + color: var(--text-secondary); + font-size: 0.9rem; +} + +.filter-group select, +.filter-group input { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + color: var(--text-primary); + padding: 0.5rem 1rem; + border-radius: 6px; + font-size: 0.9rem; + cursor: pointer; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.filter-group select:hover, +.filter-group input:hover { + border-color: var(--accent); +} + +.filter-group select:focus, +.filter-group input:focus { + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2); +} + +/* Main container */ +.container { + max-width: 1400px; + margin: 0 auto; + padding: 2rem 1rem; +} + +/* Book count display */ +.book-count { + text-align: center; + color: var(--text-secondary); + margin-bottom: 1.5rem; + font-size: 0.95rem; +} + +/* Books grid */ +.books-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 1.5rem; +} + +@media (min-width: 640px) { + .books-grid { + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + } +} + +@media (min-width: 1024px) { + .books-grid { + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + } +} + +/* Book card */ +.book-card { + background-color: var(--bg-card); + border-radius: 12px; + overflow: hidden; + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s, background-color 0.2s; + border: 1px solid var(--border-color); +} + +.book-card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 24px var(--shadow); + background-color: var(--bg-card-hover); +} + +.book-card:focus { + outline: none; + box-shadow: 0 0 0 3px var(--accent); +} + +/* Cover image container */ +.cover-container { + position: relative; + width: 100%; + padding-top: 150%; /* 2:3 aspect ratio for book covers */ + background-color: var(--bg-secondary); + overflow: hidden; +} + +.cover-container img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + transition: opacity 0.3s; +} + +/* Placeholder for missing covers */ +.cover-placeholder { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-card) 100%); + padding: 1rem; + text-align: center; +} + +.cover-placeholder .book-icon { + font-size: 3rem; + margin-bottom: 0.5rem; + opacity: 0.5; +} + +.cover-placeholder .placeholder-title { + font-size: 0.85rem; + color: var(--text-secondary); + word-break: break-word; +} + +/* Loading spinner for images */ +.cover-loading { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 32px; + height: 32px; + border: 3px solid var(--border-color); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + to { transform: translate(-50%, -50%) rotate(360deg); } +} + +/* Card info section */ +.card-info { + padding: 1rem; +} + +.card-info h3 { + font-size: 0.95rem; + font-weight: 600; + margin-bottom: 0.25rem; + color: var(--text-primary); + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.card-info .author { + font-size: 0.85rem; + color: var(--text-secondary); + margin-bottom: 0.5rem; +} + +.card-info .meta { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} + +.format-badge { + display: inline-block; + font-size: 0.7rem; + padding: 0.2rem 0.5rem; + border-radius: 4px; + background-color: var(--bg-secondary); + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.format-badge.audiobook { background-color: #3730a3; color: #c7d2fe; } +.format-badge.ebook { background-color: #065f46; color: #a7f3d0; } +.format-badge.paperback { background-color: #7c2d12; color: #fed7aa; } + +/* Modal overlay */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: var(--overlay); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: opacity 0.3s, visibility 0.3s; + padding: 1rem; + overflow-y: auto; +} + +.modal-overlay.active { + opacity: 1; + visibility: visible; +} + +/* Modal content */ +.modal-content { + background-color: var(--bg-secondary); + border-radius: 16px; + max-width: 800px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + position: relative; + transform: scale(0.9); + transition: transform 0.3s; + border: 1px solid var(--border-color); +} + +.modal-overlay.active .modal-content { + transform: scale(1); +} + +/* Close button */ +.modal-close { + position: absolute; + top: 1rem; + right: 1rem; + width: 40px; + height: 40px; + border: none; + background-color: var(--bg-card); + color: var(--text-primary); + border-radius: 50%; + cursor: pointer; + font-size: 1.5rem; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s; + z-index: 10; +} + +.modal-close:hover { + background-color: var(--bg-card-hover); +} + +/* Modal body layout */ +.modal-body { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; + padding: 1.5rem; +} + +@media (min-width: 640px) { + .modal-body { + grid-template-columns: 250px 1fr; + padding: 2rem; + } +} + +/* Modal cover image */ +.modal-cover { + position: relative; + width: 100%; + max-width: 250px; + margin: 0 auto; +} + +.modal-cover { + position: relative; +} + +.modal-cover img { + width: 100%; + height: auto; + border-radius: 8px; + box-shadow: 0 8px 24px var(--shadow); +} + +.modal-cover .cover-loading { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 48px; + height: 48px; + border: 4px solid var(--border-color); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 1s linear infinite; + z-index: 1; +} + +.modal-cover .cover-placeholder { + position: relative; + padding-top: 150%; + border-radius: 8px; +} + +/* Modal details */ +.modal-details h2 { + font-size: 1.5rem; + margin-bottom: 0.5rem; + color: var(--text-primary); +} + +.modal-details .author { + font-size: 1.1rem; + color: var(--accent); + margin-bottom: 1rem; +} + +.modal-meta { + display: flex; + gap: 1rem; + flex-wrap: wrap; + margin-bottom: 1.5rem; + padding-bottom: 1.5rem; + border-bottom: 1px solid var(--border-color); +} + +.meta-item { + display: flex; + flex-direction: column; +} + +.meta-item .label { + font-size: 0.75rem; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.meta-item .value { + font-size: 1rem; + color: var(--text-primary); +} + +/* Summary section */ +.modal-summary h3 { + font-size: 1rem; + color: var(--text-secondary); + margin-bottom: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.modal-summary p { + color: var(--text-primary); + line-height: 1.7; +} + +.modal-summary .loading { + color: var(--text-secondary); + font-style: italic; +} + +.modal-summary .no-summary { + color: var(--text-secondary); + font-style: italic; +} + +.modal-summary .summary-source { + margin-top: 1rem; + font-size: 0.8rem; + color: var(--text-secondary); + font-style: italic; +} + +/* Loading state for the grid */ +.loading-message { + text-align: center; + padding: 4rem 2rem; + color: var(--text-secondary); +} + +.loading-message .spinner { + width: 48px; + height: 48px; + border: 4px solid var(--border-color); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 1rem; +} + +/* Error state */ +.error-message { + text-align: center; + padding: 4rem 2rem; + color: #ef4444; +} + +/* No results state */ +.no-results { + text-align: center; + padding: 4rem 2rem; + color: var(--text-secondary); +} + +/* Footer */ +.footer { + text-align: center; + padding: 2rem 1rem; + color: var(--text-secondary); + font-size: 0.85rem; + border-top: 1px solid var(--border-color); + margin-top: 2rem; +} + +.footer a { + color: var(--accent); + text-decoration: none; +} + +.footer a:hover { + text-decoration: underline; +} |
