/* q4u-slider: custom styles */

/* ─── Base ────────────────────────────────────────────── */

.q4u-slider {
    width: 100%;
    min-width: 0;
    position: relative;
}

/* Override Swiper CSS variables set by q4u_base _carousel.scss.
   Specificity 0-2-0 (.q4u-slider.swiper) beats both .q4u-slider and .swiper (0-1-0),
   so these values survive regardless of CSS load order — including the dynamic
   theme-CSS injection that happens on theme switch (non-default themes). */
.q4u-slider.swiper {
    --swiper-pagination-bottom: 16px;
    --swiper-pagination-top: auto;
    --swiper-navigation-top-offset: 50%;
}

/* Navigation arrows — Tactile Depth */
.q4u-slider .swiper-button-prev,
.q4u-slider .swiper-button-next {
    color: var(--bs-primary, #0d6efd);
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.4));
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                filter 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.q4u-slider .swiper-button-prev:hover,
.q4u-slider .swiper-button-next:hover {
    transform: translateY(-2px);
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.35));
}

.q4u-slider .swiper-button-prev:active,
.q4u-slider .swiper-button-next:active {
    transform: translateY(0) scale(0.92);
    transition-duration: 0.1s;
}

/* Focus: glow ring (WCAG 2.4.7) */
.q4u-slider .swiper-button-prev:focus-visible,
.q4u-slider .swiper-button-next:focus-visible {
    outline: none;
    filter: drop-shadow(0 0 8px rgba(var(--bs-primary-rgb, 13, 110, 253), 0.5))
            drop-shadow(0 0 16px rgba(var(--bs-primary-rgb, 13, 110, 253), 0.3));
}

.q4u-slider .swiper-pagination-bullet:focus-visible {
    outline: 3px solid var(--bs-primary, #0d6efd);
    outline-offset: 2px;
}

/* ─── Card layout ──────────────────────────────────────── */

/* Equal-height slides: force all slides to wrapper height.
   Needed because coverflow 3D transforms can break flex stretch. */
.q4u-slider--card .swiper-wrapper {
    align-items: stretch;
}

.q4u-slider--card .swiper-slide {
    height: auto;
}

/* Equal-height cards: fill the slide */
.q4u-slider .swiper-slide > .card {
    height: 100%;
}

/* Consistent image height: 3:2 aspect ratio like q4u_cards.
   Higher specificity needed to override q4u_base's .swiper .swiper-slide img (0-2-1).
   <picture> wrapper must also be constrained so it doesn't expand to natural ratio. */
.q4u-slider--card .swiper-slide .card-img-top {
    aspect-ratio: 3 / 2;
    object-fit: cover;
}

.q4u-slider--card .swiper-slide picture {
    display: contents;
}

/* Card-body: grow to fill remaining space so all cards match the tallest slide's height.
   Swiper's flex layout equalizes slide heights; card-body absorbs the text height difference. */
.q4u-slider--card .card-body {
    flex: 1 1 auto;
}

/* Card layout: override image-bottom variable for 3:2 aspect ratio.
   _carousel.scss positions all controls (pagination, timer, info) via
   --swiper-image-bottom, so setting this once aligns everything. */
.q4u-slider--card.swiper {
    --swiper-image-bottom: calc(100cqi * 2 / 3);
    --swiper-navigation-top-offset: calc(100cqi / 3);
    /* Restore top-based pagination from _carousel.scss — the base rule
       (.q4u-slider.swiper) sets bottom:16px which misses the image edge
       on Card slides because the text area sits below the image. */
    --swiper-pagination-bottom: auto;
    --swiper-pagination-top: var(--swiper-image-bottom);
}

/* Card overlay controls: use the shared image-bottom variable */
.q4u-slider--card .q4u-slider-controls {
    bottom: auto;
    top: var(--swiper-image-bottom);
    transform: translateY(calc(-100% - 16px));
}

.q4u-slider--card .q4u-slider-info {
    bottom: auto;
    top: var(--swiper-image-bottom);
    transform: translateY(calc(-100% - 16px));
}

/* ─── Glassmorphism shared ────────────────────────────── */

/* Glassmorphism shared — all slider controls including info pill */
.q4u-slider-controls,
.q4u-slider-timer,
.q4u-slider-pause,
.q4u-slider-info {
    background: rgba(0, 0, 0, 0.35);
    -webkit-backdrop-filter: blur(8px) saturate(180%);
    backdrop-filter: blur(8px) saturate(180%);
    color: #fff;
    transition: background-color 0.2s ease,
                transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.q4u-slider-timer:hover,
.q4u-slider-pause:hover,
.q4u-slider-info:hover {
    background: rgba(0, 0, 0, 0.5);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.q4u-slider-timer:active,
.q4u-slider-pause:active,
.q4u-slider-info:active {
    transform: translateY(0) scale(0.965);
    transition-duration: 0.1s;
}

/* ─── Autoplay controls (bottom-left) ─────────────────── */

.q4u-slider-controls {
    position: absolute;
    z-index: 10;
    bottom: 16px;
    left: 16px;
    display: none; /* shown by JS when autoplay is active */
    align-items: center;
    gap: 8px;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* Show controls when autoplay is enabled (JS adds class) */
.q4u-slider--has-autoplay .q4u-slider-controls {
    display: flex;
}

/* Timer circle */
.q4u-slider-timer {
    position: relative;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.q4u-slider-timer svg {
    --progress: 0;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 10;
    width: 100%;
    height: 100%;
    stroke-width: 4px;
    stroke: #fff;
    fill: none;
    stroke-dashoffset: calc(125.6px * (1 - var(--progress)));
    stroke-dasharray: 125.6;
    transform: rotate(-90deg);
}

.q4u-slider-timer span {
    position: relative;
    z-index: 11;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
}

/* Pause/Play button */
.q4u-slider-pause {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    appearance: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.q4u-slider-pause:focus-visible {
    outline: none;
    box-shadow:
        0 0 0 3px rgba(255, 255, 255, 0.9),
        0 0 0 5px var(--bs-primary, #0d6efd),
        0 0 12px rgba(var(--bs-primary-rgb, 13, 110, 253), 0.4);
}

.q4u-slider-pause__play {
    display: none;
}

.q4u-slider-pause.is-paused .q4u-slider-pause__pause {
    display: none;
}

.q4u-slider-pause.is-paused .q4u-slider-pause__play {
    display: block;
}

/* ─── Copyright / AI info pill (bottom-right) ─────────── */

.q4u-slider-info {
    position: absolute;
    z-index: 10;
    bottom: 16px;
    right: 16px;
    height: 48px;
    display: none; /* shown by JS when slide has copyright/AI data */
    align-items: center;
    gap: 2px;
    padding: 0 12px;
    border-radius: 24px;
    cursor: pointer;
}

.q4u-slider-info[data-visible="true"] {
    display: flex;
}

.q4u-slider-info__icon {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* CSS-only tooltip (same pattern as picture-info in _tooltip-images.scss) */
.q4u-slider-info::after {
    content: attr(data-picture-info-label);
    position: absolute;
    right: calc(100% + .5rem);
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, .85);
    color: #fff;
    font-size: .8125rem;
    line-height: 1.4;
    padding: .375rem .75rem;
    border-radius: .25rem;
    white-space: nowrap;
    pointer-events: auto;
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s ease-in-out, visibility .15s ease-in-out;
    z-index: 1080;
}

.q4u-slider-info:hover::after,
.q4u-slider-info:focus::after {
    opacity: 1;
    visibility: visible;
}

.q4u-slider-info[data-tooltip-dismissed]::after {
    opacity: 0;
    visibility: hidden;
}

/* WCAG 2.4.7: keyboard focus indicator */
.q4u-slider-info:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .q4u-slider-info::after {
        transition: none;
    }
}

/* ─── Image + Hero shared ─────────────────────────────── */

.q4u-slider--image .swiper-slide,
.q4u-slider--hero .swiper-slide {
    position: relative;
    overflow: hidden;
}

.q4u-slider--image .swiper-slide img,
.q4u-slider--hero .swiper-slide img {
    display: block;
    width: 100%;
    height: auto;
}

/* Image + Hero arrows: color and shadow now inherited from base rule */

/* Pagination pill: constrain width and center for ALL layouts.
   _carousel.scss handles glassmorphism but not width — Swiper default is 100%.
   Specificity 0-4-0 beats _carousel.scss (0-3-0) regardless of load order. */
.q4u-slider.swiper .swiper-pagination.swiper-pagination-bullets {
    width: auto !important;
    left: 50% !important;
    display: inline-flex;
    align-items: center;
    translate: -50% 0;
}

/* Card pagination: shift pill above image bottom edge.
   Base rule centers with translate:-50% 0, Card adds Y shift for top-based positioning.
   Specificity must match base (0-4-0): .q4u-slider--card.swiper + descendant. */
.q4u-slider--card.swiper .swiper-pagination.swiper-pagination-bullets {
    translate: -50% calc(-100% - 16px);
}

/* ─── Hero layout ─────────────────────────────────────── */

/* Hero frame reset: no header, no padding, no background, full width */
.frame-type-q4u_slider:has(.q4u-slider--hero) {
    padding: 0 !important;
    margin: 0 !important;
    width: 100%;
    background: transparent !important;
}

/* Hero max-width: applied on the slider element where the CSS variable lives */
.q4u-slider--hero {
    max-width: var(--q4u-slider-max-width, 1440px);
    margin: 0 auto;
}

.frame-type-q4u_slider:has(.q4u-slider--hero) > .container {
    max-width: none;
    padding: 0;
}

.frame-type-q4u_slider:has(.q4u-slider--hero) .ce-header {
    display: none;
}

/* Hero in colPos 5: pull behind sticky navbar, strip wrapper chrome */
.hero:has(.q4u-slider--hero) {
    /* The pull must equal the space the header occupies in flow. q4u_base's
       header-offset.js measures that and publishes --q4u-header-offset; no CSS
       can read a rendered height.

       The fallback is the OLD formula on purpose, so an install without the
       q4u_base change keeps today's behaviour instead of breaking. That old
       formula is wrong at every breakpoint: --header-height is declared 3rem
       (48px) in t3bootstrap's main.css and the generated theme CSS, while the
       header renders 122px on desktop and 70px on a phone, and the `+ 6rem` is
       a fudge that lands near the right DESKTOP number (144px vs a true 154px)
       while overshooting a phone by 74px — enough that most of a short mobile
       hero ended up above the document top or behind the navbar. */
    margin-top: calc(var(--q4u-header-offset, calc(var(--header-height, 3rem) + 6rem)) * -1);
    padding: 0 !important;
    background: transparent !important;
}

.hero:has(.q4u-slider--hero) .hero-content {
    max-width: none;
    padding: 0;
}

/* Background image: cover the slide */
.q4u-slider-hero__image {
    display: block;
    width: 100%;
    height: auto;
}

/* Text overlay: covers the full slide area */
.q4u-slider-hero__overlay {
    position: absolute;
    inset: 0;
    display: flex;
    padding: 48px 64px;
    /* Default gradient: dark at bottom for readability */
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.7) 0%,
        rgba(0, 0, 0, 0.3) 40%,
        rgba(0, 0, 0, 0.05) 70%,
        transparent 100%
    );
}

/* Vertical alignment variants */
.q4u-slider-hero__overlay--bottom {
    align-items: flex-end;
}

.q4u-slider-hero__overlay--center {
    align-items: center;
    background: linear-gradient(
        to right,
        rgba(0, 0, 0, 0.6) 0%,
        rgba(0, 0, 0, 0.3) 50%,
        transparent 100%
    );
}

.q4u-slider-hero__overlay--top {
    align-items: flex-start;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.7) 0%,
        rgba(0, 0, 0, 0.3) 40%,
        rgba(0, 0, 0, 0.05) 70%,
        transparent 100%
    );
}

/* Content container */
.q4u-slider-hero__content {
    max-width: 600px;
    color: #fff;
}

.q4u-slider-hero__title {
    font-size: clamp(1.5rem, 4vw, 3rem);
    font-weight: 700;
    line-height: 1.15;
    margin-bottom: 16px;
    color: inherit;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.q4u-slider-hero__text {
    font-size: clamp(1rem, 1.5vw, 1.25rem);
    line-height: 1.5;
    margin-bottom: 24px;
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.q4u-slider-hero__text p:last-child {
    margin-bottom: 0;
}

/* ─── Reduced Motion: disable Tactile Depth ──────────── */
@media (prefers-reduced-motion: reduce) {
    .q4u-slider .swiper-button-prev,
    .q4u-slider .swiper-button-next,
    .q4u-slider-timer,
    .q4u-slider-pause,
    .q4u-slider-info {
        transition: background-color 0.15s ease;
    }

    .q4u-slider .swiper-button-prev:hover,
    .q4u-slider .swiper-button-next:hover,
    .q4u-slider-timer:hover,
    .q4u-slider-pause:hover,
    .q4u-slider-info:hover {
        transform: none;
    }

    .q4u-slider .swiper-button-prev:active,
    .q4u-slider .swiper-button-next:active,
    .q4u-slider-timer:active,
    .q4u-slider-pause:active,
    .q4u-slider-info:active {
        transform: none;
    }
}

/* Mobile: reduce padding */
@media (max-width: 575.98px) {
    .q4u-slider-hero__overlay {
        padding: 24px;
    }

    .q4u-slider-hero__content {
        max-width: 100%;
    }
}

/* ─── Keep top/centre text clear of the sticky header ─────── */

/* A hero in colPos 5 sits UNDER the sticky header by design, so top- and
   centre-aligned overlay text renders behind the navbar.

   Only these two variants are guarded, because padding-top can only help these
   two. The overlay is `position: absolute; inset: 0` inside a box of fixed
   height, so unlike q4u_heroimage's grid-stacked overlay it cannot make the hero
   taller to absorb the padding — it can only shrink its own content box.

   For `--top` and `--center` that is exactly what is wanted: the content is
   laid out from the top / centred, so shrinking the box from above moves the
   text down, out from under the navbar. Measured at 375px against a 70px
   header: top +24px clearance, centre +7px.

   `--bottom` cannot be fixed this way. `align-items: flex-end` anchors the
   content to the bottom, so padding-top does not move it; content taller than
   the content box simply overflows upward, past the padding, and reaches the
   header anyway. Measured on the same hero, bottom-aligned text still sits 10px
   under the header with or without padding — adding it would buy nothing and
   only bring the clipping threshold closer. That case needs the box to GROW,
   which is the grid restructure q4u_heroimage received; doing it here means
   restructuring a video / carousel component and is left as a follow-up. */
.hero .q4u-slider-hero__overlay--top,
.hero .q4u-slider-hero__overlay--center {
    padding-top: calc(var(--q4u-header-offset, 0px) + 24px);
}
