/* ---------- collapsible gallery groups ---------- */

/* Put ONE custom class, "gallery-group", on a Group block, then drop plain Gallery blocks
   inside it — no per-gallery class needed. The Group tiles its galleries in a responsive
   grid, and assets/js/gallery-group.js collapses each gallery to its first image (the
   "cover"), expanding it on click. (The class also works placed directly on a single
   Gallery block; the :not(.wp-block-gallery) guard just skips the grid in that case.) */
.gallery-group:not(.wp-block-gallery) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 30px;
    align-items: start;
}
/* Reset the grid items' own flow margins so the grid gap alone spaces them — WordPress's
   block-gap adds a top margin to every child except the first, which otherwise makes the
   first cell sit tighter than the rest. Targets whatever the direct children are: the
   galleries themselves, or (as on the photo-gallery page) the inner Groups that each wrap a
   heading + gallery. */
.gallery-group:not(.wp-block-gallery) > * {
    margin-top: 0;
    margin-bottom: 0;
}
/* Break the expanded gallery's grid cell out to full width. The gallery may be a direct grid
   child, or nested in an inner Group with its heading — :has() lets that wrapping grid item
   break out too. */
.gallery-group:not(.wp-block-gallery) > .wp-block-gallery.is-expanded,
.gallery-group:not(.wp-block-gallery) > *:has(.wp-block-gallery.is-expanded) {
    grid-column: 1 / -1;
}
/* Fill that full width — override the constrained layout's content-size cap. */
.wp-block-gallery.is-expanded {
    width: 100%;
    max-width: none;
}
.gallery-group h3 {
font-size: var(--wp--preset--font-size--medium);
}

/* Collapsed gallery: show only the cover image, full width. The state class lives on the
   gallery (added by JS), so only galleries inside a .gallery-group are ever affected. */
.wp-block-gallery.is-collapsed {
    cursor: pointer;
}
.wp-block-gallery.is-collapsed .wp-block-image:not(.gallery-cover) {
    display: none;
}
.wp-block-gallery.is-collapsed .gallery-cover {
    flex-basis: 100% !important;
    width: 100%;
    max-width: 100%;
    margin: 0;
    position: relative;
    overflow: hidden; /* contain the hover zoom below */
}
/* Uniform cover height for a tidy grid — crops covers to 3:2. Remove this rule if you'd
   rather each cover keep its own aspect ratio. */
.wp-block-gallery.is-collapsed .gallery-cover img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transition: transform 0.3s ease;
}
/* Gentle zoom on the cover to signal it's clickable. */
.wp-block-gallery.is-collapsed:hover .gallery-cover img {
    transform: scale(1.03);
}

/* "View all N photos" button over the cover. */
.gallery-group__badge {
    position: absolute;
    top: 10px;
    right: 10px;
    border: 0;
    cursor: pointer;
    padding: 6px 12px;
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--wp--preset--color--base);
    background: var(--wp--preset--color--contrast);
    opacity: 0.92;
}
.gallery-group__badge:hover {
    background: var(--wp--preset--color--primary);
}
.wp-block-gallery.is-expanded .gallery-group__badge {
    display: none;
}

/* "Show less" control — hidden until JS reveals it (is-visible) when expanded. */
.gallery-group__collapse {
    display: none;
    border: 0;
    cursor: pointer;
    padding: 6px 14px;
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--wp--preset--color--base);
    background: var(--wp--preset--color--contrast);
}
.gallery-group__collapse.is-visible {
    display: block;
    width: fit-content;
    margin: 12px auto 0;
}
.gallery-group__collapse:hover {
    background: var(--wp--preset--color--primary);
}

/* Smooth the button hovers, and fade/slide the extra photos in as the gallery expands.
   (The reveal is a keyframe animation, not a transition, because display:none can't be
   transitioned — the animation just plays when the images switch to visible on expand.) */
.gallery-group__badge,
.gallery-group__collapse {
    transition: background-color 0.2s ease;
}
@keyframes npea-gallery-reveal {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
.wp-block-gallery.is-expanded .wp-block-image:not(.gallery-cover) {
    animation: npea-gallery-reveal 0.3s ease both;
}
@media (prefers-reduced-motion: reduce) {
    .wp-block-gallery.is-collapsed .gallery-cover img,
    .wp-block-gallery.is-expanded .wp-block-image:not(.gallery-cover) {
        transition: none;
        animation: none;
    }
}

/* Tile multiple gallery groups. Wrap them in a Group with the extra class "gallery-grid". */
.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 30px;
    align-items: start;
}
/* An expanded gallery breaks out to the full grid width so the whole gallery has room. */
.gallery-grid .gallery-group.is-expanded {
    grid-column: 1 / -1;
}

/* ---------- framed slideshow (gallery-frame) ---------- */

/* Wrap a Gallery in a Group with class "gallery-frame" to get the classic framed,
   auto-advancing crossfade slideshow (ported from templates/slideshow-small.php). The frame
   is slide-frame.svg (864x468); the slides sit in the inner 810x414 window, clipped to its
   notched corners by the objectBoundingBox clip path assets/js/gallery-frame.js injects. */
.gallery-frame {
    position: relative;
    box-sizing: border-box;
    max-width: 864px;
    margin-inline: auto;
    /* The frame border is a uniform 27px = 3.125% of the 864px width on every side, so one
       width-relative padding keeps the inner window aligned to the SVG at any size — and it
       gives the frame a real height (derived from the stage), which the parent-aspect-ratio
       approach did not. */
    padding: 3.125%;
    background: url('assets/images/slide-frame.svg') center / contain no-repeat;
}
/* Hide the gallery's title when it's shown in a frame — the frame is just the slideshow. */
.gallery-frame .wp-block-heading {
    display: none;
}
/* No stray block margins on the frame's children — they'd add height and letterbox the frame
   background (making the photo look further inset than it is). */
.gallery-frame > * {
    margin-top: 0;
    margin-bottom: 0;
}
/* The gallery is the inner "stage": it carries its OWN aspect-ratio so it has a definite
   height (deriving height from the parent's aspect-ratio collapsed it to 0), and the slides
   stack absolutely over it. The !important width/height/position beat WordPress's
   high-specificity gallery-column rules, which otherwise pin each slide at its ~25% flex
   width and leave the stack broken. */
.gallery-frame .wp-block-gallery {
    position: relative;
    width: 100%;
    max-width: none;
    aspect-ratio: 810 / 414;
    margin: 0;
    gap: 0;
}
.gallery-frame .wp-block-image {
    position: absolute !important;
    inset: 0;
    margin: 0 !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    opacity: 0;
    transition: opacity 1.2s ease;
    pointer-events: none;
    /* Clip each slide (not the stage) to the frame's notched window, so the dots/arrows the
       JS adds to the stage aren't clipped away. */
    clip-path: url(#npea-slide-clip);
}
.gallery-frame .wp-block-image.is-active {
    opacity: 1;
    pointer-events: auto;
}
.gallery-frame .wp-block-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* The slides' own inline captions are hidden — they'd stack over the photo. Instead
   gallery-frame.js mirrors the active slide's caption into .gallery-frame__caption, a single
   band below the frame (like the old carousel's caption). */
.gallery-frame .wp-block-gallery figcaption {
    display: none;
}

/* Control row beneath the frame: prev arrow, caption, next arrow — brown, centered. It sits in
   normal flow (inserted as the frame's sibling by gallery-frame.js), so the row grows to fit a
   multi-line caption instead of overlapping whatever follows the slideshow. */
.gallery-frame__controls {
    max-width: 864px;
    margin: 0.6em auto 1.5em;
    padding: 0 2%;
    display: flex;
    align-items: center;
    /* space-between pins the arrows to the left/right edges, so they hold the same position
       whether or not the current slide has a caption (the caption just centers between them). */
    justify-content: space-between;
    gap: 0.4em;
}
.gallery-frame__caption {
    flex: 1 1 auto;
    text-align: center;
    line-height: 1.35;
    font-size: clamp(13px, 1.4vw, 15px);
    color: var(--wp--preset--color--contrast);
}
.gallery-frame__caption:empty {
    display: none;
}

/* Indicator dots. */
.gallery-frame__dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 4%;
    z-index: 2;
    display: flex;
    justify-content: center;
    gap: 8px;
}
.gallery-frame__dots button {
    width: 11px;
    height: 11px;
    padding: 0;
    cursor: pointer;
    border: 2px solid var(--wp--preset--color--base);
    border-radius: 50%;
    background: transparent;
}
.gallery-frame__dots button.is-active {
    background: var(--wp--preset--color--base);
}

/* Prev/next arrows (npea-glyphs-arrow, same as the old carousel controls) — inline in the
   control row below the frame, flanking the caption. */
.gallery-frame__arrow {
    flex: 0 0 auto;
    padding: 0 10px;
    border: 0;
    background: none;
    cursor: pointer;
    line-height: 1;
    font-size: 38px;
    color: var(--wp--preset--color--contrast);
}
.gallery-frame__arrow:hover { color: var(--wp--preset--color--primary); }

/* The ornate frame doesn't scale down gracefully, so on small screens drop it and show the
   slides as a plain crossfade — same as the old theme, which removed the frame on mobile. */
@media (max-width: 600px) {
    .gallery-frame {
        padding: 0;
        background: none;
    }
    .gallery-frame .wp-block-image {
        clip-path: none;
    }
}