html, body {
    margin: 0;
    padding: 0;
    background-color: #121212;
}

/* Prevent horizontal scroll */
.mud-main-content {
    overflow-x: hidden;
}

/* Locked chapter row style */
.chapter-locked {
    opacity: 0.5;
    cursor: not-allowed !important;
}

/* Chapter still downloading on the server — clickable but visually muted. */
.chapter-pending td {
    opacity: 0.7;
}

/* Reader images — crisp rendering */
#reader-container img {
    image-rendering: auto;
    max-width: 100%;
}

/*
 * Pinch-to-zoom on chapter pages is enabled via the meta viewport
 * (user-scalable=yes) and Android WebView's BuiltInZoomControls. We leave
 * touch-action at its default — explicit values like `pan-y pinch-zoom`
 * actually break native pinch on Android WebView.
 */

#reader-container .reader-image-slot {
    position: relative;
}

#reader-container .reader-image-error {
    background: #1f1f29;
    color: #d8d8e0;
    border: 1px dashed #4a4a55;
    border-radius: 6px;
    padding: 1.5rem 1rem;
    margin-bottom: 2px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    min-height: 140px;
    justify-content: center;
}

#reader-container .reader-image-error small {
    color: #9a9aa6;
}

/* Subtle progress chip while images download in the background for offline use. */
.reader-cache-chip {
    margin: 8px 12px;
    padding: 6px 10px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
    color: #b8b8c2;
    font-size: 12px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* MudDataGrid row pointer */
.cursor-pointer td {
    cursor: pointer;
}

/* Novel drawer layout: Add Novel → scrollable list → NSFW toggle pinned at bottom */
.mud-drawer .mud-drawer-content {
    height: 100%;
}

.novel-drawer-root {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.novel-drawer-scroll {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
    /* Prevent scroll-chaining: when the drawer reaches its top/bottom the
       page underneath shouldn't start scrolling. */
    overscroll-behavior: contain;
}

/* Section header that introduces the NSFW group at the bottom of the drawer. */
.novel-drawer-nsfw-divider {
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 12px 0 6px;
    padding: 0 12px;
    position: relative;
}

.novel-drawer-nsfw-divider::before,
.novel-drawer-nsfw-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.08);
    margin: 0 8px;
}

.novel-drawer-footer {
    flex-shrink: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Reader bottom nav — sticky mode toggled by tapping an image */
.reader-nav-sticky {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1100;
    border-radius: 0 !important;
}

/* Bottom navigation bar — Prev / Hamburger / Next.
   Buttons stretch to fill the space (large tap targets) and the hamburger
   gets generous side padding so it isn't accidentally hit when reaching
   for Prev or Next. */
.reader-nav-bar {
    display: flex;
    align-items: stretch;
    gap: 0;
    padding: 6px;
    border-radius: 0 !important;
}

.reader-nav-bar__btn {
    flex: 1 1 0;
    min-width: 0;
    height: 56px;
    font-size: 1rem;
    letter-spacing: 0.04em;
}

.reader-nav-bar__menu {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 18px;
    flex: 0 0 auto;
}

/* ── Pull-to-next-chapter ────────────────────────────────────────────────
   Lives below the last image. Static state shows a subtle "pull up" hint;
   as the user drags upward past the bottom of the document we map the drag
   distance to --pull-progress (0..1) which expands the panel and animates
   the sprint motion lines faster. At progress >= 1 the panel re-colors and
   swaps the label, signalling that releasing will navigate. */
.reader-pull-to-next {
    --pull-progress: 0;
    position: relative;
    margin: 8px auto 32px;
    padding: 14px 16px calc(14px + var(--pull-progress) * 32px);
    text-align: center;
    color: #b8b8c2;
    border-top: 1px dashed rgba(255, 255, 255, 0.08);
    cursor: pointer;
    overflow: hidden;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    transition: padding 80ms linear, background-color 120ms ease, color 120ms ease;
    background: linear-gradient(to bottom,
        rgba(124, 77, 255, 0) 0%,
        rgba(124, 77, 255, calc(var(--pull-progress) * 0.16)) 100%);
}

.reader-pull-to-next.reader-pull-to-next--armed {
    color: #fff;
    background: linear-gradient(to bottom,
        rgba(187, 134, 252, 0.08) 0%,
        rgba(187, 134, 252, 0.32) 100%);
}

.reader-pull-to-next__body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    position: relative;
    z-index: 1;
}

.reader-pull-to-next__runner {
    font-size: calc(28px + var(--pull-progress) * 16px) !important;
    color: inherit;
    transform: translateX(calc(var(--pull-progress) * 12px));
    transition: transform 80ms linear, font-size 80ms linear;
}

.reader-pull-to-next__text {
    font-size: 13px;
    letter-spacing: 0.02em;
}

.reader-pull-to-next__hint {
    display: inline;
}
.reader-pull-to-next__armed {
    display: none;
    font-weight: 600;
}
.reader-pull-to-next.reader-pull-to-next--armed .reader-pull-to-next__hint {
    display: none;
}
.reader-pull-to-next.reader-pull-to-next--armed .reader-pull-to-next__armed {
    display: inline;
}

/* Sprint effect — three motion lines streaking across the panel. They sit
   behind the runner; their animation speed scales with the pull progress so
   the harder the user pulls, the faster the lines streak. */
.reader-pull-to-next__sprint {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
    opacity: calc(0.25 + var(--pull-progress) * 0.75);
}

.reader-pull-to-next__sprint .sprint-line {
    position: absolute;
    left: -40%;
    height: 2px;
    width: 40%;
    background: linear-gradient(to right,
        rgba(187, 134, 252, 0),
        rgba(187, 134, 252, 0.85));
    border-radius: 2px;
    animation: sprint-streak 1.6s linear infinite;
    animation-duration: calc(1.6s - var(--pull-progress) * 1.2s);
}

.reader-pull-to-next__sprint .sprint-line:nth-child(1) { top: 22%; animation-delay: 0s;   }
.reader-pull-to-next__sprint .sprint-line:nth-child(2) { top: 50%; animation-delay: 0.4s; width: 55%; }
.reader-pull-to-next__sprint .sprint-line:nth-child(3) { top: 78%; animation-delay: 0.8s; width: 30%; }

@keyframes sprint-streak {
    0%   { transform: translateX(0);     opacity: 0; }
    20%  { opacity: 1; }
    100% { transform: translateX(360%);  opacity: 0; }
}

/* Error boundary */
.blazor-error-boundary {
    background: #b32121;
    padding: 1rem;
    color: white;
}
