/* ── Animations ──────────────────────────────────────────────────────────── */ @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.97) } to { opacity: 1; transform: scale(1) } } @keyframes pulse { 0%,100% { opacity: 0.4 } 50% { opacity: 0.8 } } /* ── Backdrop ────────────────────────────────────────────────────────────── */ .backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.72); z-index: var(--z-settings); display: flex; align-items: center; justify-content: center; animation: fadeIn 0.12s ease both; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } /* ── Modal shell ─────────────────────────────────────────────────────────── */ .modal { width: min(800px, calc(100vw - 48px)); height: min(560px, calc(100vh - 80px)); display: flex; background: var(--bg-surface); border: 1px solid var(--border-base); border-radius: var(--radius-xl); overflow: hidden; animation: scaleIn 0.16s ease both; box-shadow: 0 0 0 1px var(--border-dim), 0 24px 64px rgba(0,0,0,0.6), 0 8px 24px rgba(0,0,0,0.4); } /* ── Cover column ────────────────────────────────────────────────────────── */ .coverCol { width: 190px; flex-shrink: 0; background: var(--bg-raised); border-right: 1px solid var(--border-dim); display: flex; flex-direction: column; padding: var(--sp-5) var(--sp-4) var(--sp-4); gap: var(--sp-3); overflow-y: auto; overflow-x: hidden; scrollbar-width: none; } .coverCol::-webkit-scrollbar { display: none; } .coverWrap { position: relative; width: 100%; } .cover { width: 100%; aspect-ratio: 2 / 3; object-fit: cover; border-radius: var(--radius-md); border: 1px solid var(--border-dim); display: block; } .coverSpinner { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.35); border-radius: var(--radius-md); color: var(--text-faint); } .coverActions { display: flex; flex-direction: column; gap: var(--sp-2); } /* ── Cover action buttons ────────────────────────────────────────────────── */ .actionBtn { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); width: 100%; padding: 7px var(--sp-3); border-radius: var(--radius-md); font-family: var(--font-ui); font-size: var(--text-xs); letter-spacing: var(--tracking-wide); border: 1px solid var(--border-strong); background: none; color: var(--text-muted); cursor: pointer; transition: color var(--t-base), border-color var(--t-base), background var(--t-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; } .actionBtn:hover:not(:disabled) { color: var(--accent-fg); border-color: var(--accent); background: var(--accent-muted); } .actionBtn:disabled { opacity: 0.4; cursor: default; } .actionBtnActive { background: var(--accent-muted); border-color: var(--accent-dim); color: var(--accent-fg); } .actionBtnActive:hover:not(:disabled) { filter: brightness(1.1); } .actionBtnFolder { color: var(--text-secondary); border-color: var(--border-strong); } .actionBtnLabel { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; } /* ── Folder picker ───────────────────────────────────────────────────────── */ .folderWrap { position: relative; width: 100%; } .folderMenu { position: absolute; bottom: calc(100% + 4px); left: 0; right: 0; background: var(--bg-raised); border: 1px solid var(--border-base); border-radius: var(--radius-md); padding: var(--sp-1); display: flex; flex-direction: column; gap: 1px; box-shadow: 0 8px 24px rgba(0,0,0,0.5); z-index: 10; animation: scaleIn 0.1s ease both; transform-origin: bottom center; } .folderEmpty { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-faint); padding: var(--sp-2) var(--sp-3); } .folderItem { display: flex; align-items: center; gap: var(--sp-2); padding: 6px var(--sp-3); border-radius: var(--radius-sm); font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-muted); background: none; border: none; cursor: pointer; text-align: left; transition: background var(--t-fast), color var(--t-fast); } .folderItem:hover { background: var(--bg-overlay); color: var(--text-primary); } .folderItemOn { color: var(--accent-fg); } .folderDivider { height: 1px; background: var(--border-dim); margin: var(--sp-1) 0; } .folderCreateRow { display: flex; gap: var(--sp-1); padding: var(--sp-1); } .folderInput { flex: 1; background: var(--bg-overlay); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 4px 8px; color: var(--text-secondary); font-family: var(--font-ui); font-size: var(--text-xs); outline: none; min-width: 0; } .folderInput:focus { border-color: var(--border-focus); } .folderOkBtn { font-family: var(--font-ui); font-size: var(--text-xs); padding: 4px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border-strong); background: none; color: var(--text-muted); cursor: pointer; flex-shrink: 0; transition: color var(--t-base); } .folderOkBtn:disabled { opacity: 0.4; cursor: default; } .folderOkBtn:not(:disabled):hover { color: var(--accent-fg); border-color: var(--accent); } .folderNewBtn { padding: 6px var(--sp-3); border-radius: var(--radius-sm); font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-faint); background: none; border: none; cursor: pointer; text-align: left; width: 100%; transition: color var(--t-fast); } .folderNewBtn:hover { color: var(--accent-fg); } /* ── Content column ──────────────────────────────────────────────────────── */ .content { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; } /* ── Header ──────────────────────────────────────────────────────────────── */ .contentHeader { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-5) var(--sp-6) var(--sp-4); border-bottom: 1px solid var(--border-dim); flex-shrink: 0; } .titleBlock { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); } .title { font-size: var(--text-lg); font-weight: var(--weight-medium); color: var(--text-primary); letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); } .byline { font-size: var(--text-sm); color: var(--text-muted); line-height: var(--leading-snug); } .skByline { height: 14px; width: 55%; background: var(--bg-overlay); border-radius: var(--radius-sm); animation: pulse 1.4s ease infinite; } .closeBtn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-sm); color: var(--text-faint); border: none; background: none; cursor: pointer; flex-shrink: 0; transition: color var(--t-base), background var(--t-base); } .closeBtn:hover { color: var(--text-muted); background: var(--bg-raised); } /* ── Scrollable body ─────────────────────────────────────────────────────── */ .contentBody { flex: 1; overflow-y: auto; padding: var(--sp-5) var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-4); scrollbar-width: thin; } /* ── Error banner ────────────────────────────────────────────────────────── */ .errorBanner { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--color-warn, #f59e0b); background: color-mix(in srgb, var(--color-warn, #f59e0b) 10%, transparent); border: 1px solid color-mix(in srgb, var(--color-warn, #f59e0b) 25%, transparent); border-radius: var(--radius-sm); padding: 6px var(--sp-3); } /* ── Skeleton rows ───────────────────────────────────────────────────────── */ .skRow { display: flex; gap: var(--sp-2); align-items: center; } .skBadge { height: 20px; width: 54px; background: var(--bg-overlay); border-radius: var(--radius-sm); animation: pulse 1.4s ease infinite; } .skDesc { display: flex; flex-direction: column; gap: 8px; padding: var(--sp-2) 0; } .skLine { height: 13px; background: var(--bg-overlay); border-radius: var(--radius-sm); animation: pulse 1.4s ease infinite; } /* ── Badges ──────────────────────────────────────────────────────────────── */ .badges { display: flex; flex-wrap: wrap; gap: var(--sp-2); } .badge { font-family: var(--font-ui); font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; padding: 3px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); background: var(--bg-raised); color: var(--text-faint); } .badgeGreen { background: color-mix(in srgb, #22c55e 12%, transparent); border-color: color-mix(in srgb, #22c55e 30%, transparent); color: #22c55e; } .badgeDim { /* default */ } .badgeAccent { background: var(--accent-muted); border-color: var(--accent-dim); color: var(--accent-fg); } .badgeUnread { background: color-mix(in srgb, #f59e0b 12%, transparent); border-color: color-mix(in srgb, #f59e0b 30%, transparent); color: #f59e0b; } .badgeNsfw { background: color-mix(in srgb, #ef4444 12%, transparent); border-color: color-mix(in srgb, #ef4444 30%, transparent); color: #ef4444; } /* ── Chapter box — clearly separated from description ────────────────────── */ .chapterBox { display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-4); background: var(--bg-raised); border: 1px solid var(--border-dim); border-radius: var(--radius-md); } .chapterLoading { display: flex; align-items: center; gap: var(--sp-2); } .chapterLoadingLabel { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-faint); letter-spacing: var(--tracking-wide); } .chapterMeta { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); } .chapterLabel { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-muted); letter-spacing: var(--tracking-wide); } .dlAllBtn { display: flex; align-items: center; gap: var(--sp-1); font-family: var(--font-ui); font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); padding: 3px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); background: none; color: var(--text-faint); cursor: pointer; flex-shrink: 0; transition: color var(--t-base), border-color var(--t-base); } .dlAllBtn:hover:not(:disabled) { color: var(--text-muted); border-color: var(--border-strong); } .dlAllBtn:disabled { opacity: 0.5; cursor: default; } .progressTrack { height: 3px; background: var(--bg-overlay); border-radius: var(--radius-full); overflow: hidden; } .progressFill { height: 100%; background: var(--accent); border-radius: var(--radius-full); transition: width 0.3s ease; } .readBtn { display: flex; align-items: center; gap: var(--sp-2); padding: 8px var(--sp-4); border-radius: var(--radius-md); font-family: var(--font-ui); font-size: var(--text-xs); letter-spacing: var(--tracking-wide); background: var(--accent-muted); border: 1px solid var(--accent-dim); color: var(--accent-fg); cursor: pointer; align-self: flex-start; transition: filter var(--t-base); } .readBtn:hover { filter: brightness(1.1); } /* ── Description block ───────────────────────────────────────────────────── */ .descBlock { display: flex; flex-direction: column; gap: var(--sp-2); border-top: 1px solid var(--border-dim); padding-top: var(--sp-3); } .desc { font-size: var(--text-sm); color: var(--text-muted); line-height: var(--leading-base); display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; } .descOpen { display: block; -webkit-line-clamp: unset; overflow: visible; } .descToggle { display: flex; align-items: center; gap: var(--sp-1); font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-faint); background: none; border: none; cursor: pointer; padding: 0; align-self: flex-start; transition: color var(--t-base); } .descToggle:hover { color: var(--accent-fg); } /* ── Genre tags ──────────────────────────────────────────────────────────── */ .genres { display: flex; flex-wrap: wrap; gap: var(--sp-1); } .genreTag { font-family: var(--font-ui); font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); padding: 3px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); background: var(--bg-raised); color: var(--text-faint); } .genreTagClickable { cursor: pointer; transition: color var(--t-base), border-color var(--t-base), background var(--t-base); } .genreTagClickable:hover { color: var(--accent-fg); border-color: var(--accent-dim); background: var(--accent-muted); } /* ── Metadata table ──────────────────────────────────────────────────────── */ .metaTable { display: flex; flex-direction: column; gap: 1px; border-top: 1px solid var(--border-dim); padding-top: var(--sp-3); } .metaRow { display: flex; align-items: baseline; gap: var(--sp-3); padding: 5px 0; } .metaKey { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-faint); letter-spacing: var(--tracking-wide); text-transform: uppercase; min-width: 56px; flex-shrink: 0; } .metaVal { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-snug); } .metaLink { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-sm); color: var(--accent-fg); text-decoration: none; transition: opacity var(--t-base); } .metaLink:hover { opacity: 0.75; }