/* ============================================
   CARDS PHOTO CAROUSEL MODULE (Swiper-based)
   Single display mode: cards (stacked deck).
   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 cards effect; this stylesheet only
   styles the module shell, slides, captions, and
   controls.
   ============================================ */

.cards-photo-carousel-viewport {
    /* Clip wrapper. The Swiper root inside keeps overflow:visible so the
       stacked cards (each rotated + offset behind the active one) read in full;
       this wrapper 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 + card 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 CARD's vertical center instead. The padding values are
       dynamic (sized from the admin rotation setting via --pc-viewport-pad-*),
       so the correction reads the SAME custom properties to stay on the card
       center at any rotation. The extra -4px nudges the arrows slightly above
       the geometric center (the -4px aesthetic buffer, kept from the original
       fixed-padding layout). All three vars live on this viewport rule, so the
       calc resolves in a single scope. */
    --swiper-navigation-top-offset: calc(50% + (var(--pc-viewport-pad-top, 12px) - var(--pc-viewport-pad-bottom, 40px)) / 2 - 4px);
    --swiper-navigation-color: var(--text-ink);
    /* Top/bottom padding so the stacked deck has breathing room above (enough to
       clear the rotated cards' lifted corners) and the dots band sits clear below
       the cards. The values are sized from the admin rotation setting by the data
       prep (cardsViewportPaddingFor) and ride in as --pc-viewport-pad-* on this
       element. The defaults (12px / 40px) match the perSlideRotate = 0 case and
       only apply if the renderer never set the custom property. The cards effect
       centers a single card, so no horizontal side-card padding is needed (unlike
       coverflow). */
    padding: var(--pc-viewport-pad-top, 12px) 0 var(--pc-viewport-pad-bottom, 40px);
}

.cards-photo-carousel {
    --pc-radius: 18px;
    /* Fixed-height card. 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 card reads as
       one uniform tile regardless of the source aspect ratio. Default is
       portrait (3 / 4) for the stacked deck look; the renderer overrides it
       from the setting. */
    --pc-main-height: 320px;
    /* The renderer overrides --pc-main-height from the admin card_height setting
       (inline on the root). This declaration remains the fallback for any
       carousel rendered without that token. */
    --pc-aspect-ratio: 3 / 4;
    /* Card elevation. Tinted toward Ink (green-grey) per the design system's
       shadow vocabulary rather than pure black, and kept soft so a stacked card
       reads as grounded. 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 cards effect needs a fixed-size container so each slide keeps its
       dimensions. The width mirrors the derived card width (main-height ×
       aspect-ratio) so the centered card fills the stage; the height tracks the
       card height. margin:auto centers the stage inside the clip viewport. */
    width: calc(var(--pc-main-height, 320px) * var(--pc-aspect-ratio, 3 / 4));
    height: var(--pc-main-height, 320px);
    max-width: 100%;
    margin: 0 auto;
}

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

/* ============================================
   SWIPER SHELL OVERRIDE
   The root is the Swiper viewport.
   ============================================ */

/* Cards viewport. overflow:visible lets the stacked cards (each rotated + offset
   behind the active one) spill past the root edge so the deck reads in full.
   The outer .cards-photo-carousel-viewport clips that spill at the module
   boundary so the carousel still respects its module-wrapper width. */
.cards-photo-carousel--cards.swiper {
    overflow: visible;
}

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

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

.cards-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, 320px);
    aspect-ratio: var(--pc-aspect-ratio, 3 / 4);
    border-radius: var(--pc-radius);
    overflow: hidden;
    background: transparent;
    text-decoration: none;
    color: inherit;
}

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

/* ============================================
   CAPTION OVERLAY (title + description)
   Mirrors the Featured Pages Carousel overlay: a
   bottom gradient band over the image. Only the
   active card shows its overlay — the stacked
   cards behind hide theirs so the deck reads
   clean. The active class is kept in sync with
   Swiper's realIndex by the engine
   (cards-photo-carousel.js).
   ============================================ */

.cards-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;
    /* Hidden by default; revealed only on the active card so the stacked cards
       behind stay clean. pointer-events:none lets the whole band sit over the
       image without blocking drag; the title link re-enables its own events. */
    display: none;
    pointer-events: none;
}

.cards-photo-carousel__item--active .cards-photo-carousel__caption {
    display: block;
}

.cards-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. */
.cards-photo-carousel__title--link {
    text-decoration: none;
    transition: color 0.2s ease;
    pointer-events: auto;
    cursor: pointer;
}

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

.cards-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);
}

/* ============================================
   CARDS MODE
   Swiper's cards effect stacks each slide behind
   the active one with a rotation + offset. The
   cardShadows/slideShadows toggle gates the depth
   shadow Swiper paints between stacked cards; the
   base card keeps its box-shadow lift so each tile
   reads as a solid framed surface.
   ============================================ */

/* Card elevation is gated on the --has-shadows modifier (set by the renderer
   from the admin "slide shadows" toggle). With shadows off, tiles rest on a
   hairline edge alone. The active card earns a slightly stronger lift to read
   as the focal point; the stacked cards inherit the base shadow so they stay
   grounded behind it. */
.cards-photo-carousel--cards.cards-photo-carousel--has-shadows .cards-photo-carousel__item {
    box-shadow: var(--pc-shadow);
}

.cards-photo-carousel--cards.cards-photo-carousel--has-shadows .cards-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 cards look flat. Lift the opacity and shift the tint
   toward true black so each tile 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 coverflow carousel arrows so both
   photo carousels 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. */
.cards-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. */
.cards-photo-carousel-viewport:hover .cards-photo-carousel__nav {
    opacity: 1;
}

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

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

.cards-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. */
.cards-photo-carousel__nav.swiper-button-disabled {
    opacity: 0.3;
    cursor: not-allowed;
    pointer-events: none;
}

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

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

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

/* ============================================
   DOT INDICATORS
   Swiper renders .swiper-pagination-bullet inside
   the .cards-photo-carousel__dots container. Styled
   to mirror the coverflow carousel indicator look.
   ============================================ */

.cards-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 card center. */
    position: absolute;
    left: 0;
    right: 0;
    bottom: 14px;
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 0;
    --swiper-pagination-bullet-horizontal-gap: 0;
}

.cards-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;
}

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

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

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

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

[data-bs-theme="dark"] .cards-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) {
    .cards-photo-carousel__nav,
    .cards-photo-carousel__dots .swiper-pagination-bullet {
        transition: none !important;
    }

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

/* ============================================
   RESPONSIVE — narrow screens.
   Breakpoint matches the coverflow carousel (767px)
   so the arrow icon size shift is identical across
   both photo carousels.
   ============================================ */

@media (max-width: 767px) {
    .cards-photo-carousel-viewport {
        /* Switch the viewport padding to the mobile-sized pair. The data prep
           computes the desktop padding from the full card height, but on a phone
           the card shrinks to 220px (see the --pc-main-height rule below), so the
           desktop padding would be far 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. */
        --pc-viewport-pad-top: var(--pc-viewport-pad-top-mobile, 12px) !important;
        --pc-viewport-pad-bottom: var(--pc-viewport-pad-bottom-mobile, 40px) !important;
    }

    .cards-photo-carousel {
        /* Smaller card height on narrow screens so the stacked deck still fits
           within the viewport without dominating it. The card width keeps
           tracking the admin aspect_ratio automatically. !important is required
           because the renderer sets --pc-main-height inline on the root from the
           admin card_height setting; inline custom-property declarations win
           over a plain media-query rule, so without !important the mobile
           shrink would be ignored and large cards would overflow narrow
           viewports. The 220px here MUST stay in sync with the mobile height in
           prepareModuleCardsPhotoCarouselData (cardsViewportPaddingFor). */
        --pc-main-height: 220px !important;
    }

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

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

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

}
