Move CSS/JS assets from static/ into views/ feature folders

Co-locate each feature's CSS and JS alongside its HTML template.
Remove the standalone static/ directory entirely.
This commit is contained in:
hiep200311
2026-06-24 16:22:14 +07:00
parent ff47d331ae
commit 9f7824825c
8 changed files with 0 additions and 272 deletions
@@ -0,0 +1,436 @@
/* ═══════════════════════════════════════════════════════════
scraperZLibraryMain.css · Mainframe Design System v3
═══════════════════════════════════════════════════════════ */
:root {
--font-heading: 'HelveticaNowDisplay-Medium','Helvetica Neue',Arial,sans-serif;
--font-body: 'HelveticaNowDisplayW01-Rg','Helvetica Neue',Arial,sans-serif;
--ink: #0a0a0a;
--ink-70: rgba(10,10,10,0.70);
--ink-45: rgba(10,10,10,0.45);
--ink-20: rgba(10,10,10,0.20);
--ink-10: rgba(10,10,10,0.10);
--ink-06: rgba(10,10,10,0.06);
--ink-03: rgba(10,10,10,0.03);
--surface: #f4f3ef;
--surface-2: #eeecea;
--card: #ffffff;
--radius-pill: 9999px;
--radius-xl: 24px;
--radius-lg: 18px;
--radius-md: 12px;
--shadow-xs: 0 1px 2px rgba(0,0,0,0.06);
--shadow-sm: 0 2px 10px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04);
--shadow-md: 0 6px 28px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.05);
--shadow-inset: inset 0 1px 0 rgba(255,255,255,0.8);
}
@keyframes fade-up {
from { opacity:0; transform:translateY(14px); }
to { opacity:1; transform:none; }
}
@keyframes spin { to { transform:rotate(360deg); } }
*,*::before,*::after { margin:0; padding:0; box-sizing:border-box; }
html {
font-family: var(--font-body);
-webkit-font-smoothing: antialiased;
background: var(--surface);
color: var(--ink);
}
body {
min-height: 100vh;
background: var(--surface);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.028'/%3E%3C/svg%3E");
padding: 0 28px 100px;
font-family: var(--font-body);
}
/* ─── Layout ─────────────────────────────────────────────── */
.container {
max-width: 1260px;
margin: 0 auto;
animation: fade-up .65s cubic-bezier(.22,1,.36,1) backwards;
animation-delay: .04s;
}
/* ─── Page Header ────────────────────────────────────────── */
.header {
padding: 42px 0 28px;
border-bottom: 1px solid var(--ink-10);
margin-bottom: 0;
}
/* Eyebrow */
.header::before {
content: '✦ Z-Library Search';
display: inline-block;
font-size: 11px;
font-weight: 600;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--ink-45);
margin-bottom: 14px;
padding: 6px 14px;
background: var(--card);
border: 1px solid var(--ink-10);
border-radius: var(--radius-pill);
box-shadow: var(--shadow-xs);
}
.header h1 {
font-family: var(--font-heading);
font-size: clamp(30px, 5.5vw, 50px);
font-weight: 500;
letter-spacing: -0.055em;
line-height: 1.0;
color: var(--ink);
margin-bottom: 8px;
}
.header p {
font-size: 14px;
color: var(--ink-45);
line-height: 1.5;
}
/* ─── Search Section ─────────────────────────────────────── */
.search-section {
padding: 26px 0;
border-bottom: 1px solid var(--ink-06);
}
.search-form {
display: flex;
gap: 10px;
align-items: flex-end;
flex-wrap: wrap;
}
.form-group { flex:1; min-width:200px; }
.form-group label {
display: block;
margin-bottom: 7px;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .1em;
color: var(--ink-45);
}
.form-group input {
width: 100%;
padding: 11px 18px;
border: 1px solid var(--ink-10);
border-radius: var(--radius-pill);
font-size: 14px;
font-family: var(--font-body);
background: var(--card);
color: var(--ink);
box-shadow: var(--shadow-xs), var(--shadow-inset);
transition: border-color .2s, box-shadow .2s;
-webkit-appearance: none;
}
.form-group input:focus {
outline: none;
border-color: var(--ink-45);
box-shadow: 0 0 0 3px rgba(10,10,10,.07), var(--shadow-inset);
}
.form-group input::placeholder { color: var(--ink-20); }
.form-group small {
display: block;
margin-top: 6px;
font-size: 11px;
color: var(--ink-45);
padding-left: 10px;
}
/* ─── Checkbox pills ─────────────────────────────────────── */
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 16px;
}
.checkbox-group label {
display: inline-flex;
align-items: center;
gap: 7px;
font-size: 13px;
letter-spacing: -0.01em;
color: var(--ink-70);
background: var(--card);
border: 1px solid var(--ink-10);
border-radius: var(--radius-pill);
padding: 6px 16px;
cursor: pointer;
box-shadow: var(--shadow-xs), var(--shadow-inset);
user-select: none;
transition: background .18s, color .18s, border-color .18s, box-shadow .18s;
}
.checkbox-group label:hover {
background: var(--ink);
color: #fff;
border-color: var(--ink);
box-shadow: var(--shadow-sm);
}
.checkbox-group input[type="checkbox"] {
accent-color: var(--ink);
width: 13px; height: 13px; cursor: pointer;
}
/* ─── Buttons ────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 9px 22px;
border-radius: var(--radius-pill);
font-size: 13px;
font-family: var(--font-body);
letter-spacing: -0.01em;
cursor: pointer;
border: 1px solid var(--ink-10);
text-decoration: none;
white-space: nowrap;
background: var(--card);
color: var(--ink);
box-shadow: var(--shadow-xs), var(--shadow-inset);
margin: 0 5px 5px 0;
line-height: 1;
position: relative;
overflow: hidden;
transition: background .2s, color .2s, border-color .2s, box-shadow .2s,
transform .18s cubic-bezier(.22,1,.36,1);
}
.btn:hover:not(:disabled) {
background: var(--ink);
color: #fff;
border-color: var(--ink);
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
.btn:active:not(:disabled) { transform:scale(.97) translateY(0); box-shadow:var(--shadow-xs); }
.btn:disabled { opacity:.35; cursor:not-allowed; }
.btn-primary { background:var(--ink); color:#fff; border-color:var(--ink); box-shadow:var(--shadow-sm); }
.btn-primary:hover:not(:disabled) { background:#1a1a1a; }
.btn-download { background:var(--ink); color:#fff; border-color:var(--ink); box-shadow:var(--shadow-sm); }
.btn-download:hover:not(:disabled) { background:#1a1a1a; }
/* ─── Results Section ────────────────────────────────────── */
.results-section { padding: 26px 0; }
/* ─── Stats Bar — horizontal card row ───────────────────── */
.stats-bar {
display: flex;
background: var(--card);
border: 1px solid var(--ink-10);
border-radius: var(--radius-xl);
margin-bottom: 26px;
overflow: hidden;
box-shadow: var(--shadow-sm), var(--shadow-inset);
flex-wrap: wrap;
}
.stat-item {
flex: 1;
min-width: 120px;
padding: 22px 26px;
border-right: 1px solid var(--ink-06);
position: relative;
}
.stat-item:last-child { border-right: none; }
.stat-item::before {
content: '';
position: absolute;
top: 0; left: 26px; right: 26px;
height: 1.5px;
background: linear-gradient(90deg, transparent 0%, var(--ink-10) 50%, transparent 100%);
}
.stat-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .1em;
color: var(--ink-45);
margin-bottom: 6px;
}
.stat-value {
font-family: var(--font-heading);
font-size: clamp(24px, 3.5vw, 34px);
font-weight: 500;
letter-spacing: -0.05em;
color: var(--ink);
line-height: 1.05;
}
/* ─── Books Grid ─────────────────────────────────────────── */
.books-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
gap: 1px;
background: var(--ink-10);
border: 1px solid var(--ink-10);
border-radius: var(--radius-xl);
overflow: hidden;
margin-top: 18px;
box-shadow: var(--shadow-sm);
}
.book-card {
background: var(--card);
padding: 22px 20px 18px;
position: relative;
transition: background .18s;
}
.book-card:hover { background: #fdfcf9; }
.book-card.selected {
background: rgba(10,10,10,0.025);
box-shadow: inset 3px 0 0 var(--ink);
}
.book-checkbox {
position: absolute;
top: 18px; right: 18px;
width: 15px; height: 15px;
accent-color: var(--ink);
cursor: pointer;
}
.book-title {
font-size: 14px;
font-weight: 500;
letter-spacing: -0.02em;
color: var(--ink);
margin-bottom: 4px;
line-height: 1.4;
padding-right: 26px;
}
.book-authors {
font-size: 12px;
color: var(--ink-45);
margin-bottom: 14px;
}
.book-details {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 10px;
margin-bottom: 14px;
padding-bottom: 14px;
border-bottom: 1px solid var(--ink-06);
}
.detail-item { font-size: 11px; }
.detail-label {
color: var(--ink-45);
text-transform: uppercase;
font-size: 9.5px;
letter-spacing: .07em;
font-weight: 700;
margin-bottom: 1px;
}
.detail-value { color: var(--ink-70); }
.book-link {
display: inline-block;
font-size: 12px;
color: var(--ink);
text-decoration: underline;
text-underline-offset: 2px;
text-decoration-color: var(--ink-20);
transition: text-decoration-color .18s;
}
.book-link:hover { text-decoration-color: var(--ink); }
/* ─── Loading ─────────────────────────────────────────────── */
.loading { text-align:center; padding:80px 20px; display:none; }
.spinner {
width:26px; height:26px;
border:1.5px solid var(--ink-10);
border-top-color: var(--ink);
border-radius:50%;
animation:spin .7s linear infinite;
margin:0 auto 16px;
}
.loading p { font-size:13px; color:var(--ink-45); }
/* ─── Misc ───────────────────────────────────────────────── */
.progress-container { margin-top:12px; }
.progress-text { font-size:11px; color:var(--ink-45); margin-top:5px; }
.error-message {
background:var(--card);
border:1px solid var(--ink-10);
color:var(--ink-70);
padding:12px 18px;
border-radius:var(--radius-md);
margin:14px 0;
font-size:13px;
display:none;
box-shadow:var(--shadow-xs);
}
.empty-state { text-align:center; padding:80px 24px; color:var(--ink-45); }
.empty-state h3 {
font-family:var(--font-heading);
font-size:20px;
font-weight:500;
letter-spacing:-0.04em;
color:var(--ink);
margin-bottom:8px;
}
.empty-state p { font-size:14px; }
.download-section { display:flex; gap:6px; flex-wrap:wrap; margin:18px 0; }
.selection-bar {
display:flex;
align-items:center;
justify-content:space-between;
padding:12px 0;
border-bottom:1px solid var(--ink-06);
margin-bottom:14px;
flex-wrap:wrap;
gap:10px;
}
.selection-controls { display:flex; align-items:center; gap:10px; }
.selection-controls label {
display:inline-flex;
align-items:center;
gap:7px;
font-size:13px;
color:var(--ink);
cursor:pointer;
}
.selection-controls label input { accent-color:var(--ink); }
.selection-info { font-size:12px; color:var(--ink-45); }
.stats-detail { margin-top:30px; padding-top:22px; border-top:1px solid var(--ink-10); }
.stats-detail h3 {
font-size:10px;
font-weight:700;
letter-spacing:.1em;
text-transform:uppercase;
color:var(--ink-45);
margin-bottom:16px;
}
hr { border:none; border-top:1px solid var(--ink-06); margin:14px 0; }
.load-more-container { margin-top:28px; text-align:center; }
.load-more-btn { width:100%; padding:13px; font-size:13px; }
#resultCountHeader {
font-size:10px;
font-weight:700;
letter-spacing:.1em;
text-transform:uppercase;
color:var(--ink-45);
margin:20px 0 14px;
}