/*
 * Homepage card rails.
 *
 * PHP emits Splide's final track/list/slide tree. Until Splide initializes,
 * that same tree is a native horizontal scroller with identical card widths,
 * 16px gaps and 20px edge breathing room. This keeps the layout stable and
 * usable if JavaScript or the CDN dependency is unavailable.
 */
.mz-splide-carousel {
    --mz-rail-fade-width: 56px;
    --mz-rail-card-width: 160px;
    position: relative;
    visibility: visible;
    direction: rtl;
}

.mz-splide-carousel.mz-wide-card-carousel {
    --mz-rail-card-width: 200px;
}

.mz-splide-carousel .splide__track {
    touch-action: pan-y pinch-zoom;
}

.mz-splide-carousel:not(.is-initialized) .splide__track {
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
}

.mz-splide-carousel:not(.is-initialized) .splide__track::-webkit-scrollbar {
    display: none;
}

.mz-splide-carousel:not(.is-initialized) .splide__list {
    box-sizing: border-box;
    width: max-content;
    min-width: 100%;
    height: auto;
    gap: 16px;
    padding-inline: 20px !important;
    transform: none !important;
}

/* CSS is the single owner of card dimensions; Splide only owns movement. */
.mz-splide-carousel .splide__slide {
    width: auto;
    height: auto;
    flex-shrink: 0;
}

/* Splide's core stylesheet uses backface hiding as a generic 3D safeguard.
 * These rails translate only in 2D, so that declaration needlessly retains a
 * layer for every list and card. The moving list is promoted explicitly by
 * .is-mz-moving below and demoted again after it settles. */
.mz-splide-carousel .splide__list,
.mz-splide-carousel .splide__slide {
    -webkit-backface-visibility: visible;
    backface-visibility: visible;
}

/* Keep the initial GPU surface close to the viewport instead of rasterizing
 * every card in a long transformed list. The head bootstrap is fail-open, and
 * carousel-splide.js replaces these provisional values with an exact buffered
 * visibility window before interaction begins. */
html.mz-carousel-window-pending .mz-splide-carousel:not(.is-mz-visibility-fallback) .splide__slide:nth-child(n + 11) {
    visibility: hidden !important;
}

html.mz-carousel-window-pending .mz-splide-carousel.is-mz-visibility-fallback .splide__slide {
    visibility: visible !important;
}

/* style.css historically promoted every native rail to a compositor layer.
 * Splide moves only its inner list, so the root must remain an ordinary layer. */
.carousel-draggable {
    will-change: auto;
}

/* Card rails are gesture surfaces, not selectable reading content. Apply this
 * before initialization so a slow mobile load cannot begin a native selection. */
.carousel-draggable,
.carousel-draggable *,
.mz-splide-carousel,
.mz-splide-carousel * {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.carousel-draggable,
.mz-splide-carousel {
    touch-action: pan-y pinch-zoom;
}

.carousel-draggable a,
.carousel-draggable img,
.mz-splide-carousel a,
.mz-splide-carousel img {
    -webkit-user-drag: none;
    user-drag: none;
}

/* Splide's fixedWidth option reads the same responsive value through
 * --mz-rail-card-width. These rules also preserve the exact native fallback. */
.mz-splide-carousel .splide__slide[class~="w-[160px]"] {
    width: 160px !important;
    min-width: 160px !important;
    max-width: 160px !important;
    flex: 0 0 160px !important;
}

.mz-splide-carousel .splide__slide[class~="min-w-[200px]"] {
    width: 200px !important;
    min-width: 200px !important;
    max-width: 200px !important;
    flex: 0 0 200px !important;
}

/* A desktop mouse/pointer gets the larger cards. Touch devices retain the
 * compact card size even when they expose a tablet-sized viewport. */
@media (min-width: 768px) and (hover: hover) and (pointer: fine) {
    .mz-splide-carousel:not(.mz-wide-card-carousel) {
        --mz-rail-card-width: 190px;
    }

    .mz-splide-carousel .splide__slide[class~="md:w-[190px]"] {
        width: 190px !important;
        min-width: 190px !important;
        max-width: 190px !important;
        flex-basis: 190px !important;
    }
}

/* The market card appends a price ticket below the common manga card. Keep its
 * width locked in both the native fallback and enhanced states. */
.mz-market-carousel .splide__slide {
    width: 160px !important;
    min-width: 160px !important;
    max-width: 160px !important;
    flex: 0 0 160px !important;
}

@media (min-width: 768px) and (hover: hover) and (pointer: fine) {
    .mz-market-carousel .splide__slide {
        width: 190px !important;
        min-width: 190px !important;
        max-width: 190px !important;
        flex-basis: 190px !important;
    }
}

/* Keep the cover's rounded silhouette without clipping the whole painted
 * subtree as one GPU surface. The children occupy the cover's inner border
 * box, so their radius is exactly the outer 12/16px radius minus its 1px
 * border. Geometry, colour, shadow and hit targets remain unchanged. */
.mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] {
    overflow: visible !important;
}

.mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > img,
.mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > .w-full.h-full,
.mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > .absolute.inset-0 {
    border-radius: 11px !important;
}

@media (min-width: 768px) {
    .mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > img,
    .mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > .w-full.h-full,
    .mz-splide-carousel:not(.mz-market-carousel) .splide__slide .aspect-\[2\/3\] > .absolute.inset-0 {
        border-radius: 15px !important;
    }
}

/* ---- Lightweight card chrome -----------------------------------------
 * backdrop-filter samples and blurs the moving cover behind every chip. A
 * viewport containing two rails can therefore create dozens of live backdrop
 * surfaces. These near-opaque layered gradients retain the dark glass visual,
 * contrast and fine highlight without any backdrop readback while moving. */
.mz-splide-carousel .mz-card-chip,
.mz-splide-carousel .backdrop-blur-md {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
}

.mz-splide-carousel .mz-card-chip {
    border-color: rgba(255, 255, 255, 0.12) !important;
    background: linear-gradient(145deg, rgba(29, 29, 35, 0.97), rgba(8, 8, 11, 0.96)) !important;
    box-shadow:
        0 3px 9px rgba(0, 0, 0, 0.28),
        inset 0 1px 0 rgba(255, 255, 255, 0.07) !important;
}

/* The desktop status pill is the only backdrop-blur-md element in a card. */
.mz-splide-carousel .backdrop-blur-md {
    border-color: rgba(255, 255, 255, 0.14) !important;
    background: linear-gradient(145deg, rgba(27, 27, 33, 0.97), rgba(7, 7, 10, 0.96)) !important;
    box-shadow:
        0 4px 11px rgba(0, 0, 0, 0.3),
        inset 0 1px 0 rgba(255, 255, 255, 0.07) !important;
}

/* Keep depth, but collapse the compiled multi-shadow card treatment to one
 * restrained shadow that rasterizes cheaply. Type colours remain unchanged. */
.mz-splide-carousel .shadow-black\/50 {
    box-shadow: 0 8px 18px rgba(0, 0, 0, 0.3) !important;
}

.mz-splide-carousel .manga-type-badge {
    top: -3px !important;
    opacity: 1 !important;
    text-shadow: none !important;
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.28),
        inset 0 1px 0 rgba(255, 255, 255, 0.13) !important;
}

.mz-splide-carousel .drop-shadow-lg {
    filter: none !important;
}

/* A stationary pointer used to activate several hover transitions on every
 * card passing beneath it. During movement, make the active rail a single
 * compositor job; hover interaction returns as soon as snapping completes. */
.mz-splide-carousel.is-mz-moving .splide__list {
    will-change: transform;
}

.mz-splide-carousel.is-mz-moving .group {
    pointer-events: none !important;
}

.mz-splide-carousel.is-mz-moving .group,
.mz-splide-carousel.is-mz-moving .group * {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation: none !important;
}

@media (hover: hover) {
    .mz-splide-carousel.is-initialized.is-mz-overflow {
        cursor: grab;
    }

    .mz-splide-carousel.is-initialized.is-mz-overflow:active {
        cursor: grabbing;
    }
}

/* ---- Edge fades -------------------------------------------------------
 * A rail that continues past an edge should say so. These overlays change
 * only opacity and never mask the moving list, avoiding re-rasterization while
 * cards move underneath them. Each section supplies --mz-rail-fade so the
 * opaque outside pixel exactly matches its background. */
.mz-splide-carousel::before,
.mz-splide-carousel::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: var(--mz-rail-fade-width);
    z-index: 30;
    pointer-events: none;
    background: var(--mz-rail-fade, #080808);
    opacity: 0;
    transition: opacity 0.28s ease;
}

.mz-splide-carousel::before {
    left: 0;
    -webkit-mask-image: linear-gradient(to right, #fff, transparent);
    mask-image: linear-gradient(to right, #fff, transparent);
}

.mz-splide-carousel::after {
    right: 0;
    -webkit-mask-image: linear-gradient(to left, #fff, transparent);
    mask-image: linear-gradient(to left, #fff, transparent);
}

.mz-splide-carousel.is-fade-left::before,
.mz-splide-carousel.is-fade-right::after {
    opacity: 1;
}

@media (max-width: 767px) {
    .mz-splide-carousel {
        --mz-rail-fade-width: 36px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .mz-splide-carousel::before,
    .mz-splide-carousel::after {
        transition: none;
    }
}
