/**
 * Frontend Styles for Layerframe (v2 runtime)
 */

:root {
    --lf-primary-color: #28266f;
    --lf-design-w: 1200;
    --lf-design-h: 675;
}

/* Slider Container & Wrapper */
.lf-slider-wrapper,
.lf-slider-container {
    position: relative;
    width: 100%;
    overflow: hidden;
    background-color: #000000;
    aspect-ratio: var(--lf-design-w, 1200) / var(--lf-design-h, 675);
    /* establishes a size context so flow-mode heights below can be resolved
       from the slider's own width (100cqw) rather than the viewport. */
    container-type: inline-size;
}

/* Flow Layout Mode: the slide is AT LEAST the design height (so it never
   collapses to a short row and hides the absolute layers) but can grow when
   the flow content is taller. Height is derived from the slider's own width. */
.lf-slider-wrapper.lf-has-flow {
    aspect-ratio: auto;
    min-height: calc(100cqw * (var(--lf-design-h, 675) / var(--lf-design-w, 1200)));
}

.lf-slider-wrapper.lf-has-flow .lf-main-swiper,
.lf-slider-wrapper.lf-has-flow .swiper-slide,
.lf-slider-wrapper.lf-has-flow .lf-slide-bg {
    height: auto;
    /* viewport-based fallback for browsers without container query units */
    min-height: calc(100vw * (var(--lf-design-h, 675) / var(--lf-design-w, 1200)));
    min-height: calc(100cqw * (var(--lf-design-h, 675) / var(--lf-design-w, 1200)));
}

.lf-slider-wrapper.lf-has-flow .lf-layers-container {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    aspect-ratio: var(--lf-design-w, 1200) / var(--lf-design-h, 675);
    pointer-events: none;
    z-index: 15;
}

/* Main Swiper */
.lf-main-swiper {
    width: 100%;
    height: 100%;
}

.lf-main-swiper .swiper-slide {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* Slide Background */
.lf-slide-bg {
    width: 100%;
    height: 100%;
    min-height: 100%;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    position: relative;
    display: flex;
    flex-direction: column;
}

/* Hide background image if video container is active */
.lf-slide-bg.has-video:not(:has(.lf-vimeo-container)):not(:has(.lf-plyrvideo-container)):not(:has(.lf-youtube-container)):not(:has(.lf-wistia-container)):not(:has(.lf-streamable-container)) {
    background-image: none !important;
}

.lf-slide-bg.has-video:has(.lf-vimeo-container.lf-video-live),
.lf-slide-bg.has-video:has(.lf-plyrvideo-container.lf-video-live) {
    background-image: none !important;
}

/* The same two rules for a picture that has its own element (see
 * .lf-slide-bg__pic below). */
.lf-slide-bg.has-video:not(:has(.lf-vimeo-container)):not(:has(.lf-plyrvideo-container)):not(:has(.lf-youtube-container)):not(:has(.lf-wistia-container)):not(:has(.lf-streamable-container)) .lf-slide-bg__pic,
.lf-slide-bg.has-video:has(.lf-vimeo-container.lf-video-live) .lf-slide-bg__pic,
.lf-slide-bg.has-video:has(.lf-plyrvideo-container.lf-video-live) .lf-slide-bg__pic {
    background-image: none !important;
}

/* Overlay */
.lf-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}

/* ==========================================================================
   FLOW LAYOUT (Rows, Columns, Content Stream)
   ========================================================================== */
.lf-slide-content {
    position: relative;
    z-index: 5;
    width: 100%;
    box-sizing: border-box;
}

.lf-row {
    width: 100%;
    box-sizing: border-box;
}

.lf-col {
    min-width: 0;
    box-sizing: border-box;
}

.lf-col-empty {
    min-height: 40px;
}

/* Absolute Layers Container */
.lf-layers-container {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 15;
}

/* Layer Elements */
.lf-layer {
    pointer-events: auto;
    box-sizing: border-box;
}

/* Only the live slide's layers take the pointer in a one-slide-at-a-time
 * slider. Fade and wipe stack every slide in the same place, and the
 * `pointer-events: auto` above overrode the `none` Swiper puts on an inactive
 * slide -- so the LAST slide's invisible layers caught every hover and click
 * meant for the one on screen: its button never showed its hover state, and a
 * link that differed per slide went to the wrong place. Carousels and
 * showcases keep several slides on screen at once, so they are left alone. */
.lf-slider-wrapper:not([data-slider-type="carousel"]):not([data-slider-type="showcase"]) .swiper-slide:not(.swiper-slide-active) .lf-layer {
    pointer-events: none;
}

/* Transform-isolated animation wrapper */
.lf-layer-anim {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    display: inherit;
    flex-direction: inherit;
    align-items: inherit;
    justify-content: inherit;
}

/* A masked layer: the animation runs behind this edge rather than over the
 * layout. One rule, because .lf-layer is already the positioned box and
 * .lf-layer-anim is already the animated child -- there is nothing to add.
 *
 * Deliberately no height here. The mask has to size to its content, or a
 * percentage translate inside it stops matching the text the moment the font
 * size, the copy or the line count changes, which is the entire reason to use
 * a percentage rather than a pixel figure. */
.lf-layer--masked {
    overflow: hidden;
}

/* The moving box must clip, or the counter-shifted picture would show past the moving edge. */
.lf-layer--masked.lf-layer--parallax > .lf-layer-anim {
    overflow: hidden;
}

/* Phase 10 media / embed layers */
.lf-media { display: block; width: 100%; height: 100%; }
.lf-media--video, .lf-media--youtube, .lf-media--vimeo, .lf-media--iframe { position: relative; overflow: hidden; }
.lf-media__el, iframe.lf-media--iframe { width: 100%; height: 100%; border: 0; display: block; }
.lf-media--video.lf-fit-cover .lf-media__el { object-fit: cover; }
.lf-media--video.lf-fit-contain .lf-media__el { object-fit: contain; }
.lf-media--audio { width: 100%; height: auto; }
.lf-media--icon { display: inline-flex; align-items: center; justify-content: center; }
.lf-media--icon .lf-icon { font-size: inherit; line-height: 1; }
.lf-media--list { font: inherit; }
.lf-list__row { display: flex; align-items: baseline; gap: 6px; }
.lf-media--input { font: inherit; width: 100%; box-sizing: border-box; }
.lf-iframe-deferred { display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.06); }

/* Phase 12 slide background system */
.lf-slide-bg { position: relative; }
.lf-slide-bg__backdrop,
.lf-slide-bg__fg { position: absolute; inset: 0; background-size: contain; background-position: center; background-repeat: no-repeat; }
.lf-slide-bg__backdrop { background-size: cover; transform: scale(1.1); z-index: 0; }
.lf-slide-bg__fg { z-index: 1; }
/* The slide's picture, when something acts on the picture alone -- blur, Ken
 * Burns, a background animation, the wipe. .lf-slide-bg also holds the layers,
 * so a filter or transform on it reached the text. shortcodes.php renders this
 * only when it is needed; a plain slide paints on .lf-slide-bg as before. */
.lf-slide-bg__pic { position: absolute; inset: 0; z-index: 0; }
.lf-slide-bg > .lf-overlay { z-index: 2; }
.lf-slide-bg.has-video .lf-video-wrapper { z-index: 3; }
.lf-layers-container { z-index: 15; }

/* Wipe transition -----------------------------------------------------------
 *
 * Three nested layers, and each one exists because the others cannot do its
 * job:
 *
 *   .lf-wipe-clip  the travelling edge. clip-path only.
 *   .lf-wipe-zoom  the counter-zoom and the fade. transform + opacity only.
 *   .lf-wipe-img   the picture, plus any Ken Burns, on its own transform.
 *
 * The clip and the zoom cannot share an element: clip-path is measured in the
 * element's own box and is transformed along with it, so a scale on the
 * clipping node would drag the wipe edge across the screen. Ken Burns cannot
 * share with the counter-zoom either, for the plainer reason that two
 * animations cannot write one transform.
 *
 * The two timing functions below are the substance of the effect and they are
 * deliberately different. They were fitted against a ~33ms sampling of the
 * reference, using the ratio of the two channels so the fit did not depend on
 * knowing the duration: residual 0.3% of range. Both are exposed as custom
 * properties because a fit over the first half of a transition pins the pair
 * against each other far better than it pins either one absolutely.
 * -------------------------------------------------------------------------- */
.lf-slider-wrapper[data-effect="wipe"] {
    --lf-wipe-edge-ease:  cubic-bezier(.65, 0, .35, 1);   /* the travelling edge: slow, quick, settle */
    --lf-wipe-image-ease: cubic-bezier(.56, .32, .6, 1);  /* the arriving picture: decelerating throughout */
}

/* Melt: no edge to ease, only a fade. Symmetric, like a colour tween. */
.lf-slider-wrapper[data-wipe-style="melt"] {
    --lf-wipe-image-ease: cubic-bezier(.45, 0, .55, 1);
}

.lf-wipe-clip {
    position: absolute;
    inset: 0;
    z-index: 0;
    clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
    transition-property: clip-path;
    transition-duration: 0ms;
    transition-timing-function: var(--lf-wipe-edge-ease, cubic-bezier(.65, 0, .35, 1));
}

.lf-wipe-zoom {
    position: absolute;
    inset: 0;
    transform: scale(1.02);
    transition-property: transform, opacity;
    transition-duration: 0ms;
    transition-timing-function: var(--lf-wipe-image-ease, cubic-bezier(.56, .32, .6, 1));
}

.lf-wipe-img {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* The slides are stacked rather than laid out in a row, so every one of them
 * is over the top of the others and would swallow clicks meant for the live
 * one. frontend.js re-enables the active slide. */
.lf-slider-wrapper[data-effect="wipe"] .swiper-slide { pointer-events: none; }

/* frontend.js pulls each slide's .lf-slide-bg back over the others with `left`
 * rather than transforming the slide, so the slides do not become stacking
 * contexts and every slide's text can sit above every slide's picture. The
 * slide stays where Swiper laid it out, so it must not clip what was pulled
 * out of it. The slider itself still clips. */
.lf-slider-wrapper[data-effect="wipe"] .swiper-slide { overflow: visible; }

@media (prefers-reduced-motion: reduce) {
    .lf-wipe-clip, .lf-wipe-zoom { transition-duration: 0ms !important; }
}

@keyframes lf-kb { from { transform: scale(1); } to { transform: scale(var(--lf-kb-scale, 1.12)); } }
.lf-slide-bg.lf-kb,
.lf-slide-bg__pic.lf-kb,
.lf-wipe-img.lf-kb { animation: lf-kb var(--lf-kb-dur, 20s) ease-out both; }
@keyframes lf-bg-zoom-in  { from { background-size: 100%; } to { background-size: 118%; } }
@keyframes lf-bg-zoom-out { from { background-size: 118%; } to { background-size: 100%; } }
@keyframes lf-bg-pan-left  { from { background-position: 100% 50%; } to { background-position: 0% 50%; } }
@keyframes lf-bg-pan-right { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
@keyframes lf-bg-pan-up    { from { background-position: 50% 100%; } to { background-position: 50% 0%; } }
@keyframes lf-bg-pan-down  { from { background-position: 50% 0%; } to { background-position: 50% 100%; } }
.lf-bganim--zoom-in  { animation: lf-bg-zoom-in  var(--lf-bganim-dur, 20s) ease-out both; }
.lf-bganim--zoom-out { animation: lf-bg-zoom-out var(--lf-bganim-dur, 20s) ease-out both; }
.lf-bganim--pan-left  { animation: lf-bg-pan-left  var(--lf-bganim-dur, 20s) linear infinite alternate; }
.lf-bganim--pan-right { animation: lf-bg-pan-right var(--lf-bganim-dur, 20s) linear infinite alternate; }
.lf-bganim--pan-up    { animation: lf-bg-pan-up    var(--lf-bganim-dur, 20s) linear infinite alternate; }
.lf-bganim--pan-down  { animation: lf-bg-pan-down  var(--lf-bganim-dur, 20s) linear infinite alternate; }
@media (prefers-reduced-motion: reduce) {
    .lf-slide-bg.lf-kb, .lf-slide-bg__pic.lf-kb, .lf-wipe-img.lf-kb, [class*="lf-bganim--"] { animation: none !important; }
}

/* Phase 11 rich widgets */
.lf-widget { display: block; }
.lf-counter { display: inline-block; font-variant-numeric: tabular-nums; }
.lf-circlecounter { display: inline-block; }
.lf-circlecounter__num { font-weight: 700; }
.lf-countdown { display: flex; gap: 12px; }
.lf-countdown__unit { display: flex; flex-direction: column; align-items: center; }
.lf-countdown__unit b { font-size: 2em; line-height: 1; font-variant-numeric: tabular-nums; }
.lf-countdown__unit small { opacity: .7; }
.lf-progressbar__bar { transition: none; }
.lf-progressbar__bar.is-striped { background-image: linear-gradient(45deg, rgba(255,255,255,.2) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.2) 50%, rgba(255,255,255,.2) 75%, transparent 75%); background-size: 1rem 1rem; }
/* These two render a heading tag (h1-h6) straight into .lf-layer-anim, where
   the layer's typography is set. The theme's own h2 rules (size, weight,
   margin, colour) would otherwise win over inheritance and the layer's
   settings would do nothing -- so the tag takes its type from the layer. */
.lf-layer .lf-animatedheading,
.lf-layer .lf-highlightedheading {
    margin: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: inherit;
}
.lf-animatedheading__word { display: inline-block; transition: opacity .2s ease; }
.lf-highlightedheading .lf-hl { position: relative; white-space: nowrap; }
.lf-highlightedheading .lf-hl::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: .12em; background: var(--lf-hl-color, #f5c542); z-index: -1; }
.lf-highlightedheading .lf-hl--box::after { top: -.1em; bottom: -.1em; height: auto; opacity: .35; }
.lf-highlightedheading .lf-hl--circle::after { top: -.15em; bottom: -.15em; left: -.35em; right: -.35em; height: auto; border: .1em solid var(--lf-hl-color, #f5c542); background: none; border-radius: 50%; }
.lf-highlightedheading .lf-hl--strike::after { top: 50%; bottom: auto; height: .1em; }
.lf-beforeafter { position: relative; overflow: hidden; width: 100%; height: 100%; user-select: none; }
.lf-beforeafter img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.lf-ba__before-wrap { position: absolute; inset: 0; width: 50%; overflow: hidden; }
.lf-ba--vertical .lf-ba__before-wrap { width: 100%; height: 50%; }
.lf-ba__handle { position: absolute; top: 0; bottom: 0; left: 50%; width: 3px; margin-left: -1.5px; background: #fff; cursor: ew-resize; }
.lf-ba--vertical .lf-ba__handle { left: 0; right: 0; top: 50%; bottom: auto; width: auto; height: 3px; margin: -1.5px 0 0; cursor: ns-resize; }
.lf-ba__handle:focus-visible { outline: 2px solid #2271b1; }
.lf-imagebox { display: flex; flex-direction: column; }
.lf-imagebox--left { flex-direction: row; }
.lf-imagebox--right { flex-direction: row-reverse; }
.lf-imagebox__img { max-width: 100%; height: auto; display: block; }
.lf-imagearea__spot { width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: rgba(34,113,177,.9); box-shadow: 0 0 0 6px rgba(34,113,177,.25); }
/* Visitor-facing copy, so it takes a readable size and is allowed to wrap:
   at 12px/nowrap a hotspot label longer than a few words ran off the slide. */
.lf-imagearea__spot[data-tip]:hover::after { content: attr(data-tip); position: absolute; left: 50%; bottom: 130%; transform: translateX(-50%); background: #1e1e1e; color: #fff; padding: 6px 10px; border-radius: 4px; font-size: 14px; line-height: 1.4; max-width: 30ch; width: max-content; text-align: center; }

.lf-layer--flow {
    position: relative;
    box-sizing: border-box;
}

.lf-heading-content {
    margin: 0;
    padding: 0;
    line-height: 1.2;
    box-sizing: border-box;
    word-break: break-word;
}

.lf-text-content {
    line-height: 1.5;
    box-sizing: border-box;
    word-break: break-word;
}

.lf-text-content p:first-child {
    margin-top: 0;
}

.lf-text-content p:last-child {
    margin-bottom: 0;
}

.lf-image-content {
    width: 100%;
    height: 100%;
    display: block;
    box-sizing: border-box;
    overflow: hidden;
}

img.lf-layer-img {
    width: 100%;
    height: 100%;
    display: block;
    max-width: 100%;
}

.lf-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    border: none;
    cursor: pointer;
    box-sizing: border-box;
    transition: filter 0.18s ease, transform 0.18s ease;
    user-select: none;
    font-weight: 600;
    line-height: 1;
}

.lf-button:hover {
    filter: brightness(1.12);
    transform: translateY(-1px);
}

.lf-button:active {
    transform: translateY(0);
}

/* Block Slider Type */
.lf-slider--block {
    cursor: default;
}

/* Admin notice for empty slider */
.lf-admin-notice {
    padding: 16px 20px;
    background: #f0f6fc;
    border: 1px solid #c8d7e1;
    border-left: 4px solid #2271b1;
    color: #1d2327;
    font-size: 14px;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
    margin: 16px 0;
    border-radius: 2px;
}

/* Navigation Arrows */
.lf-nav-prev,
.lf-nav-next {
    position: absolute;
    bottom: 38px;
    transform: translateY(-50%);
    z-index: 25;
    background: transparent;
    border: none;
    color: #ffffff;
    cursor: pointer;
    transition: all 0.3s ease;
    padding: 14px 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lf-nav-prev {
    right: 68px;
}

.lf-nav-next {
    right: 26px;
}

@media (min-width: 768px) {
    .lf-nav-prev,
    .lf-nav-next {
        bottom: 53px;
        color: rgba(255, 255, 255, 0.75);
    }

    .lf-nav-prev {
        right: 80px;
    }

    .lf-nav-next {
        right: 40px;
    }
}

.lf-nav-prev:hover,
.lf-nav-next:hover {
    color: #ffffff;
    transform: translateY(-50%) scale(1.1);
}

/* =====================================================
   VIDEO STYLES (HTML5, YouTube, Vimeo, Wistia, Streamable)
   ===================================================== */
.lf-video-wrapper {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
}

.lf-video-poster {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background-size: cover;
    background-position: center;
}

.lf-video-poster img {
    width: 100% !important;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.lf-play-video {
    position: absolute;
    z-index: 20;
    background: rgba(0, 0, 0, 0);
    border: none;
    color: #fff;
    width: 84px;
    height: 84px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    cursor: pointer;
    transition: transform 0.12s ease, background 0.12s ease;
}

.lf-play-video:hover {
    transform: scale(1.06);
}

.lf-play-video .play-icon {
    width: 64px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lf-play-video .play-svg {
    width: 100%;
    height: 100%;
    fill: currentColor;
}

.lf-video-placeholder {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 2;
}

/* YouTube Wrapper */
.lf-youtube-wrapper {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    overflow: hidden;
    background-color: #000000;
}

.lf-youtube-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.lf-youtube-container iframe {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: max(100vw, calc(100vh * (16 / 9))) !important;
    height: max(100vh, calc(100vw * (9 / 16))) !important;
    border: none;
    max-width: none !important;
}

/* Wistia Wrapper */
.lf-wistia-wrapper {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    overflow: hidden;
    background-color: #000000;
}

.lf-wistia-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    overflow: hidden;
}

.lf-wistia-container iframe {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: max(100vw, calc(100vh * (16 / 9))) !important;
    height: max(100vh, calc(100vw * (9 / 16))) !important;
    border: none;
    max-width: none !important;
}

/* Streamable Wrapper */
.lf-streamable-wrapper {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
    overflow: hidden;
    background-color: #000000;
}

.lf-streamable-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    overflow: hidden;
}

.lf-streamable-container iframe {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: max(100vw, calc(100vh * (16 / 9))) !important;
    height: max(100vh, calc(100vw * (9 / 16))) !important;
    border: none;
    max-width: none !important;
}

/* Vimeo Wrapper & Plyr Container */
.lf-vimeo-wrapper,
.lf-vimeo-container {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.lf-vimeo-container iframe {
    position: relative;
    width: 100%;
    height: 200% !important;
    top: -50% !important;
    border: none;
}

/* Native Plyr Video Container */
.lf-plyrvideo-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background-color: #000;
}

.lf-plyrvideo-container .plyr,
.lf-plyrvideo-container .plyr__video-wrapper {
    width: 100% !important;
    height: 100% !important;
    padding-bottom: 0 !important;
    transform: none !important;
    background: transparent !important;
}

.lf-plyrvideo-container video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
}

.lf-plyrvideo-container.lf-native-fit-cover video {
    object-fit: cover;
}

.lf-plyrvideo-container.lf-native-fit-contain video {
    object-fit: contain;
}

/* Video loading indicator */
.lf-vimeo-container .plyr,
.lf-vimeo-container iframe,
.lf-plyrvideo-container .plyr {
    transition: opacity 0.5s ease;
}

.lf-vimeo-container.lf-video-pending .plyr,
.lf-vimeo-container.lf-video-pending iframe,
.lf-plyrvideo-container.lf-video-pending .plyr {
    opacity: 0 !important;
}

.lf-video-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: none;
    align-items: center;
    gap: 10px;
    padding: 10px 18px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 14px;
    line-height: 1;
    white-space: nowrap;
    z-index: 6;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.lf-vimeo-container.lf-video-pending .lf-video-loading,
.lf-plyrvideo-container.lf-video-pending .lf-video-loading {
    display: flex;
    opacity: 1;
    animation: lf-video-loading-appear 0.3s ease 0.6s backwards;
}

@keyframes lf-video-loading-appear {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.lf-video-loading-spinner {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: lf-video-loading-spin 0.8s linear infinite;
}

@keyframes lf-video-loading-spin {
    to { transform: rotate(360deg); }
}

/* Mobile responsive rules */
@media (max-width: 768px) {
    .lf-video-wrapper,
    .lf-vimeo-wrapper,
    .lf-vimeo-container,
    .lf-youtube-wrapper,
    .lf-youtube-container,
    .lf-wistia-wrapper,
    .lf-wistia-container,
    .lf-streamable-wrapper,
    .lf-streamable-container {
        width: 100% !important;
        height: 100% !important;
        overflow: hidden !important;
    }

    .lf-video-wrapper video {
        width: 100% !important;
        height: 100% !important;
        object-fit: cover !important;
    }
}

/* Shape Dividers */
.lf-shape-divider {
    position: absolute;
    left: 0;
    right: 0;
    width: 100%;
    pointer-events: none;
    overflow: hidden;
    line-height: 0;
}

.lf-shape-divider svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* Particles Container */
.lf-particles-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 3;
    overflow: hidden;
}

/* Carousel & Showcase Slider Types */
.lf-slider-wrapper[data-slider-type="carousel"] .swiper-slide,
.lf-slider-wrapper[data-slider-type="showcase"] .swiper-slide {
    width: 80%;
    max-width: 960px;
    box-sizing: border-box;
}

.lf-slider-wrapper[data-slider-type="showcase"] .swiper-slide {
    transition: transform 0.5s ease;
}

/* =========================================================================
   Phase 15: Modular Widgets & Controls CSS
   ========================================================================= */

/* Navigation Arrows */
.lf-nav-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
    cursor: pointer;
    border: none;
    outline: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--lf-arrow-size, 40px);
    height: var(--lf-arrow-size, 40px);
    color: var(--lf-arrow-color, #ffffff);
    background: var(--lf-arrow-bg, rgba(0, 0, 0, 0.4));
    transition: background-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
    padding: 0;
}

.lf-nav-prev {
    left: var(--lf-arrow-offset, 16px);
}

.lf-nav-next {
    right: var(--lf-arrow-offset, 16px);
}

.lf-nav-arrow:hover {
    color: var(--lf-arrow-hover-color, #ffffff);
    background: var(--lf-arrow-hover-bg, rgba(0, 0, 0, 0.8));
}

.lf-nav-style-circle {
    border-radius: 50%;
}

.lf-nav-style-square {
    border-radius: 4px;
}

.lf-nav-style-clean {
    background: transparent !important;
}

.lf-nav-arrow svg {
    width: 60%;
    height: 60%;
}

/* Grouped arrows: prev and next side by side in one spot, for any placement
   other than 'sides'. The group is what is positioned; the buttons inside
   drop every rule that anchors them to an edge -- both the .lf-nav-arrow
   block above and the older .lf-nav-prev / .lf-nav-next block near the top
   of this file, whose right/bottom offsets and hover scale would otherwise
   still apply and pull them apart. */
.lf-nav-group {
    position: absolute;
    z-index: 25;
    display: flex;
    align-items: center;
    gap: var(--lf-nav-gap, 24px);
}
.lf-nav-place-bottom-left   { left: var(--lf-nav-x, 24px); bottom: var(--lf-nav-y, 24px); }
.lf-nav-place-bottom-right  { right: var(--lf-nav-x, 24px); bottom: var(--lf-nav-y, 24px); }
.lf-nav-place-top-left      { left: var(--lf-nav-x, 24px); top: var(--lf-nav-y, 24px); }
.lf-nav-place-top-right     { right: var(--lf-nav-x, 24px); top: var(--lf-nav-y, 24px); }
.lf-nav-place-bottom-center { left: 50%; bottom: var(--lf-nav-y, 24px); transform: translateX(-50%); }
.lf-nav-place-top-center    { left: 50%; top: var(--lf-nav-y, 24px); transform: translateX(-50%); }

.lf-nav-group .lf-nav-prev,
.lf-nav-group .lf-nav-next,
.lf-nav-group .lf-nav-prev:hover,
.lf-nav-group .lf-nav-next:hover {
    position: static;
    left: auto;
    right: auto;
    top: auto;
    bottom: auto;
    transform: none;
    margin: 0;
}

/* Text arrows: words instead of chevrons, so no box, no fixed size and no
   background -- just type in the arrow colours. Works in a group and in the
   original 'sides' layout alike. */
.lf-nav-arrow.lf-nav-style-text {
    width: auto;
    height: auto;
    padding: 4px 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    color: var(--lf-arrow-color, #ffffff);
    font-size: var(--lf-nav-font-size, 11px);
    font-weight: var(--lf-nav-font-weight, 600);
    letter-spacing: var(--lf-nav-ls, 0.2em);
    line-height: 1;
    font-family: inherit;
    transition: color 0.2s ease;
}
.lf-nav-arrow.lf-nav-style-text:hover,
.lf-nav-arrow.lf-nav-style-text:focus-visible {
    background: transparent;
    color: var(--lf-arrow-hover-color, #ffffff);
}
.lf-nav-arrow.lf-nav-style-text:focus-visible {
    outline: 1px solid currentColor;
    outline-offset: 4px;
}

/* Pill arrows: neo-brutalist outlined buttons.
   Specific enough (.lf-nav-arrow.lf-nav-style-pill) to beat the older 
   .lf-nav-prev:hover scale(1.1) and .lf-nav-group .lf-nav-prev:hover transform: none. */
.lf-nav-arrow.lf-nav-style-pill {
    display: inline-flex;
    gap: 0.4em;
    align-items: center;
    width: auto;
    height: auto;
    padding: 0.55em 1.15em;
    border: 2px solid var(--lf-arrow-color);
    border-radius: 999px;
    background: var(--lf-arrow-bg);
    color: var(--lf-arrow-color);
    box-shadow: 2px 2px 0 var(--lf-arrow-color);
    font-size: var(--lf-nav-font-size, 11px);
    font-weight: var(--lf-nav-font-weight, 600);
    letter-spacing: var(--lf-nav-ls, 0.2em);
    line-height: 1;
    font-family: inherit;
    transition: transform 0.15s, box-shadow 0.15s;
}
.lf-nav-arrow.lf-nav-style-pill:hover,
.lf-nav-arrow.lf-nav-style-pill:focus-visible {
    background: var(--lf-arrow-hover-bg);
    color: var(--lf-arrow-hover-color);
    transform: translateY(-50%) translate(-1px, -1px);
    box-shadow: 3px 3px 0 var(--lf-arrow-color);
}
.lf-nav-arrow.lf-nav-style-pill:active {
    transform: translateY(-50%) translate(1px, 1px);
    box-shadow: 0 0 0;
}
.lf-nav-group .lf-nav-arrow.lf-nav-style-pill:hover,
.lf-nav-group .lf-nav-arrow.lf-nav-style-pill:focus-visible {
    transform: translate(-1px, -1px);
}
.lf-nav-group .lf-nav-arrow.lf-nav-style-pill:active {
    transform: translate(1px, 1px);
}
.lf-nav-arrow.lf-nav-style-pill svg {
    width: 1em;
    height: 1em;
}

.lf-nav-upper {
    text-transform: uppercase;
}

@media (max-width: 767px) {
    .lf-hide-on-mobile {
        display: none !important;
    }
}

/* Chapter nav -----------------------------------------------------------------
 *
 * A grouped prev / label / next cluster and a segmented progress bar.
 *
 * Placed AFTER both arrow blocks on purpose. There are two live sets of arrow
 * rules above -- the legacy one near the top of this file and the widget one
 * just here -- and they only avoid contradicting each other through CSS
 * over-constraint. A rule landing between them inherits that argument. This
 * block shares no selector with either.
 *
 * The horizontal centring is translateX(-50%) rather than left/right offsets,
 * so the cluster stays centred whatever its label says. Labels change per
 * slide and change width as they go.
 * -------------------------------------------------------------------------- */
.lf-chapter-nav {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    z-index: 25;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px;
    color: var(--lf-cn-color, #fff);
}

.lf-chapter-pos-bottom {
    bottom: var(--lf-cn-offset, 40px);
}

.lf-chapter-pos-top {
    top: var(--lf-cn-offset, 40px);
}

.lf-chapter-nav--pill {
    background: var(--lf-cn-bg, rgba(255, 255, 255, 0.15));
    border-radius: 100px;
}

.lf-chapter-prev,
.lf-chapter-next {
    width: var(--lf-cn-size, 34px);
    height: var(--lf-cn-size, 34px);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 100px;
    cursor: pointer;
    color: inherit;
    background: var(--lf-cn-bg, rgba(255, 255, 255, 0.15));
    transition: background-color 0.25s, opacity 0.25s;
}

.lf-chapter-nav--bare .lf-chapter-prev,
.lf-chapter-nav--bare .lf-chapter-next {
    background: transparent;
}

.lf-chapter-prev:hover,
.lf-chapter-next:hover {
    background: var(--lf-cn-color, #fff);
    color: #000;
}

.lf-chapter-label {
    padding: 0 10px;
    font-size: 14px;
    line-height: 1;
    white-space: nowrap;
    color: inherit;
}

/* The segmented bar. Full-bleed within the slider's own gutter, one segment
 * per slide, and the ARRIVING segment fills while the slide is changing --
 * it is the transition's own progress drawn as a bar, not a second animation
 * with its own timer. frontend.js hands it the transition's duration and the
 * wipe's own easing so the two cannot drift apart at a duration nobody tested. */
.lf-chapter-progress {
    position: absolute;
    left: 2.23%;
    right: 2.23%;
    z-index: 25;
    display: flex;
    gap: 8px;
    height: 2px;
}

.lf-chapter-progress.lf-chapter-pos-bottom {
    bottom: 32px;
}

.lf-chapter-progress.lf-chapter-pos-top {
    top: 16px;
}

.lf-chapter-seg {
    flex: 1 1 0;
    height: 100%;
    background: rgba(255, 255, 255, 0.2);
    overflow: hidden;
}

/* scaleX rather than width: a compositor-only property, the same technique
 * .lf-autoplay-progress uses, so a bar under a running transition costs no
 * layout. */
.lf-chapter-seg-fill {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--lf-cn-color, #fff);
    transform: scaleX(0);
    transform-origin: left center;
    transition-property: transform;
    transition-duration: 0ms;
    transition-timing-function: var(--lf-wipe-edge-ease, cubic-bezier(.65, 0, .35, 1));
}

.lf-chapter-seg-fill.is-full {
    transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
    .lf-chapter-seg-fill {
        transition-duration: 0ms !important;
    }
}

/* Bullets / Pagination */
.lf-bullets {
    position: absolute;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--lf-bullet-spacing, 8px);
    pointer-events: auto;
}

.lf-bullets-pos-bottom {
    bottom: 16px;
    left: 0;
    right: 0;
    flex-direction: row;
}

.lf-bullets-pos-top {
    top: 16px;
    left: 0;
    right: 0;
    flex-direction: row;
}

.lf-bullets-pos-left {
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
}

.lf-bullets-pos-right {
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
}

.lf-bullets .swiper-pagination-bullet {
    background: var(--lf-bullet-color, rgba(255, 255, 255, 0.5));
    opacity: 1;
    cursor: pointer;
    transition: all 0.25s ease;
    margin: 0 !important;
}

.lf-bullets .swiper-pagination-bullet-active {
    background: var(--lf-bullet-active-color, #ffffff);
}

.lf-bullet-style-dot .swiper-pagination-bullet {
    width: var(--lf-bullet-size, 10px);
    height: var(--lf-bullet-size, 10px);
    border-radius: 50%;
}

.lf-bullet-style-square .swiper-pagination-bullet {
    width: var(--lf-bullet-size, 10px);
    height: var(--lf-bullet-size, 10px);
    border-radius: 0;
}

.lf-bullet-style-bar .swiper-pagination-bullet {
    width: calc(var(--lf-bullet-size, 10px) * 2.5);
    height: calc(var(--lf-bullet-size, 10px) * 0.5);
    border-radius: 2px;
}

.lf-bullet-style-line .swiper-pagination-bullet {
    width: calc(var(--lf-bullet-size, 10px) * 3);
    height: 2px;
    border-radius: 0;
}

/* Corner positions. Three classes deep on purpose: Swiper's own
   .swiper-pagination-bullets.swiper-pagination-horizontal sets bottom, left:0
   and width:100% at two, and would stretch a corner index across the slider. */
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-bottom-left,
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-bottom-right,
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-top-left,
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-top-right {
    width: auto;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    transform: none;
    flex-direction: row;
}
/* The side positions had the same fight and lost it: Swiper's horizontal
   rule pinned them to the bottom, full width, so a 'right' column of bullets
   sat at the bottom centre. */
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-left,
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-right {
    width: auto;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    flex-direction: column;
}
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-left  { left: 16px; right: auto; }
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-right { right: 16px; left: auto; }
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-bottom-left  { left: var(--lf-bullet-x, 24px); bottom: var(--lf-bullet-y, 24px); }
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-bottom-right { right: var(--lf-bullet-x, 24px); bottom: var(--lf-bullet-y, 24px); }
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-top-left     { left: var(--lf-bullet-x, 24px); top: var(--lf-bullet-y, 24px); }
.lf-slider-wrapper .lf-bullets.lf-bullets-pos-top-right    { right: var(--lf-bullet-x, 24px); top: var(--lf-bullet-y, 24px); }

/* Bars: one thin vertical bar per slide, bottom-aligned; the active one rises
   and brightens, and the change animates because Swiper only moves the
   active class -- so the old bar falls while the new one grows, whichever
   way the deck went. A 2px bar is no target for a finger, so each one
   carries an invisible hit area around it. */
.lf-bullet-style-bars {
    align-items: flex-end;
}
.lf-bullet-style-bars.lf-bullets-pos-left,
.lf-bullet-style-bars.lf-bullets-pos-right {
    align-items: center;
}
.lf-bullets.lf-bullet-style-bars .swiper-pagination-bullet {
    position: relative;
    width: var(--lf-bar-w, 2px);
    height: var(--lf-bar-h, 22px);
    border-radius: 0;
    transition: height 0.45s cubic-bezier(.65, 0, .35, 1), background-color 0.45s cubic-bezier(.65, 0, .35, 1);
}
.lf-bullets.lf-bullet-style-bars .swiper-pagination-bullet::before {
    content: "";
    position: absolute;
    left: calc(var(--lf-bullet-spacing, 8px) / -2);
    right: calc(var(--lf-bullet-spacing, 8px) / -2);
    top: -8px;
    bottom: -8px;
}
.lf-bullets.lf-bullet-style-bars .swiper-pagination-bullet-active {
    height: var(--lf-bar-active-h, 36px);
}
@media (prefers-reduced-motion: reduce) {
    .lf-bullets.lf-bullet-style-bars .swiper-pagination-bullet { transition: none; }
}

/* Thumbnail Navigation */
.lf-thumbnails-nav {
    position: absolute;
    z-index: 10;
    display: flex;
    overflow-x: auto;
    pointer-events: auto;
    padding: 8px;
    box-sizing: border-box;
}

.lf-thumbnails-track {
    display: flex;
    gap: var(--lf-thumb-gap, 8px);
}

.lf-thumbs-pos-bottom {
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
    max-width: 90%;
}

.lf-thumbs-pos-top {
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    max-width: 90%;
}

.lf-thumbs-pos-left {
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
}

.lf-thumbs-pos-left .lf-thumbnails-track,
.lf-thumbs-pos-right .lf-thumbnails-track {
    flex-direction: column;
}

.lf-thumbs-pos-right {
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
}

.lf-thumb-item {
    width: var(--lf-thumb-w, 100px);
    height: var(--lf-thumb-h, 60px);
    background-size: cover;
    background-position: center;
    border: 2px solid transparent;
    border-radius: 4px;
    opacity: var(--lf-thumb-opacity, 0.6);
    cursor: pointer;
    transition: opacity 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
    padding: 0;
    flex-shrink: 0;
}

.lf-thumb-item:hover {
    opacity: 0.9;
    transform: scale(1.04);
}

.lf-thumb-item.lf-thumb-active {
    opacity: 1;
    border-color: var(--lf-thumb-active-border, #0073aa);
}

/* Autoplay Progress Bar */
.lf-autoplay-bar {
    position: absolute;
    left: 0;
    right: 0;
    width: 100%;
    z-index: 12;
    overflow: hidden;
    pointer-events: none;
}

.lf-bar-pos-top {
    top: 0;
}

.lf-bar-pos-bottom {
    bottom: 0;
}

/* Driven by requestAnimationFrame for the whole time a slider autoplays, so the
   fill is a transform rather than a width: scaleX runs on the compositor, where
   a width write forced layout + paint on every frame. The element is a flat
   background-color with no radius or gradient, so scaling distorts nothing.
   No transition — the value is already written every frame, and the reset on
   slide change has to snap rather than ease back. */
.lf-autoplay-progress {
    height: 100%;
    width: 100%;
    transform: scaleX(0);
    transform-origin: left center;
    will-change: transform;
}

/* Fullscreen Toggle Button */
.lf-fullscreen-btn {
    position: absolute;
    z-index: 12;
    width: var(--lf-fs-size, 36px);
    height: var(--lf-fs-size, 36px);
    color: var(--lf-fs-color, #ffffff);
    background: var(--lf-fs-bg, rgba(0, 0, 0, 0.4));
    border: none;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: background-color 0.2s ease, transform 0.2s ease;
}

.lf-fullscreen-btn:hover {
    transform: scale(1.08);
}

.lf-fs-pos-top-right {
    top: 12px;
    right: 12px;
}

.lf-fs-pos-top-left {
    top: 12px;
    left: 12px;
}

.lf-fs-pos-bottom-right {
    bottom: 12px;
    right: 12px;
}

.lf-fs-pos-bottom-left {
    bottom: 12px;
    left: 12px;
}

/* Custom HTML Widget */
.lf-custom-html-widget {
    position: absolute;
    z-index: 10;
    pointer-events: auto;
}

.lf-html-pos-top-left {
    top: 16px;
    left: 16px;
}

.lf-html-pos-top-right {
    top: 16px;
    right: 16px;
}

.lf-html-pos-bottom-left {
    bottom: 16px;
    left: 16px;
}

.lf-html-pos-bottom-right {
    bottom: 16px;
    right: 16px;
}

/* ---------------------------------------------------------------------------
   Fullscreen layout mode
   The slider height tracks the browser viewport instead of the design canvas
   ratio. Three heights are declared in ascending order of preference:
     1. --lf-vh  : a JS-maintained fallback (px per 1vh) for browsers with no
                   dvh support and for orientation changes that leave vh stale.
     2. 100dvh   : the dynamic viewport, which follows mobile browser chrome.
   --lf-fs-offset subtracts a fixed area (a sticky header, for example).
   --------------------------------------------------------------------------- */
.lf-slider-wrapper.lf-layout-fullscreen {
    aspect-ratio: auto;
    height: calc((var(--lf-vh, 1vh) * 100) - var(--lf-fs-offset, 0px));
    height: calc(100dvh - var(--lf-fs-offset, 0px));
    min-height: 320px;
}

/* Fit to height: never shorter than the tier's grid height at the current
   scale, set by frontend.js from data-fit-heights. On a screen too short to
   fit, the slider runs past the window, as Slider Revolution's module does,
   rather than cropping its layers or squeezing them past the scale floor. */
.lf-slider-wrapper.lf-layout-fullscreen[data-fit-heights] {
    min-height: max(320px, var(--lf-fit-min-h, 0px));
}

/* Flow content must not force the fullscreen box taller than the viewport. */
.lf-slider-wrapper.lf-layout-fullscreen.lf-has-flow {
    min-height: 320px;
}

.lf-slider-wrapper.lf-layout-fullscreen.lf-has-flow .lf-main-swiper,
.lf-slider-wrapper.lf-layout-fullscreen.lf-has-flow .swiper-slide,
.lf-slider-wrapper.lf-layout-fullscreen.lf-has-flow .lf-slide-bg {
    height: 100%;
    min-height: 100%;
}

.lf-slider-wrapper.lf-layout-fullscreen.lf-has-flow .lf-layers-container {
    aspect-ratio: auto;
    bottom: 0;
}

/* Native browser fullscreen (the fullscreen widget) always fills the screen. */
.lf-slider-wrapper:fullscreen {
    aspect-ratio: auto;
    height: 100%;
    min-height: 100%;
}

/* ---------------------------------------------------------------------------
   Proportional layer scaling
   Layer geometry and typography are emitted as design pixels multiplied by
   --lf-scale. The runtime recomputes the factor from the slider width on every
   resize; the 1 fallback keeps the design readable before scripts run.
   --------------------------------------------------------------------------- */
.lf-slider-wrapper.lf-scale-proportional {
    --lf-scale: 1;
}

/* Autoplay pause toggle (WCAG 2.2.2).
   Styled off the arrow variables so it matches whatever the arrows were
   given, with its own fallbacks for a slider that has arrows switched
   off. Bottom-left, out of the way of bullets (bottom-centre) and
   thumbnails. */
.lf-autoplay-toggle {
	position: absolute;
	left: 16px;
	bottom: 16px;
	z-index: 12;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	color: var(--lf-arrow-color, #fff);
	background: var(--lf-arrow-bg, rgba(0, 0, 0, 0.35));
	transition: background-color 0.2s ease, color 0.2s ease;
}
.lf-autoplay-toggle:hover,
.lf-autoplay-toggle:focus-visible {
	color: var(--lf-arrow-hover-color, #fff);
	background: var(--lf-arrow-hover-bg, rgba(0, 0, 0, 0.6));
}
.lf-autoplay-toggle:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}
/* One icon at a time: pressed means paused, so it offers Play. */
.lf-autoplay-toggle__play { display: none; }
.lf-autoplay-toggle[aria-pressed="true"] .lf-autoplay-toggle__pause { display: none; }
.lf-autoplay-toggle[aria-pressed="true"] .lf-autoplay-toggle__play { display: block; }


/* ---------------------------------------------------------------------------
   Scroll-driven animation: pinning
   ---------------------------------------------------------------------------
   A pinned slider sits in a track with a spacer N screen-heights tall after
   it, and sticks to the top of the screen while the page scrolls past the
   spacer; frontend.js maps how far through that the page has scrolled onto
   the slide's timeline.

   A spacer ELEMENT, not padding on the track: sticky travels inside its
   parent's content box, and padding is outside it. With padding the track
   was tall but its content box was only the slider, so the slider had
   nowhere to stick and scrolled away with the page.

   The admin bar's height is honoured so a logged-in visitor's bar does not
   cover the pinned slider. */
.lf-scroll-track {
    position: relative;
}

.lf-scroll-track > .lf-slider-wrapper {
    position: sticky;
    top: var(--wp-admin--admin-bar--height, 0px);
}

.lf-scroll-spacer {
    height: calc(var(--lf-pin-screens, 0) * 100vh);
    pointer-events: none;
}

/* Set by frontend.js when an ancestor makes sticky impossible: no empty
   scroll, and the slider plays as it passes through the screen. */
.lf-scroll-track.is-unpinned > .lf-slider-wrapper {
    position: relative;
    top: auto;
}

.lf-scroll-track.is-unpinned > .lf-scroll-spacer {
    display: none;
}

/* Reduced motion gets the finished layout and no empty scroll to cross. */
@media (prefers-reduced-motion: reduce) {
    .lf-scroll-track > .lf-slider-wrapper {
        position: relative;
        top: auto;
    }

    .lf-scroll-spacer {
        display: none;
    }
}

/* Preloader (Optimize > Preloader). The slider is rendered with
   .lf-preloading and held behind this overlay until frontend.js has its
   images, then .lf-preloaded fades the overlay out. Opacity rather than
   visibility hides the rest, because a descendant with visibility:visible
   would show straight through a hidden parent.

   The failsafe: if the script never runs -- a JS error elsewhere on the page,
   an optimiser that drops it -- the same selectors time out on their own and
   show the slider unstarted rather than a spinner forever. The script gives
   up waiting well before this (PRELOAD_TIMEOUT_MS), so on a working page it
   is never reached. */
@keyframes lf-preloader-failsafe-show { to { opacity: 1; } }
@keyframes lf-preloader-failsafe-hide { to { opacity: 0; visibility: hidden; } }
@keyframes lf-preloader-spin { to { transform: rotate(360deg); } }

.lf-slider-wrapper.lf-preloading > :not(.lf-preloader) {
    opacity: 0;
    animation: lf-preloader-failsafe-show 0s 20s forwards;
}
.lf-slider-wrapper.lf-preloading > .lf-preloader {
    animation: lf-preloader-failsafe-hide 0s 20s forwards;
}

.lf-preloader {
    position: absolute;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--lf-preloader-bg, #ffffff);
    color: var(--lf-preloader-color, #000000);
    transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
.lf-slider-wrapper.lf-preloaded > .lf-preloader {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

.lf-preloader__spinner {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 3px solid currentColor;
    border-right-color: transparent;
    opacity: 0.9;
    animation: lf-preloader-spin 0.8s linear infinite;
}

.lf-preloader__track {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(240px, 50%);
    height: 3px;
    transform: translate(-50%, -50%);
    border-radius: 3px;
    background: color-mix(in srgb, currentColor 25%, transparent);
    overflow: hidden;
}
.lf-preloader__fill {
    display: block;
    height: 100%;
    width: 0;
    background: currentColor;
    transition: width 0.25s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .lf-preloader__spinner { animation-duration: 2.4s; }
    .lf-preloader { transition: none; }
}
