/* ============================================
   DOOR PIVOT PHOTO CAROUSEL MODULE (Swiper-based)
   Single display mode: creative (slides
   positioned via free 3D transforms driven by
   the fixed door-pivot effect config). Runtime
   values come from CSS custom properties
   (--pc-radius, --pc-aspect-ratio,
   --pc-main-height) set inline by the renderer.
   The carousel mechanics are driven by the
   Swiper library's creative effect; this
   stylesheet only styles the module shell,
   slides, captions, and controls.
   ============================================ */

.door-pivot-photo-carousel-viewport {
    /* Clip wrapper. The Swiper root inside is overflow:visible so the
       transforming slides read in full while they move; this outer viewport
       clips any spill exactly at the module boundary so the carousel never reads
       wider than its module-wrapper (matching every other module).
       box-sizing:border-box keeps the padding inside the 100% width. This
       wrapper is also the containing block for the nav arrows and pagination
       dots, which are rendered as SIBLINGS of the Swiper root (not inside it).
       position:relative makes the absolute arrows anchor to the module box; the
       --swiper-navigation-* tokens live here so Swiper's own
       .swiper-button-prev/next rules size and place the arrows against this
       wrapper. */
    box-sizing: border-box;
    position: relative;
    width: 100%;
    overflow: hidden;
    --swiper-navigation-size: 44px;
    --swiper-navigation-sides-offset: 8px;
    /* The arrows anchor against this viewport (their containing block). Swiper
       applies `top: var(--swiper-navigation-top-offset, 50%)` to its prev/next
       buttons (with a negative margin-top to vertically center the button on
       that top), so this token IS the button's absolute top — it must keep its
       50% base. The viewport height = padding-top + slide height + padding-bottom
       (the bottom padding reserves the dots band). A plain 50% centers against
       the whole box and drifts down as the bottom padding grows, so half the
       (top − bottom) padding difference is subtracted from 50% to land the
       arrows on the SLIDE's vertical center instead. The padding values are
       dynamic (sized from the slide's perspective-overshoot via
       --pc-viewport-pad-*), so the correction reads the SAME custom properties
       to stay on the slide center at every padding size. The extra -4px nudges
       the arrows slightly above the geometric center (the aesthetic buffer). */
    --swiper-navigation-top-offset: calc(50% + (var(--pc-viewport-pad-top, 16px) - var(--pc-viewport-pad-bottom, 48px)) / 2 - 4px);
    --swiper-navigation-color: var(--text-ink);
    /* Top/bottom padding so the transforming slide has breathing room above and
       the dots band sits clear below the slide. The values are sized from the
       slide's perspective-overshoot by the data prep
       (doorPivotViewportPaddingFor) and ride in as --pc-viewport-pad-* on this
       element. The defaults (16px / 48px) match the no-overshoot case and only
       apply if the renderer never set the custom property. */
    padding: var(--pc-viewport-pad-top, 16px) 0 var(--pc-viewport-pad-bottom, 48px);
}

.door-pivot-photo-carousel {
    --pc-radius: 18px;
    /* Fixed-height slide. The height is set by --pc-main-height and the width is
       derived from the admin aspect_ratio via the CSS `aspect-ratio` property.
       object-fit:cover crops each image to fill the box, so every slide reads as
       one uniform tile regardless of the source aspect ratio. Default is
       landscape (16 / 9) for photo content; the renderer overrides it from the
       setting. */
    --pc-main-height: 360px;
    /* The renderer overrides --pc-main-height from the admin main_height setting
       (inline on the root). This declaration remains the fallback for any
       carousel rendered without that token. */
    --pc-aspect-ratio: 16 / 9;
    /* Slide elevation. Tinted toward Ink (green-grey) per the design system's
       shadow vocabulary rather than pure black. A distinct dark-mode value is
       layered under the dark-theme block below so the shadow stays visible
       against the charcoal-teal canvas instead of dissolving into it. */
    --pc-shadow: 0 8px 20px rgba(26, 36, 33, 0.16);
    --pc-shadow-active: 0 12px 28px rgba(26, 36, 33, 0.22);
    box-sizing: border-box;
    position: relative;
    /* The creative effect needs a fixed-size container so the slide keeps its
       dimensions while it transforms. The width mirrors the derived slide width
       (main-height × aspect-ratio) so the centered slide fills the stage; the
       height tracks the slide height. margin:auto centers the stage inside the
       clip viewport. */
    width: calc(var(--pc-main-height, 360px) * var(--pc-aspect-ratio, 16 / 9));
    height: var(--pc-main-height, 360px);
    max-width: 100%;
    margin: 0 auto;
}

.door-pivot-photo-carousel *,
.door-pivot-photo-carousel *::before,
.door-pivot-photo-carousel *::after {
    box-sizing: border-box;
}

/* ============================================
   SWIPER SHELL OVERRIDE
   The root is the Swiper viewport. Do NOT set
   transform / perspective / transform-style on
   .swiper or .swiper-wrapper here — Swiper's
   creative effect applies the 3D perspective
   itself, and overriding it breaks the
   transforms.
   ============================================ */

/* Creative viewport. overflow:visible lets the transforming slide and its
   box-shadow lift spill past the root edge so the slide reads in full while it
   moves — the slide's shadow lift would otherwise be clipped at the stage
   boundary and the slide would look "trapped" in its box with no depth. This
   mirrors the cube, flip and stacked-cards modules, which all keep the Swiper
   root visible for the same 3D-spill reason. The outer
   .door-pivot-photo-carousel-viewport clips that spill at the module boundary so
   the carousel still respects its module-wrapper width. */
.door-pivot-photo-carousel--creative.swiper {
    overflow: visible;
}

.door-pivot-photo-carousel__wrapper.swiper-wrapper {
    align-items: center;
}

/* ============================================
   SLIDE BASE
   ============================================ */

.door-pivot-photo-carousel__item.swiper-slide {
    position: relative;
    display: block;
    /* Fixed-height tile. The height is set by --pc-main-height and the width is
       derived from the admin aspect_ratio via the CSS `aspect-ratio` property;
       object-fit:cover on the image fills the box regardless of the source
       aspect ratio. width:auto lets the aspect-ratio derive the rendered width
       from the fixed height. */
    width: auto;
    height: var(--pc-main-height, 360px);
    aspect-ratio: var(--pc-aspect-ratio, 16 / 9);
    border-radius: var(--pc-radius);
    overflow: hidden;
    background: transparent;
    text-decoration: none;
    color: inherit;
}

.door-pivot-photo-carousel__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ============================================
   CAPTION OVERLAY (title + description)
   A bottom gradient band over the image, painted onto the slide face itself.
   The caption rides the face it belongs to: while a slide is the active face
   its caption stays visible, and as the slide transforms away its caption
   leaves together with the image — there is no separate show/hide. This
   mirrors the image itself, so the caption never appears or disappears
   independently of its slide.
   ============================================ */

.door-pivot-photo-carousel__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 40px 15px 15px;
    background: linear-gradient(to top, rgba(0, 0, 0, 1), transparent);
    color: #ffffff;
    z-index: 2;
    /* pointer-events:none lets the whole band sit over the image without
       blocking drag; the title link re-enables its own events. */
    pointer-events: none;
}

.door-pivot-photo-carousel__title {
    display: block;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    color: #ffffff;
    line-height: 1.4;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Title as a link: only this element is clickable inside the overlay. */
.door-pivot-photo-carousel__title--link {
    text-decoration: none;
    transition: color 0.2s ease;
    pointer-events: auto;
    cursor: pointer;
}

.door-pivot-photo-carousel__title--link:hover {
    color: rgba(255, 255, 255, 0.85);
    text-decoration: underline;
}

.door-pivot-photo-carousel__desc {
    font-weight: 600;
    text-decoration: none;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    padding-bottom: 15px;
    margin-top: 6px;
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.9);
}

/* ============================================
   SLIDE ELEVATION
   Each tile always carries a box-shadow lift so it reads as a solid framed
   surface. The creative effect's per-direction shadow knob (in the effect
   config) is separate from this elevation and managed by Swiper itself; there
   is no admin toggle for it here, so the lift is applied unconditionally. The
   active slide earns a slightly stronger lift to read as the focal point.
   ============================================ */

.door-pivot-photo-carousel__item {
    box-shadow: var(--pc-shadow);
}

.door-pivot-photo-carousel__item.swiper-slide-active {
    box-shadow: var(--pc-shadow-active);
}

/* Dark mode: the light-mode shadow tint (green-grey on a near-black field)
   dissolves and the slide looks flat. Lift the opacity and shift the tint
   toward true black so the slide separates from the charcoal-teal canvas
   instead of disappearing into it. Active stays a step stronger than rest. */
[data-bs-theme="dark"] {
    --pc-shadow: 0 8px 22px rgba(0, 0, 0, 0.55);
    --pc-shadow-active: 0 12px 30px rgba(0, 0, 0, 0.65);
}

/* ============================================
   NAVIGATION ARROWS
   Mirrors the other photo carousels' arrows so all
   share an identical control style.
   ============================================ */

/* The arrows carry Swiper's .swiper-button-prev/next classes too, so Swiper
   already provides position/top/size/placement via the --swiper-navigation-*
   tokens set on the clip viewport above (the arrows' containing block, since
   they live as siblings of the Swiper root). Only the visual layer (face,
   color, reveal-on-hover) is layered on top — no left/right/margin overrides
   needed, which avoids any specificity clash with Swiper's selectors. */
.door-pivot-photo-carousel__nav {
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.9);
    box-shadow: var(--shadow-sm);
    opacity: 0;
    transition: background 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

/* Reveal arrows on hover over the whole module. The arrows are siblings of the
   Swiper root (inside the viewport), so the :hover is scoped to the viewport —
   the element that contains both the carousel and the arrows. */
.door-pivot-photo-carousel-viewport:hover .door-pivot-photo-carousel__nav {
    opacity: 1;
}

.door-pivot-photo-carousel__nav:hover {
    background: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.door-pivot-photo-carousel__nav:focus-visible {
    outline: 3px solid var(--accent-color, #c2683f);
    outline-offset: 3px;
}

.door-pivot-photo-carousel__nav svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Disabled arrow: a dimmed-but-visible control (0.3 opacity) rather than fully
   hidden, so the user reads it as "no more slides in that direction" instead of
   the control vanishing. Swiper's own .35 opacity is overridden here. */
.door-pivot-photo-carousel__nav.swiper-button-disabled {
    opacity: 0.3;
    cursor: not-allowed;
    pointer-events: none;
}

.door-pivot-photo-carousel-viewport:hover .door-pivot-photo-carousel__nav.swiper-button-disabled {
    opacity: 0.3;
}

/* Dark mode: dark button face with a light icon. */
[data-bs-theme="dark"] .door-pivot-photo-carousel__nav {
    background: rgba(30, 30, 30, 0.9);
    color: #d7dedb;
}

[data-bs-theme="dark"] .door-pivot-photo-carousel__nav:hover {
    background: #161c1a;
}

/* ============================================
   DOT INDICATORS
   Swiper renders .swiper-pagination-bullet inside
   the .door-pivot-photo-carousel__dots container.
   Styled to mirror the other photo carousels'
   indicator look.
   ============================================ */

.door-pivot-photo-carousel__dots.swiper-pagination {
    /* Absolutely positioned at the bottom of the clip viewport so the dots row
       does NOT add to the viewport's flow height. This keeps the viewport height
       equal to the Swiper root height, which is what the nav arrows' top:50%
       centers against — otherwise the dots (~36px) push the vertical midpoint
       down and the arrows sit below the slide center. */
    position: absolute;
    left: 0;
    right: 0;
    bottom: 14px;
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 0;
    --swiper-pagination-bullet-horizontal-gap: 0;
}

.door-pivot-photo-carousel__dots .swiper-pagination-bullet {
    width: 10px;
    height: 10px;
    margin: 0;
    border: none;
    border-radius: 50%;
    background: var(--border-strong, #c4ccc8);
    opacity: 1;
    /* Swiper defaults inactive bullets to transform:scale(.33); reset to none so
       the dots read as full-size circles. */
    transform: none;
    transition: background 0.2s ease, transform 0.2s ease;
}

.door-pivot-photo-carousel__dots .swiper-pagination-bullet:hover {
    background: var(--text-muted);
}

.door-pivot-photo-carousel__dots .swiper-pagination-bullet-active {
    background: var(--cc-dot-active-color, var(--primary-color));
    transform: scale(1.2);
}

[data-bs-theme="dark"] .door-pivot-photo-carousel__dots .swiper-pagination-bullet {
    background: var(--border-strong);
}

[data-bs-theme="dark"] .door-pivot-photo-carousel__dots .swiper-pagination-bullet:hover {
    background: var(--text-muted);
}

[data-bs-theme="dark"] .door-pivot-photo-carousel__dots .swiper-pagination-bullet-active {
    background: var(--cc-dot-active-color, var(--primary-color));
}

/* ============================================
   REDUCED MOTION
   Strip transitions for users who prefer reduced
   motion; behavior stays intact (Swiper speed is
   set to 0 by the engine).
   ============================================ */

@media (prefers-reduced-motion: reduce) {
    .door-pivot-photo-carousel__nav,
    .door-pivot-photo-carousel__dots .swiper-pagination-bullet {
        transition: none !important;
    }

    .door-pivot-photo-carousel__dots .swiper-pagination-bullet-active {
        transform: none;
    }
}

/* ============================================
   RESPONSIVE — narrow screens.
   Breakpoint matches the other photo carousels
   (767px) so the arrow icon size shift is
   identical across all of them.
   ============================================ */

@media (max-width: 767px) {
    .door-pivot-photo-carousel-viewport {
        /* Switch the viewport padding to the mobile-sized pair. The data prep
           computes the desktop padding from the full slide height, but on a phone
           the slide shrinks to 200px (see the --pc-main-height rule below), so
           the desktop padding would be too generous. Reassigning the SAME custom
           properties (rather than overriding padding-top/bottom directly) keeps
           the base padding rule unchanged AND lets the nav-offset calc above
           recompute from the mobile values automatically. !important is required
           for the same reason as --pc-main-height below: the renderer sets these
           inline on the viewport, and inline custom-property declarations win
           over a plain media-query rule. NOTE: door pivot mobile height is 200px. */
        --pc-viewport-pad-top: var(--pc-viewport-pad-top-mobile, 16px) !important;
        --pc-viewport-pad-bottom: var(--pc-viewport-pad-bottom-mobile, 48px) !important;
    }

    .door-pivot-photo-carousel {
        /* Smaller slide on narrow screens so the slide still fits within the
           viewport without dominating it. !important is required because the
           renderer sets --pc-main-height inline on the root from the admin
           main_height setting; inline custom-property declarations win over a
           plain media-query rule, so without !important the mobile shrink would
           be ignored and a large slide would overflow narrow viewports. The
           200px here is the mobile slide height. */
        --pc-main-height: 200px !important;
    }

    .door-pivot-photo-carousel__nav svg {
        width: 16px;
        height: 16px;
    }

    .door-pivot-photo-carousel__caption {
        padding: 30px 12px 12px;
    }

    .door-pivot-photo-carousel__title {
        font-size: 0.85rem;
    }

}
