/* ==========================================================================
   TGL STICKY UTILITIES
   Global, opt-in sticky positioning for sidebars and rails.

   Applied by hand from Elementor's "CSS Classes" field, so this file loads on
   every frontend page and assumes no particular markup.

   Three classes, on purpose:
     .tgl-sticky-sidebar          Sticks. Safe on anything.
     .tgl-sticky-sidebar--scroll  Also caps height and scrolls. Opt-in only:
                                  it clips popups. See section 1.
     .tgl-sticky-scope            Goes on the ANCESTOR container that has a
                                  non-visible overflow. See section 2.

   ── Why every selector below is doubled ──
   Elementor does not style containers directly. It routes each property
   through a custom property and declares, in `frontend.min.css`:

       .e-con { --position: relative; --overflow: visible; --z-index: revert;
                position: var(--position); overflow: var(--overflow);
                z-index: var(--z-index); }

   Those rules are a single class, so they tie with ours on specificity, and
   `frontend.min.css` is enqueued AFTER this file. A tie broken by load order
   means Elementor wins and the container computes to `position: relative`:
   the class applies, `top` and `align-self` land, and nothing sticks.

   So each rule does two things: it sets Elementor's custom property, which
   feeds Elementor's own declaration instead of fighting it, and it doubles
   the class to outrank `.e-con`. Verified against Elementor 4.2.3.
   ========================================================================== */

:root {
    /* Fixed header plus breathing room. Derived from the design-system token
       so a header height change cannot silently desync this offset. */
    --tgl-sticky-offset: calc(var(--tgl-header-height) + var(--tgl-space-6));
}


/* ==========================================================================
   1. The sticky element
   ========================================================================== */
.tgl-sticky-sidebar.tgl-sticky-sidebar {
    /* For Elementor containers, which read this instead of `position`. */
    --position: sticky;
    --z-index: var(--tgl-z-sticky);

    /* For everything else: shortcode output, plain divs, the booking widget. */
    position: sticky;
    z-index: var(--tgl-z-sticky);

    top: var(--tgl-sticky-offset);

    /* Required inside flex and grid parents. Without it the item stretches to
       the container's full height, leaving no travel to stick along. Elementor
       containers are flex by default, so this is not optional here. */
    align-self: start;
}

/* Opt-in height cap with its own scroll. Add ONLY when the element is taller
   than the viewport, because it turns the element into a clipping and
   scrolling container: anything rendered inside it (Litepicker calendars,
   guest dropdowns, tooltips) gets cut off or dragged into the inner scroll.
   Do not put this on the booking widget. */
.tgl-sticky-sidebar--scroll.tgl-sticky-sidebar--scroll {
    max-height: calc(100vh - var(--tgl-sticky-offset) - var(--tgl-space-6));
    overflow-y: auto;
    overscroll-behavior: contain;
}


/* ==========================================================================
   2. Ancestor scroll containers, which are what actually breaks sticky
   ========================================================================== */
/* ANY ancestor with a non-visible overflow silently disables sticky: that
   ancestor becomes the sticky containing block, and since it does not scroll,
   the element has nothing to stick to. No error, no warning. Elementor sets
   overflow:hidden on containers routinely, so put .tgl-sticky-scope on the
   offending ancestor.

   `!important` is deliberate here. When the overflow was set from Elementor's
   own Overflow control, the generated per-page CSS targets it as
   `.elementor-{page} .elementor-element.elementor-element-{id}`, which is
   three classes and outranks anything this file can write with class
   selectors alone. Adding this class is an explicit request to override that,
   so it overrides it. */
.tgl-sticky-scope.tgl-sticky-scope,
.tgl-sticky-scope > .e-con-inner,
.tgl-sticky-scope > .elementor-container,
.tgl-sticky-scope .elementor-widget-wrap {
    --overflow: visible !important;
    overflow: visible !important;
}

/* The ancestor this plugin broke itself: tgl-design-system.css declares
   `html, body { overflow-x: hidden }`.

   On <html> that is harmless. The root element's overflow propagates to the
   viewport and the used value on <html> itself stays visible, so it never
   becomes a sticky containing block.

   On <body> it is fatal. Body turns into a scroll container whose own
   scrollport never scrolls (its height is auto, it grows with its content),
   so every sticky descendant on the page dies. `clip` contains horizontal
   overflow the same way WITHOUT creating a scroll container, and it is the
   one non-visible value that pairs with `overflow-y: visible` instead of
   forcing it to `auto`.

   Scoped with :has() so only pages that actually use the utility are
   touched. Browsers without :has() or without `clip` keep today's behavior. */
body:has(.tgl-sticky-sidebar) {
    overflow-x: clip;
}


/* ==========================================================================
   3. Tablet and mobile, where there is nothing to stick to
   ========================================================================== */
/* Below the Elementor tablet breakpoint the sidebar stacks under the content,
   so there is no parallel scroll to follow and sticky is turned off.
   `--position` goes back to Elementor's own default rather than to `static`,
   so absolutely positioned children keep their containing block.

   Note the gap: the booking widget hides itself at <=768px and shows from
   769px up, so between 769px and 1024px it renders non-sticky. That band is
   too short for a sticky rail to earn its keep. */
@media (max-width: 1024px) {
    .tgl-sticky-sidebar.tgl-sticky-sidebar {
        --position: relative;
        position: static;
    }

    .tgl-sticky-sidebar--scroll.tgl-sticky-sidebar--scroll {
        max-height: none;
        overflow-y: visible;
    }
}
