/*! Theme Name: dhive
Author: Digital Hyve
template: bb-theme
*/

/**
 * Photo gallery: sticky "Jump to" navigation.
 * Paired with assets/scripts/gallery-nav.js.
 */

/* --------------------------------------------------------------------------
   Section headings
   -------------------------------------------------------------------------- */

/**
 * Offset scroll targets by the sticky header and the pinned bar, both measured
 * in JS, so a heading never lands underneath either one.
 */
.gallery-nav__heading {
    scroll-margin-top: calc(
        var(--gallery-nav-offset, 0px) + var(--gallery-nav-height, 0px) + 20px
    );
}

/* The rule that closes each section title off from the photos under it. */
.gallery-nav__heading .fl-heading {
    border-bottom: 1px solid rgba(0, 0, 0, 0.12);
    padding-bottom: 12px;
}

html,
body {
    overflow-x: clip;
}

/* --------------------------------------------------------------------------
   "Jump to" bar
   -------------------------------------------------------------------------- */

/**
 * The bar pins under the sticky header for the length of the gallery.
 *
 * Sticky positioning is bounded by the element's parent, and each gallery sits
 * in its own Beaver Builder row, so the script lifts this bar out to be a
 * sibling of those rows. Its parent is then .fl-builder-content, which spans
 * every section. The inner wrapper carries Beaver Builder's own row width
 * classes, which is what keeps the bar aligned with the photos below it.
 *
 * The header container is z-index 100, so staying under that leaves the header
 * on top while the bar still clears the photo grids.
 */
.gallery-nav__bar {
    position: sticky;
    top: var(--gallery-nav-offset, 0px);
    z-index: 20;
}

/**
 * Close the gap above the pinned bar.
 *
 * Two things open one. The offset is measured to the bottom of the header
 * container, but on narrow screens the header's last row runs transparent for
 * its final ten pixels or so; and on wider screens the bar deliberately stands
 * off the header. Photos would show through both. This fills the strip in the
 * page colour, only while pinned, and the header paints over whatever part of
 * it the header itself covers, at z-index 100.
 */
.gallery-nav__bar.is-stuck::before {
    background: #fcfcfc;
    bottom: 100%;
    content: "";
    height: 30px;
    left: 0;
    position: absolute;
    right: 0;
}

/**
 * Wider screens have the room for the bar to breathe: the 12px it used to get
 * from the row it sat in, back above it at rest, and the same again between it
 * and the header once pinned.
 */
@media only screen and (min-width: 601px) {
    /* The margin sets the resting gap only. A sticky element's pinned position
       comes from its top inset alone, so the standoff has to be added there
       too rather than inherited from the margin. */
    .gallery-nav__bar {
        margin-top: 12px;
        top: calc(var(--gallery-nav-offset, 0px) + 12px);
    }
}

.gallery-nav {
    align-items: center;
    /* Opaque so photos do not show through once the bar is pinned. This is the
       flat equivalent of rgba(0, 0, 0, 0.03) over the #fcfcfc page. */
    background: #f4f4f4;
    border-radius: 4px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-bottom: 30px;
    padding: 15px 20px;
}

/* Lift the bar off the photos sliding underneath it, but only once pinned. */
.gallery-nav__bar.is-stuck .gallery-nav {
    border-radius: 0 0 4px 4px;
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.14);
}

.gallery-nav__label {
    font-weight: 700;
}

.gallery-nav__list {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    gap: 10px 20px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.gallery-nav__list li {
    margin: 0;
}

.gallery-nav__link {
    text-decoration: underline;
    transition: color 250ms ease, text-decoration-thickness 250ms ease;
}

/**
 * The section being read, in the same red the section headings use.
 *
 * Colour and underline weight only. Anything that changes the text's width,
 * bold included, would shuffle the links sideways as the reader scrolls from
 * one section to the next, which on the narrow scrolling strip reads as jitter.
 */
.gallery-nav__link.is-current {
    color: #d72027;
    text-decoration-thickness: 2px;
}

/* --------------------------------------------------------------------------
   "Back to top"
   -------------------------------------------------------------------------- */

/**
 * The .fl-page prefix is load bearing. The skin sets a dark fill, white text,
 * a border and a 24px font on ".fl-page button", at specificity (0,1,1), which
 * outweighs a lone class. Everything the skin touches is declared here across
 * all four states, so the fill set below is the only thing that changes.
 */
.fl-page .gallery-nav__top,
.fl-page .gallery-nav__top:hover,
.fl-page .gallery-nav__top:focus,
.fl-page .gallery-nav__top:active {
    align-items: center;
    border: 1px solid currentColor;
    border-radius: 3px;
    box-shadow: none;
    color: inherit;
    cursor: pointer;
    display: flex;
    flex: 0 0 auto;
    font: inherit;
    font-size: 0.875em;
    gap: 8px;
    letter-spacing: inherit;
    line-height: inherit;
    padding: 6px 14px;
    text-decoration: none;
    text-transform: inherit;
    white-space: nowrap;
}

/**
 * Background is kept out of the block above so hover has something to say. The
 * skin's own hover is a dark fill with white text, which is a lot of weight for
 * a small secondary control, so this is a light tint instead. Both rules
 * outrank ".fl-page button" and ".fl-page button:hover" respectively.
 */
.fl-page .gallery-nav__top {
    background: none;
}

.fl-page .gallery-nav__top:hover,
.fl-page .gallery-nav__top:focus {
    background: rgba(0, 0, 0, 0.08);
}

.gallery-nav__top:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
}

/**
 * Hidden until the bar pins, with visibility rather than display so its space
 * in the bar is always reserved. The delay holds it on screen until the fade
 * has finished; hidden, it is out of the tab order and off the accessibility
 * tree. Kept off the rules above so the pinned states cannot outrank it.
 */
.gallery-nav__top {
    opacity: 0;
    transition: opacity 250ms ease, visibility 0s linear 250ms;
    visibility: hidden;
}

.gallery-nav__bar.is-stuck .gallery-nav__top {
    opacity: 1;
    transition: opacity 250ms ease;
    visibility: visible;
}

/* Chevron, drawn from borders so it always matches the button's colour. */
.gallery-nav__top-icon {
    border-left: 2px solid currentColor;
    border-top: 2px solid currentColor;
    display: block;
    flex: 0 0 auto;
    height: 0.5em;
    margin-top: 0.2em;
    transform: rotate(45deg);
    width: 0.5em;
}

/* --------------------------------------------------------------------------
   Row spacing
   -------------------------------------------------------------------------- */

.gallery-row {
    padding-bottom: 0 !important;
    padding-top: 12px !important;
}

.pp-photo-gallery-content {
    padding-bottom: 30px;
}

/* --------------------------------------------------------------------------
   Narrow screens
   -------------------------------------------------------------------------- */

/**
 * Small screens get a single row instead of a stacked layout.
 *
 * Stacked, the bar ran to 138px, which on a phone costs a third of the visible
 * page once the header is counted. Kept to one row it is roughly 40px. The
 * links scroll sideways rather than wrapping, because the bar has to be the
 * same height pinned and unpinned: a sticky element still occupies its original
 * space in flow, so a height that changed on pinning would drag the photos up
 * under the reader's finger.
 */
@media only screen and (max-width: 600px) {
    .gallery-nav {
        flex-wrap: nowrap;
        gap: 12px;
        padding: 10px 15px;
    }

    .gallery-nav__label {
        flex: 0 0 auto;
    }

    /* Pinned, the links get the whole strip. The label is decorative and the
       nav keeps its aria-label, so nothing is lost by dropping it. */
    .gallery-nav__bar.is-stuck .gallery-nav__label {
        display: none;
    }

    /**
     * Scrollbar hidden: it costs vertical room the bar cannot spare, and the
     * part-visible last link is the affordance touch devices go by anyway.
     *
     * "safe" centring is what makes centring and scrolling coexist. Plain
     * "center" pushes the overflow out both sides of a scroller and puts the
     * first link somewhere the reader cannot scroll back to; "safe" falls back
     * to the left edge as soon as the links stop fitting.
     */
    .gallery-nav__list {
        flex-wrap: nowrap;
        justify-content: safe center;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .gallery-nav__list::-webkit-scrollbar {
        display: none;
    }

    .gallery-nav__list li {
        white-space: nowrap;
    }

    /* Desktop only. The strip is 42px here and has no room to spare, and a
       phone's own scroll gesture already gets you back up quickly. Prefixed to
       outrank the display:flex the state rules above set. */
    .fl-page .gallery-nav__top {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .gallery-nav__link,
    .gallery-nav__top,
    .gallery-nav__bar.is-stuck .gallery-nav__top {
        transition: none;
    }
}
