/*
 * Kino overrides on top of the StreamIT theme.
 * Plain CSS (no build step) to match how the template ships its own assets.
 */

/* Stand-in artwork for titles with no poster uploaded yet. Mirrors the
   dimensions of the .img-box <img> so card layout is unaffected. */
.kino-poster-fallback {
    display: flex;
    align-items: flex-end;
    width: 100%;
    aspect-ratio: 2 / 3;
    padding: 0.75rem;
    background-image: var(--kino-gradient);
}

.kino-poster-fallback__title {
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.25;
    color: #fff;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}

/* Landscape stand-in used on the detail page when there's no trailer. */
.kino-landscape-fallback {
    display: flex;
    align-items: flex-end;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 0.5rem;
    padding: 1.25rem;
    background-image: var(--kino-gradient);
    font-weight: 700;
    color: #fff;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}

/* The hero uses a DB-driven background image; keep it covering on all sizes. */
.banner-home-swiper-image,
.iq-banner-thumb-slider .slider--image {
    background-size: cover;
    background-position: center;
}

/*
 * Solid title text.
 *
 * The template's .texture-text sets color:transparent and clips a noise
 * bitmap (images/pages/texure.webp) into the glyphs, so titles render blotchy
 * and vary with whatever the texture happens to line up with. Real titles read
 * better as a flat colour, so the texture is dropped while the template's own
 * weight/line-height rules for the class still apply.
 */
.texture-text {
    color: #fff;
    background-image: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    -webkit-text-fill-color: currentColor;
}

/*
 * Header over the hero.
 *
 * The template absolutely positions the header but then pads .main-content by
 * the header height, so it sits *above* the artwork rather than over it. On
 * pages with a hero we drop that padding and fade the bar into the image;
 * hovering anywhere on it returns a solid background so the menu stays
 * readable against busy artwork.
 */
.kino-hero-home .main-content {
    padding-top: 0;
}

.kino-hero-home header.header-sticky:not(.sticky) {
    background: -webkit-linear-gradient(top, rgba(var(--bs-black-rgb), 0.85) 0%, rgba(var(--bs-black-rgb), 0.4) 55%, rgba(var(--bs-black-rgb), 0) 100%);
    background: -o-linear-gradient(top, rgba(var(--bs-black-rgb), 0.85) 0%, rgba(var(--bs-black-rgb), 0.4) 55%, rgba(var(--bs-black-rgb), 0) 100%);
    background: linear-gradient(to bottom, rgba(var(--bs-black-rgb), 0.85) 0%, rgba(var(--bs-black-rgb), 0.4) 55%, rgba(var(--bs-black-rgb), 0) 100%);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

/* Opaque on hover — applies on every page, not just the hero pages. */
header.header-sticky:hover,
.kino-hero-home header.header-sticky:not(.sticky):hover {
    background: rgb(var(--bs-black-rgb));
    -webkit-backdrop-filter: blur(0.625em);
    backdrop-filter: blur(0.625em);
}

/*
 * Hero trailer takeover. The video sits above the backdrop image but stays
 * earlier in the DOM than .container-fluid (which is position-relative), so
 * the slide's text keeps painting on top without needing a z-index war.
 */
.iq-banner-thumb-slider .slider--image {
    position: relative;
    overflow: hidden;
}

.kino-hero-video.video-js {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: transparent;
    opacity: 0;
    transition: opacity 900ms ease;
    pointer-events: none;
    z-index: 1;
}

/*
 * Extra darkening.
 *
 * The template's own scrim is a ::before, which paints *under* absolutely
 * positioned children — so once the trailer video faded in it covered the
 * scrim completely and the copy lost its contrast. This ::after sits above
 * the video (z-index 2) but below the text (z-index 3), so artwork and
 * trailer are darkened alike.
 */
.iq-banner-thumb-slider .slider .slider-bg .slider-images .slider--image::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    pointer-events: none;
    background:
        -webkit-linear-gradient(left, rgba(var(--bs-black-rgb), 0.68) 0%, rgba(var(--bs-black-rgb), 0.33) 35%, rgba(var(--bs-black-rgb), 0.08) 65%, rgba(var(--bs-black-rgb), 0) 100%),
        -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.58) 0%, rgba(var(--bs-black-rgb), 0.16) 38%, rgba(var(--bs-black-rgb), 0) 72%);
    background:
        linear-gradient(to right, rgba(var(--bs-black-rgb), 0.68) 0%, rgba(var(--bs-black-rgb), 0.33) 35%, rgba(var(--bs-black-rgb), 0.08) 65%, rgba(var(--bs-black-rgb), 0) 100%),
        linear-gradient(to top, rgba(var(--bs-black-rgb), 0.58) 0%, rgba(var(--bs-black-rgb), 0.16) 38%, rgba(var(--bs-black-rgb), 0) 72%);
}

/* Keep the title/description/buttons above the new scrim. */
.iq-banner-thumb-slider .slider .slider-bg .slider-images .slider--image > .container-fluid {
    z-index: 3;
}

.slider--image.is-trailer-playing .kino-hero-video.video-js {
    opacity: 1;
}

.kino-hero-video.video-js video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Respect users who don't want motion: never swap in the trailer. */
@media (prefers-reduced-motion: reduce) {
    .slider--image.is-trailer-playing .kino-hero-video.video-js {
        opacity: 0;
    }
}

/*
 * Hero thumbnails: the template ships these as tall 2/2.8 portraits with
 * mix-blend-mode overlay (which washes real photography out). We show small
 * 16:9 landscape stills instead, so they read as video, not book covers.
 */
/*
 * Reposition the hero thumb strip to match the StreamIT demo: the shipped HTML
 * template centres it vertically inside a dark gradient panel, whereas the demo
 * bottom-aligns a bare strip over the artwork.
 */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider {
    top: auto;
    bottom: 2.5em;
    /* Inset far enough that the "next" arrow, which hangs outside the strip,
       still lands inside the viewport instead of being clipped by the edge. */
    right: 4.5em;
    /* Wide enough that each thumb lands near the ~250px of the demo, but
       viewport-relative so it can't crowd out the hero copy on smaller
       screens. Paired with the slidesPerView breakpoints in swiper.js. */
    width: clamp(28em, 54vw, 66em);
    -webkit-transform: none;
    -ms-transform: none;
    transform: none;
    background: none;
    padding: 0;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav {
    padding-bottom: 0;
}

/* Arrows flank the strip instead of stacking under its left edge. */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav .slider-prev,
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav .slider-next {
    top: 50%;
    bottom: auto;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav .slider-prev {
    left: -2.75em;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav .slider-next {
    left: auto;
    right: -2.75em;
}

/* With too few featured titles to scroll, Swiper disables the arrows — say so
   rather than leaving them looking clickable. */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .banner-thumb-slider-nav .swiper-button-disabled {
    opacity: 0.3;
    pointer-events: none;
}

/* Bottom-aligned hero copy needs breathing room above the fold edge. */
.iq-banner-thumb-slider .slider .slider-bg .slider-images .swiper-wrapper .banner-bg .slider-content-full-height {
    padding-bottom: 5em;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .block-images .img-box img,
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .block-images .img-box .kino-thumb-fallback {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    /* Template shipped 0.5em here; 2px softer again per design review. */
    border-radius: calc(0.5em + 2px);
    /* Template blends the thumb into its gradient; that muddies real stills. */
    mix-blend-mode: normal;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .block-images .img-box .kino-thumb-fallback {
    background-image: var(--kino-gradient);
}

/* Keep the caption legible now that the image behind it is full-contrast. */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .block-images .img-box .block-description {
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.75);
}

/*
 * Thumbs are controls, so they need to look and behave like it: pointer
 * cursor, a hover lift, and a highlight ring on the one currently showing.
 * The template only styles an active state for its *vertical* thumb slider,
 * not this OTT strip, so it's added here.
 */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .swiper-slide {
    cursor: pointer;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .swiper-slide .img-box {
    /* Matches the thumb image radius so the highlight ring hugs the corners */
    border-radius: calc(0.5em + 2px);
    border: 2px solid transparent;
    -webkit-transition: border-color 250ms ease, opacity 250ms ease;
    -o-transition: border-color 250ms ease, opacity 250ms ease;
    transition: border-color 250ms ease, opacity 250ms ease;
    opacity: 0.65;
}

.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .swiper-slide:hover .img-box {
    opacity: 1;
}

/* Only the thumb whose title is playing. .swiper-slide-active is deliberately
   NOT matched: the strip always has its own active slide (the leftmost visible
   one), which showed a second ring. */
.iq-banner-thumb-slider .slider .slider-bg .horizontal_thumb_slider .swiper-slide.swiper-slide-thumb-active .img-box {
    border-color: rgba(255, 255, 255, 0.9);
    opacity: 1;
}

/* ------------------------------------------------------------------------
 * Card hover: zoom the artwork, never change the tile's footprint.
 *
 * The template's hover grows the card — margin-top:-1.875em, overflow:visible,
 * translate3d(±12%) on edge slides, plus an expanded border box via ::after —
 * which shoves neighbouring cards around. All of that is suppressed here; the
 * frame stays put and only the image scales inside it.
 * ------------------------------------------------------------------------ */

.card-hover:hover .block-images,
.card-hover.landscape-card-hover:hover .block-images,
.view-all-movies .card-hover:hover .block-images,
.card-style-grid:hover .block-images,
.card-style-slider li.swiper-slide.swiper-slide-active .card-hover:hover .block-images,
.card-style-slider li.swiper-slide.swiper-slide-active .card-hover.landscape-card-hover:hover .block-images,
.card-style-slider li.swiper-slide.swiper-active.last .card-hover:hover .block-images,
.card-style-slider li.swiper-slide.swiper-active.last .card-hover.landscape-card-hover:hover .block-images {
    /* !important: the template sets these across many deep selectors. */
    -webkit-transform: none !important;
    -ms-transform: none !important;
    transform: none !important;
    margin-top: 0 !important;
    overflow: hidden !important;
    z-index: auto;
}

/* The expanded bordered box that made the card look bigger. */
.iq-card:hover .block-images::after {
    opacity: 0;
    visibility: hidden;
}

/* Artwork: true colours (template blends it to overlay), dimmed at rest,
   brightening and zooming on hover — the fade effect. */
.iq-card .block-images .img-box {
    overflow: hidden;
}

.iq-card .block-images .img-box img,
.iq-card .block-images .img-box .kino-poster-fallback {
    mix-blend-mode: normal;
    opacity: 0.82;
    -webkit-transition: opacity 400ms ease, -webkit-transform 600ms ease;
    -o-transition: opacity 400ms ease, transform 600ms ease;
    transition: opacity 400ms ease, transform 600ms ease;
}

.iq-card:hover .block-images .img-box img,
.iq-card:hover .block-images .img-box .kino-poster-fallback {
    opacity: 1;
    -webkit-transform: scale(1.08);
    -ms-transform: scale(1.08);
    transform: scale(1.08);
}

/* Info panel fades in over the bottom of the artwork rather than hanging below
   it — the template parks it at bottom:-3.75em, outside the frame, which only
   worked because the card grew. */
.iq-card .block-images .card-description.with-transition,
.iq-card:hover .block-images .card-description.with-transition {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.5em 1em 1em;
    background: -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.92) 0%, rgba(var(--bs-black-rgb), 0.55) 55%, rgba(var(--bs-black-rgb), 0) 100%);
    background: linear-gradient(to top, rgba(var(--bs-black-rgb), 0.92) 0%, rgba(var(--bs-black-rgb), 0.55) 55%, rgba(var(--bs-black-rgb), 0) 100%);
    -webkit-transition: opacity 350ms ease, -webkit-transform 350ms ease, visibility 350ms ease;
    -o-transition: opacity 350ms ease, transform 350ms ease, visibility 350ms ease;
    transition: opacity 350ms ease, transform 350ms ease, visibility 350ms ease;
}

.iq-card .block-images .card-description.with-transition {
    opacity: 0;
    visibility: hidden;
    -webkit-transform: translateY(0.5em);
    -ms-transform: translateY(0.5em);
    transform: translateY(0.5em);
}

.iq-card:hover .block-images .card-description.with-transition {
    opacity: 1;
    visibility: visible;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .iq-card:hover .block-images .img-box img,
    .iq-card:hover .block-images .img-box .kino-poster-fallback {
        -webkit-transform: none;
        -ms-transform: none;
        transform: none;
    }
}

/* Fade-to-black on the hovered card.
 *
 * The template's own scrim is .img-box::before, but .img-box a carries
 * z-index:1, so the artwork paints over it and it never shows (it only
 * appeared in the demo because the image was blend-mode'd). This overlay sits
 * above the image (z-index 2) and below .card-description (z-index 9), so the
 * card darkens on hover and the title/Play Now stay legible on top.
 */
.iq-card .block-images .img-box::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    pointer-events: none;
    background: -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.6) 45%, rgba(var(--bs-black-rgb), 0.2) 100%);
    background: linear-gradient(to top, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.6) 45%, rgba(var(--bs-black-rgb), 0.2) 100%);
    opacity: 0;
    -webkit-transition: opacity 400ms ease;
    -o-transition: opacity 400ms ease;
    transition: opacity 400ms ease;
}

.iq-card:hover .block-images .img-box::after {
    opacity: 1;
}

/* The overlay above now does the darkening, so the info panel doesn't need its
   own gradient stacked on top of it. */
.iq-card .block-images .card-description.with-transition,
.iq-card:hover .block-images .card-description.with-transition {
    background: transparent;
}

/* Logged-in identifier shown in full, as a pill rather than a round avatar
   (a phone number or email doesn't fit in a circle). */
.kino-user-chip {
    display: inline-flex;
    align-items: center;
    max-width: 14em;
    padding: 0.45em 0.9em;
    border-radius: 999px;
    background: var(--bs-primary);
    color: #fff;
    font-weight: 600;
    font-size: 0.875em;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ------------------------------------------------------------------------
 * Content detail page.
 *
 * .iq-main-slider.site-video is an aspect-ratio box (height:0 + padding) and
 * .movie-detail-part is absolutely positioned by the template, so the details
 * overlay the background media rather than sitting under it.
 * ------------------------------------------------------------------------ */

/* The template wraps this section in .poition-relative — a typo that matches
   no rule, so nothing established a positioning context and the absolutely
   positioned .movie-detail-part escaped to the page bottom (footer above it).
   Anchor it here instead. */
.kino-detail {
    position: relative;
}

.kino-detail .iq-main-slider.site-video {
    position: relative;
    overflow: hidden;
}

/* Trailer and still both fill the box and crop rather than letterbox. */
.kino-detail .video-js,
.kino-detail .kino-detail__still {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: transparent;
}

.kino-detail .video-js video,
.kino-detail .kino-detail__still {
    -o-object-fit: cover;
       object-fit: cover;
    width: 100%;
    height: 100%;
}

.kino-detail .kino-detail__still--empty {
    display: block;
    background-image: var(--kino-gradient);
}

/* Keeps the overlaid copy readable over bright artwork or motion. */
.kino-detail .kino-detail__scrim {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    background:
        -webkit-linear-gradient(left, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.6) 40%, rgba(var(--bs-black-rgb), 0.15) 75%),
        -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.35) 45%, rgba(var(--bs-black-rgb), 0) 75%);
    background:
        linear-gradient(to right, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.6) 40%, rgba(var(--bs-black-rgb), 0.15) 75%),
        linear-gradient(to top, rgba(var(--bs-black-rgb), 0.95) 0%, rgba(var(--bs-black-rgb), 0.35) 45%, rgba(var(--bs-black-rgb), 0) 75%);
}

/* Description clamp; the toggle swaps this class off to reveal the rest. */
.kino-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.kino-readmore {
    color: var(--bs-primary);
    font-size: 0.875em;
    font-weight: 600;
    text-decoration: none;
}

/*
 * Detail overlay positioning — stated explicitly rather than inherited.
 *
 * The template positions BOTH .movie-detail-part (absolute, bottom:0) and
 * .details-parts (absolute, bottom:6em, width:50%) — the latter inside a
 * zero-height parent. Its own breakpoints then flip the parent to
 * `top:12%/32px; bottom:unset`, so between 768 and 1200px the copy was
 * anchored upward from the top of the media box and vanished off-screen.
 */
.kino-detail .movie-detail-part {
    position: absolute;
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2;
}

/* Back into normal flow, so the block sizes to its content. */
.kino-detail .movie-detail-part .trending-info .details-parts {
    position: relative;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    width: auto;
    max-width: 46em;
    padding: 0 4vw 3em;
}

@media (max-width: 991.98px) {
    /* 42–46% of a narrow viewport is only ~250–400px tall — not enough to hold
       the copy — so stop overlaying and stack it under the media instead. */
    .kino-detail .movie-detail-part {
        position: static;
    }

    /* Plain 16:9 once it is no longer a backdrop for text. */
    .kino-detail .iq-main-slider.site-video {
        padding-bottom: 56.25%;
    }

    .kino-detail .movie-detail-part .trending-info .details-parts {
        max-width: none;
        padding: 1.5em 1.25em 2.5em;
    }

    /* Nothing sits on the scrim any more, so lighten it. */
    .kino-detail .kino-detail__scrim {
        background: -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.5) 0%, rgba(var(--bs-black-rgb), 0) 60%);
        background: linear-gradient(to top, rgba(var(--bs-black-rgb), 0.5) 0%, rgba(var(--bs-black-rgb), 0) 60%);
    }
}

/* ------------------------------------------------------------------------
 * Sticky footer: on short pages (a sparse category, a coming-soon title) the
 * footer used to float mid-screen with dead space beneath it. Making the body
 * a column flexbox and letting <main> absorb the slack pins it to the bottom
 * without pushing it off-screen on tall pages.
 *
 * Scoped to .kino-app so the auth layout, which has no <main>/<footer>, is
 * unaffected.
 * ------------------------------------------------------------------------ */
.kino-app {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column;
    min-height: 100vh;
    /* Accounts for mobile browser chrome where supported. */
    min-height: 100dvh;
}

.kino-app > .main-content {
    -webkit-box-flex: 1;
    -ms-flex: 1 0 auto;
    flex: 1 0 auto;
}

.kino-app > .footer {
    -ms-flex-negative: 0;
    flex-shrink: 0;
}

/* ------------------------------------------------------------------------
 * Watch page: header, player, footer.
 * ------------------------------------------------------------------------ */

/*
 * streamit.js measures the header and sets --header-height at runtime, but it
 * loads deferred — until then `padding-top: var(--header-height)` is invalid
 * and content slides under the absolutely positioned header. A fallback keeps
 * the first paint correct on every non-hero page.
 */
.custom-header-relative:not(.kino-hero-home) .main-content {
    padding-top: var(--header-height, 5em);
}

.kino-watch {
    padding: 2em 0 3.5em;
}

.kino-watch__stage {
    position: relative;
    width: 100%;
    max-width: 100em;
    margin: 0 auto;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: 0.5em;
    overflow: hidden;
}

/* Video.js copies the element's classes onto a generated wrapper div, so both
   the wrapper and the inner <video> need to fill the stage. */
.kino-watch__stage .video-js {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/* contain, not cover: never crop a feature the viewer chose to watch. */
.kino-watch__stage .video-js video {
    width: 100%;
    height: 100%;
    -o-object-fit: contain;
       object-fit: contain;
}

/* Title left, sound toggle right, on one line above the player. */
.kino-watch__head {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between;
    gap: 1em;
    max-width: 100em;
    margin: 0 auto 0.75em;
}

.kino-watch__title {
    margin: 0;
    font-size: clamp(1.35rem, 2.6vw, 2rem);
    font-weight: 800;
    color: #fff;
}

.kino-sound {
    -ms-flex-negative: 0;
    flex-shrink: 0;
    white-space: nowrap;
}

/* ---------- Subscription / payment screens ---------- */

.kino-subscribe {
    padding: 2.5em 0 4em;
}

.kino-subscribe__title {
    font-size: clamp(1.5rem, 3vw, 2.25rem);
    font-weight: 800;
    color: #fff;
    margin-bottom: 1.25em;
}

.kino-plan {
    background: var(--bs-gray-900);
    border: 1px solid rgba(var(--bs-white-rgb, 255, 255, 255), 0.08);
    border-radius: 0.75em;
    padding: 1.5em;
}

.kino-plan__name {
    font-size: 1.15rem;
    font-weight: 700;
    color: #fff;
    margin: 0;
}

.kino-plan__price {
    font-size: 2rem;
    font-weight: 800;
    color: var(--bs-primary);
    margin: 0.35em 0 0.15em;
}

.kino-plan__note {
    font-size: 0.875rem;
    margin-bottom: 1.25em;
}

.kino-qr {
    width: 100%;
    max-width: 17em;
    height: auto;
    background: #fff;
    border-radius: 0.5em;
    padding: 0.5em;
}

/* Bank deeplinks: a wrapping grid so 20+ options stay scannable. */
.kino-banks {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5em, 1fr));
    gap: 0.75em;
}

.kino-bank {
    display: flex;
    align-items: center;
    gap: 0.6em;
    padding: 0.6em 0.75em;
    border-radius: 0.5em;
    background: rgba(var(--bs-black-rgb), 0.35);
    border: 1px solid rgba(var(--bs-white-rgb, 255, 255, 255), 0.08);
    color: #fff;
    text-decoration: none;
    transition: background 200ms ease, border-color 200ms ease;
}

.kino-bank:hover {
    background: rgba(var(--bs-black-rgb), 0.6);
    border-color: var(--bs-primary);
    color: #fff;
}

.kino-bank__logo {
    width: 1.75em;
    height: 1.75em;
    border-radius: 0.25em;
    flex-shrink: 0;
    object-fit: contain;
    background: #fff;
}

.kino-bank__name {
    font-size: 0.8rem;
    line-height: 1.2;
}

/* Playback blocked overlay (session replaced / subscription lapsed). */
.kino-watch__blocked {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 1.5em;
    background: rgba(var(--bs-black-rgb), 0.88);
}

.kino-watch__blocked-inner i {
    font-size: 2.5rem;
    color: var(--bs-primary);
    display: block;
    margin-bottom: 0.5em;
}

/*
 * Hero copy on tablets/phones (< 992px), where the template hides the thumb
 * strip.
 *
 * The template swaps the hero's `min-height: 92vh` for `min-height: inherit`
 * here, collapsing the slide so `align-items-end` had no slack to work with and
 * the copy drifted up the artwork. Rather than fight that cascade through the
 * Bootstrap row, the background box itself becomes a flex column and pushes its
 * content block to the bottom — one rule, no reliance on row alignment.
 */
@media (max-width: 991.98px) {
    .iq-banner-thumb-slider .slider .slider-bg .slider-images .slider--image {
        /* Shorter than desktop's 92vh: a full-height hero on a phone hides the
           rows below it entirely. */
        min-height: 62vh;
        height: auto;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -ms-flex-direction: column;
        flex-direction: column;
        -webkit-box-pack: end;
        -ms-flex-pack: end;
        justify-content: flex-end;
    }

    .iq-banner-thumb-slider .slider .slider-bg .slider-images .slider--image > .container-fluid {
        width: 100%;
    }

    /* Sizes to its content now that the parent handles placement. The header
       overlays the top of the artwork, which the copy no longer reaches. */
    .iq-banner-thumb-slider .slider .slider-bg .slider-images .swiper-wrapper .banner-bg .slider-content-full-height {
        min-height: 0;
        padding: 0 0 2em;
    }

    /* Thumb strip is hidden here, so the copy can use the full width. */
    .iq-banner-thumb-slider .slider .slider-bg .slider-images .slider-content {
        max-width: none;
    }
}

/*
 * Small-screen gutter.
 *
 * The template steps .container-fluid down 3.75em -> 2em -> 1em, and that final
 * 1em (16px) below 768px left the logo and the login button looking flush to the
 * screen edges. Match the 2em (32px) used in the band just above instead, so the
 * header margin looks the same either side of the breakpoint.
 */
@media (max-width: 767.98px) {
    /*
     * Header only. Applying this to every .container-fluid also widened the
     * content rows, which left too much dead space either side of the cards on
     * a phone — those keep the template's 1em.
     */
    header .navbar > .container-fluid {
        padding-left: 1.5em;
        padding-right: 1.5em;
        /*
         * Vertical breathing room. The template gives the logo
         * `padding: 1.5em 0` at every other width, but zeroes it here
         * (.navbar-brand img.logo { padding: 0 }) — and because the header is
         * absolutely positioned over the hero, the logo and the login button
         * ended up flush against the top of the screen. Padding the container
         * lifts both, not just the logo.
         */
        padding-top: 1rem;
        padding-bottom: 1rem;
    }
}

/* ------------------------------------------------------------------------
 * Notices.
 *
 * Bootstrap's stock alerts are pale, high-radius blocks that fight a dark
 * cinema UI — the yellow warning in particular. Restyled as a quiet dark panel
 * with a thin coloured edge, so the meaning still reads without shouting.
 * ------------------------------------------------------------------------ */
.alert {
    border: 0;
    border-left: 3px solid var(--bs-primary);
    border-radius: 0.25rem;
    background: rgba(var(--bs-black-rgb), 0.5);
    color: #fff;
    font-size: 0.9rem;
    padding: 0.85em 1.1em;
    -webkit-box-shadow: none;
    box-shadow: none;
}

.alert-success {
    border-left-color: #2ecc71;
}

.alert-warning {
    border-left-color: #f5c518;
}

.alert-danger {
    border-left-color: var(--bs-primary);
}

.alert-info {
    border-left-color: #4aa3df;
}

/* ---------- All-categories modal ---------- */

.kino-category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11em, 1fr));
    gap: 0.6em;
}

.kino-category-link {
    display: block;
    padding: 0.7em 0.9em;
    border-radius: 0.375rem;
    border: 1px solid rgba(var(--bs-black-rgb), 0.6);
    background: rgba(var(--bs-black-rgb), 0.4);
    color: #fff;
    font-size: 0.875rem;
    line-height: 1.25;
    text-decoration: none;
    -webkit-transition: background 200ms ease, border-color 200ms ease;
    -o-transition: background 200ms ease, border-color 200ms ease;
    transition: background 200ms ease, border-color 200ms ease;
}

.kino-category-link:hover,
.kino-category-link:focus-visible {
    background: rgba(var(--bs-black-rgb), 0.75);
    border-color: var(--bs-primary);
    color: #fff;
}

.kino-category-link.is-active {
    border-color: var(--bs-primary);
    color: var(--bs-primary);
}

/*
 * Category names as stored.
 *
 * The template applies `text-transform: capitalize` to nav links, which
 * upper-cases every word — "Монгол порно од" rendered as "Монгол Порно Од".
 * Render the stored value instead, so sentence case survives (and a genuine
 * proper noun mid-name, e.g. "Төгс Орос хүүхэн", keeps its capital).
 */
.iq-nav-menu > li > a,
.iq-nav-menu > li > a .item-name,
.kino-category-link {
    text-transform: none;
}

/*
 * "Бусад категориуд" trigger.
 *
 * Sat among the category links looking identical to them, so it didn't read as
 * a control. Styled as an outlined pill with a grid icon and a count, and given
 * higher specificity than .iq-nav-menu > li > a so the template's own link
 * padding doesn't fight it.
 */
.iq-nav-menu > li > a.kino-more-cats {
    /* Template nav links are 1rem; this sits 2px smaller so the pill reads as a
       control rather than competing with the category links. The icon is 1.05em,
       so it scales down with it. */
    font-size: 0.875rem;
    display: -webkit-inline-box;
    display: -ms-inline-flexbox;
    display: inline-flex;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    gap: 0.45em;
    padding: 0.4em 0.9em;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 999px;
    color: #fff;
    -webkit-transition: border-color 200ms ease, background 200ms ease, color 200ms ease;
    -o-transition: border-color 200ms ease, background 200ms ease, color 200ms ease;
    transition: border-color 200ms ease, background 200ms ease, color 200ms ease;
}

.iq-nav-menu > li > a.kino-more-cats:hover,
.iq-nav-menu > li > a.kino-more-cats:focus-visible {
    border-color: var(--bs-primary);
    background: rgba(var(--bs-black-rgb), 0.55);
    color: var(--bs-primary);
}

.iq-nav-menu > li > a.kino-more-cats i {
    font-size: 1.05em;
    line-height: 1;
}

/* Count badge, so it's obvious how much more is behind the click. */
.kino-more-cats__count {
    display: inline-block;
    min-width: 1.5em;
    padding: 0.1em 0.35em;
    border-radius: 999px;
    background: var(--bs-primary);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.4;
    text-align: center;
}

.iq-nav-menu > li > a.kino-more-cats:hover .kino-more-cats__count {
    background: #fff;
    color: var(--bs-primary);
}

/* ---------- Profile page ---------- */

/* Definition list rendered as label/value rows. */
.kino-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.4em 1em;
    margin: 0;
}

.kino-facts dt {
    font-weight: 400;
    font-size: 0.875rem;
    color: var(--bs-body-color);
}

.kino-facts dd {
    margin: 0;
    font-weight: 600;
    color: #fff;
    text-align: right;
}

.kino-table {
    color: #fff;
    font-size: 0.85rem;
}

.kino-table thead th {
    font-weight: 600;
    color: var(--bs-body-color);
    border-bottom-color: rgba(255, 255, 255, 0.12);
    text-transform: none;
}

.kino-table td {
    border-bottom-color: rgba(255, 255, 255, 0.07);
}

/*
 * Logo sizing.
 *
 * Two problems with the template's rule (`width: 9.375em` + `max-height:
 * 5.375em`): it pins both axes, so a 4:3 mark got squashed by the cap; and em
 * here resolves against .navbar-brand, whose font-size comes from a Bootstrap
 * variable and is `unset` elsewhere — it measured ~12.4px on desktop and
 * ~8.7px at 768px, so em-based sizing was unpredictable.
 *
 * Driven by width in px (deterministic) with `height: auto`, so the source
 * aspect ratio is always preserved.
 */
.navbar-brand img.logo {
    width: 85px;
    height: auto;
    max-height: none;
    padding: 0;
    -o-object-fit: contain;
       object-fit: contain;
}

@media (min-width: 768px) {
    .navbar-brand img.logo {
        width: 100px;
        padding: 14px 0;
    }
}

/*
 * Auth pages (login / register) logo.
 *
 * This one sits outside .navbar-brand, so the header rule above doesn't reach
 * it. The template sizes it with `width: 11.25em`, which is em-based and
 * therefore unpredictable here; pin it in px and let the height follow.
 */
.sign-in-page img.logo {
    width: 120px;
    height: auto;
    max-height: none;
}

/*
 * Soften the template's own hero scrim.
 *
 * Its ::before starts at fully opaque `var(--bs-black)` for the first ~10% and
 * fades out, which reads as a hard black band down the left edge. It's hidden
 * behind a playing trailer, but stacks under our ::after on titles that only
 * have a static landscape — so those looked markedly darker than the rest.
 */
.iq-banner-thumb-slider .slider .slider-bg .slider-images .slider--image::before {
    background:
        -webkit-linear-gradient(left, rgba(var(--bs-black-rgb), 0.46) 0%, rgba(var(--bs-black-rgb), 0) 34%),
        -webkit-linear-gradient(bottom, rgba(var(--bs-black-rgb), 0.36) 0%, rgba(var(--bs-black-rgb), 0) 60%);
    background:
        linear-gradient(to right, rgba(var(--bs-black-rgb), 0.46) 0%, rgba(var(--bs-black-rgb), 0) 34%),
        linear-gradient(to top, rgba(var(--bs-black-rgb), 0.36) 0%, rgba(var(--bs-black-rgb), 0) 60%);
}
