Files
libnovel/ui/src/app.css
root 320f9fc76b
All checks were successful
Release / Test backend (push) Successful in 41s
Release / Check ui (push) Successful in 1m35s
Release / Docker (push) Successful in 5m53s
Release / Gitea Release (push) Successful in 29s
feat: add page fade transition and CSS performance improvements
- Wrap {#key} children in fade transition (out 100ms, in 180ms+60ms delay)
  for a smooth cross-fade between pages with no added dependencies
- Halve navigation progress bar animation duration (8s → 4s) for
  more realistic feedback on typical navigations
- Add prefers-reduced-motion media query to collapse all animation/transition
  durations for users with accessibility needs
- Add content-visibility: auto on footer to skip browser paint of
  off-screen content and improve rendering performance
2026-04-08 16:54:51 +05:00

269 lines
9.7 KiB
CSS

@import "tailwindcss";
@theme {
--color-brand: #f59e0b; /* amber-400 */
--color-brand-dim: #d97706; /* amber-600 */
--color-surface: #18181b; /* zinc-900 */
--color-surface-2: #27272a; /* zinc-800 */
--color-surface-3: #3f3f46; /* zinc-700 */
--color-muted: #a1a1aa; /* zinc-400 */
--color-text: #f4f4f5; /* zinc-100 */
--color-border: #3f3f46; /* zinc-700 */
--color-danger: #f87171; /* red-400 */
--color-success: #4ade80; /* green-400 */
}
/* ── Amber theme (default) — same as @theme above, explicit for clarity ── */
[data-theme="amber"] {
--color-brand: #f59e0b;
--color-brand-dim: #d97706;
--color-surface: #18181b;
--color-surface-2: #27272a;
--color-surface-3: #3f3f46;
--color-muted: #a1a1aa;
--color-text: #f4f4f5;
--color-border: #3f3f46;
--color-danger: #f87171;
--color-success: #4ade80;
}
/* ── Slate theme — indigo/slate dark ─────────────────────────────────── */
[data-theme="slate"] {
--color-brand: #818cf8; /* indigo-400 */
--color-brand-dim: #4f46e5; /* indigo-600 */
--color-surface: #0f172a; /* slate-900 */
--color-surface-2: #1e293b; /* slate-800 */
--color-surface-3: #334155; /* slate-700 */
--color-muted: #94a3b8; /* slate-400 */
--color-text: #f1f5f9; /* slate-100 */
--color-border: #334155; /* slate-700 */
--color-danger: #f87171; /* red-400 */
--color-success: #4ade80; /* green-400 */
}
/* ── Rose theme — dark pink ───────────────────────────────────────────── */
[data-theme="rose"] {
--color-brand: #fb7185; /* rose-400 */
--color-brand-dim: #e11d48; /* rose-600 */
--color-surface: #18181b; /* zinc-900 */
--color-surface-2: #1c1318; /* custom dark rose */
--color-surface-3: #2d1f26; /* custom dark rose-2 */
--color-muted: #a1a1aa; /* zinc-400 */
--color-text: #f4f4f5; /* zinc-100 */
--color-border: #3f2d36; /* custom rose border */
--color-danger: #f87171; /* red-400 */
--color-success: #4ade80; /* green-400 */
}
/* ── Light amber theme ────────────────────────────────────────────────── */
[data-theme="light"] {
--color-brand: #d97706; /* amber-600 */
--color-brand-dim: #b45309; /* amber-700 */
--color-surface: #ffffff;
--color-surface-2: #f4f4f5; /* zinc-100 */
--color-surface-3: #e4e4e7; /* zinc-200 */
--color-muted: #71717a; /* zinc-500 */
--color-text: #18181b; /* zinc-900 */
--color-border: #d4d4d8; /* zinc-300 */
--color-danger: #dc2626; /* red-600 */
--color-success: #16a34a; /* green-600 */
}
/* ── Light slate theme ────────────────────────────────────────────────── */
[data-theme="light-slate"] {
--color-brand: #4f46e5; /* indigo-600 */
--color-brand-dim: #4338ca; /* indigo-700 */
--color-surface: #f8fafc; /* slate-50 */
--color-surface-2: #f1f5f9; /* slate-100 */
--color-surface-3: #e2e8f0; /* slate-200 */
--color-muted: #64748b; /* slate-500 */
--color-text: #0f172a; /* slate-900 */
--color-border: #cbd5e1; /* slate-300 */
--color-danger: #dc2626; /* red-600 */
--color-success: #16a34a; /* green-600 */
}
/* ── Light rose theme ─────────────────────────────────────────────────── */
[data-theme="light-rose"] {
--color-brand: #e11d48; /* rose-600 */
--color-brand-dim: #be123c; /* rose-700 */
--color-surface: #fff1f2; /* rose-50 */
--color-surface-2: #ffe4e6; /* rose-100 */
--color-surface-3: #fecdd3; /* rose-200 */
--color-muted: #9f1239; /* rose-800 at 60% */
--color-text: #0f0a0b; /* near black */
--color-border: #fda4af; /* rose-300 */
--color-danger: #dc2626; /* red-600 */
--color-success: #16a34a; /* green-600 */
}
/* ── Forest theme — dark green ────────────────────────────────────────── */
[data-theme="forest"] {
--color-brand: #4ade80; /* green-400 */
--color-brand-dim: #16a34a; /* green-600 */
--color-surface: #0a130d; /* custom near-black green */
--color-surface-2: #111c14; /* custom dark green */
--color-surface-3: #1a2e1e; /* custom mid green */
--color-muted: #6b9a77; /* custom muted green */
--color-text: #e8f5e9; /* custom light green-tinted white */
--color-border: #1e3a24; /* custom green border */
--color-danger: #f87171; /* red-400 */
--color-success: #4ade80; /* green-400 */
}
/* ── Mono theme — pure dark with white accent ─────────────────────────── */
[data-theme="mono"] {
--color-brand: #f4f4f5; /* zinc-100 — white accent */
--color-brand-dim: #a1a1aa; /* zinc-400 */
--color-surface: #09090b; /* zinc-950 */
--color-surface-2: #18181b; /* zinc-900 */
--color-surface-3: #27272a; /* zinc-800 */
--color-muted: #71717a; /* zinc-500 */
--color-text: #f4f4f5; /* zinc-100 */
--color-border: #27272a; /* zinc-800 */
--color-danger: #f87171; /* red-400 */
--color-success: #4ade80; /* green-400 */
}
/* ── Cyberpunk theme — dark with neon cyan/magenta accents ────────────── */
[data-theme="cyber"] {
--color-brand: #22d3ee; /* cyan-400 — neon cyan */
--color-brand-dim: #06b6d4; /* cyan-500 */
--color-surface: #050712; /* custom near-black blue */
--color-surface-2: #0d1117; /* custom dark blue-black */
--color-surface-3: #161b27; /* custom dark blue */
--color-muted: #6272a4; /* dracula comment blue */
--color-text: #e2e8f0; /* slate-200 */
--color-border: #1e2d45; /* custom dark border */
--color-danger: #ff5555; /* dracula red */
--color-success: #50fa7b; /* dracula green */
}
html {
background-color: var(--color-surface);
color: var(--color-text);
}
/* ── Reading typography custom properties ──────────────────────────── */
:root {
--reading-font: system-ui, -apple-system, sans-serif;
--reading-size: 1.05rem;
--reading-line-height: 1.85;
--reading-max-width: 72ch;
}
/* ── Chapter prose ─────────────────────────────────────────────────── */
.prose-chapter {
max-width: var(--reading-max-width, 72ch);
line-height: var(--reading-line-height, 1.85);
font-family: var(--reading-font);
font-size: var(--reading-size);
color: var(--color-muted);
}
.prose-chapter h1,
.prose-chapter h2,
.prose-chapter h3 {
color: var(--color-text);
font-weight: 700;
margin-top: 1.5em;
margin-bottom: 0.5em;
}
.prose-chapter h1 { font-size: 1.4rem; }
.prose-chapter h2 { font-size: 1.2rem; }
.prose-chapter h3 { font-size: 1.05rem; }
.prose-chapter p {
margin-bottom: 1.2em;
}
/* Indented paragraph style — book-like, no gap, indent instead */
.prose-chapter.para-indented p {
text-indent: 2em;
margin-bottom: 0.35em;
}
.prose-chapter em {
color: var(--color-muted);
}
.prose-chapter strong {
color: var(--color-text);
}
.prose-chapter hr {
border-color: var(--color-border);
margin: 2em 0;
}
/* ── Reading progress bar ───────────────────────────────────────────── */
.reading-progress {
position: fixed;
top: 0;
left: 0;
height: 2px;
z-index: 100;
background: var(--color-brand);
pointer-events: none;
transition: width 0.1s linear;
}
/* ── Paginated reader ───────────────────────────────────────────────── */
.paginated-container {
overflow: hidden;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
}
.paginated-container .prose-chapter {
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform;
}
/* ── Hide scrollbars (used on horizontal carousels) ────────────────── */
.scrollbar-none {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE / Edge legacy */
}
.scrollbar-none::-webkit-scrollbar {
display: none; /* Chrome / Safari / WebKit */
}
/* ── Hero carousel fade ─────────────────────────────────────────────── */
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.animate-fade-in {
animation: fade-in 0.4s ease-out forwards;
}
/* ── Navigation progress bar ───────────────────────────────────────── */
@keyframes progress-bar {
0% { width: 0%; opacity: 1; }
80% { width: 90%; opacity: 1; }
100% { width: 100%; opacity: 0; }
}
.animate-progress-bar {
animation: progress-bar 4s cubic-bezier(0.1, 0.05, 0.1, 1) forwards;
}
/* ── Respect reduced motion — disable all decorative animations ─────── */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* ── Footer content-visibility — skip paint for off-screen footer ───── */
footer {
content-visibility: auto;
contain-intrinsic-size: auto 80px;
}