/* ==========================================================================
   Basuto UX — Site Footer (footer-v2)
   Extracted from the inline <style> that used to live inside the shared
   "GLOBAL: Footer" template part (wp_template_part 426), where a content save
   stripped the <style>/<script> tags and left the code visible on the page.
   Owned by the plugin so it cannot be destroyed by a content save.

   Adapted for native core blocks: the grid/columns/logo wrappers are now
   core/group and core/image, so block-gap margins and figure defaults are
   neutralised here. Visual result is unchanged from the baseline.

   Site shell, not an optional enhancement: always loaded, independent of the
   Basuto UX feature toggles.
   ========================================================================== */

/* ── Shell ── */

.basuto-footer-v2 {
    background: #0E5C5C;
    color: #ffffff;
    font-family: 'DM Sans', sans-serif;
    padding: 64px 40px 0;
}

.basuto-footer-v2 * { box-sizing: border-box; }
.basuto-footer-v2 a { color: inherit; text-decoration: none; }
.basuto-footer-v2 a:hover { text-decoration: underline; }

.basuto-footer-v2-inner {
    max-width: 1500px;
    margin: 0 auto;
}

/* Block-gap neutralisation — core's flow layout adds margin-block-start to
   every sibling after the first (`:where(.is-layout-flow) > * + *`, zero
   specificity). Spacing below is explicit, so clear it on our containers. */
.basuto-footer-v2-inner > *,
.basuto-footer-v2-grid > *,
.basuto-footer-v2-col > *,
.basuto-footer-v2-bottom > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* ── Six-column grid ── */

.basuto-footer-v2-grid {
    display: grid;
    grid-template-columns: 1.5fr repeat(5, 1fr);
    gap: 32px;
    padding-bottom: 48px;
}

/* ── Brand column ── */

/* core/image renders a <figure class="wp-block-image">; it carries the
   footer-v2-logo class, so reset figure defaults and keep the 20px gap the
   baseline put on the <img>. */
.basuto-footer-v2-logo {
    margin: 0 0 20px;
}

/* Width + intrinsic ratio are owned here rather than by block resize
   attributes, so the rendered 150x44 survives a save that strips style
   attributes. 1024x301 is the source upload ratio: 150px wide => 44px tall. */
.basuto-footer-v2-logo img {
    width: 150px;
    height: auto;
    aspect-ratio: 1024 / 301;
    display: block;
}

.basuto-footer-v2-brand p {
    margin: 0 0 14px;
    font-size: 14px;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.85);
}

.basuto-footer-v2-brand p a {
    color: #ffffff;
}

.basuto-footer-v2-hours strong {
    display: block;
    margin-bottom: 4px;
    color: #ffffff;
}

/* The CQC badge was a bare <a>; it now sits in a paragraph that must not add
   spacing of its own — the badge keeps its own margin-top below. */
.basuto-footer-v2-cqc-line {
    margin: 0;
}

.basuto-footer-v2-cqc {
    display: inline-block;
    margin-top: 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #D4A574;
}

/* ── Link columns ── */

.basuto-footer-v2-col h4 {
    margin: 0 0 20px;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #D4A574;
}

.basuto-footer-v2-col ul,
.basuto-footer-v2-col .wp-block-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.basuto-footer-v2-col li {
    margin-bottom: 12px;
    font-size: 14px;
    line-height: 1.5;
}

.basuto-footer-v2-col li a {
    color: rgba(255, 255, 255, 0.85);
}

.basuto-footer-v2-col li a:hover {
    color: #ffffff;
}

/* ── Bottom bar ── */

.basuto-footer-v2-bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    padding: 22px 0;
    text-align: center;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.55);
}

/* The copyright line is a core/paragraph now, not a bare text node. */
.basuto-footer-v2-bottom p {
    margin: 0;
}

/* ── Responsive ── */

@media (max-width: 1100px) {
    .basuto-footer-v2-grid {
        grid-template-columns: repeat(3, 1fr);
    }
    .basuto-footer-v2-brand {
        grid-column: 1 / -1;
    }
}

@media (max-width: 640px) {
    .basuto-footer-v2 {
        padding: 40px 20px 0;
    }
    .basuto-footer-v2-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 20px 16px;
        padding-bottom: 24px;
    }
    .basuto-footer-v2-brand {
        grid-column: 1 / -1;
        padding-bottom: 4px;
    }
    .basuto-footer-v2-logo {
        margin-bottom: 12px;
    }
    .basuto-footer-v2-brand p {
        margin-bottom: 10px;
        font-size: 13px;
    }
    .basuto-footer-v2-brand p a.basuto-footer-contact-link {
        display: inline-block;
        line-height: 24px;
    }
    .basuto-footer-v2-col h4 {
        margin-bottom: 12px;
        font-size: 12px;
    }
    .basuto-footer-v2-col li {
        margin-bottom: 8px;
        font-size: 13px;
        line-height: 1.4;
    }
    .basuto-footer-v2-bottom {
        padding: 16px 0;
    }

    /* Mobile centring */
    .basuto-footer-v2-brand {
        text-align: center;
    }
    .basuto-footer-v2-logo {
        display: flex;
        justify-content: center;
    }
    .basuto-footer-v2-hours {
        text-align: center;
    }
    .basuto-footer-v2-cqc {
        margin-left: auto;
        margin-right: auto;
    }

    .basuto-footer-v2-about {
        grid-column: 1 / -1;
    }
    .basuto-footer-v2-about ul {
        column-count: 2;
        column-gap: 16px;
    }
    .basuto-footer-v2-about li {
        break-inside: avoid;
    }

    .basuto-footer-v2-col {
        text-align: center;
    }
}

@media (max-width: 340px) {
    .basuto-footer-v2-grid {
        grid-template-columns: 1fr;
    }
}

/* ==========================================================================
   Back-to-top button
   The element and its icon are created (or, on the legacy footer content,
   adopted and repaired) by site-shell.js, so nothing non-functional is
   rendered when JS is unavailable. The styling lives here.
   ========================================================================== */

#basuto-back-to-top {
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #0E5C5C;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity 0.2s ease, transform 0.2s ease, background 0.2s ease;
    z-index: 999;
}

/* visibility:hidden also keeps the button out of the tab order until shown. */
#basuto-back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

#basuto-back-to-top:hover {
    background: #D4A574;
}

#basuto-back-to-top:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

#basuto-back-to-top svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: #ffffff;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@media (max-width: 640px) {
    #basuto-back-to-top {
        right: 16px;
        bottom: 16px;
        width: 40px;
        height: 40px;
    }
}

@media (prefers-reduced-motion: reduce) {
    #basuto-back-to-top {
        transition: none;
        transform: none;
    }
    #basuto-back-to-top.is-visible {
        transform: none;
    }
}

/* ==========================================================================
   Mobile booking bar ↔ cookie consent clearance

   The site has a fixed bottom booking bar on phones: the theme's header
   template part ships `.mobile-cta-bar` (z-index 1000002, measured 66.4px
   tall at 320 and 390), and this plugin's own `.basuto-sticky-cta` is the
   fallback where the theme has none — components.css suppresses ours
   whenever the theme's is in the document.

   The consent plugin's info bar is also fixed to the bottom, at a much lower
   layer: stock 5.1.0 ships `#moove_gdpr_cookie_info_bar { bottom: 0;
   z-index: 9900 }` and `.gdpr_lightbox { z-index: 9990 }`. So the booking bar
   paints over the bottom ~66px of the banner. On staging that concealed the
   banner's Cookie Settings button outright (the click landed on the bar's
   CALL US link) and covered part of Accept/Reject; the consent dialog was
   covered the same way. A hit test that only asks "is the booking bar
   clickable" passes while that is happening, so it cannot be the gate.

   Two independent mechanisms, because each covers the other's failure mode:

     1. Clearance (primary). The banner is lifted by the bar's *measured*
        height, published by site-shell.js as `--basuto-bookingbar-h`. No
        hardcoded bar height: the bar's height comes from the theme's own
        content and safe-area padding, and a baked-in number would silently
        rot. The variable is the measured overlap of whatever bottom bar is
        actually visible, so it is 0px when no bar is drawn — above the
        768/960 breakpoints, with the feature toggled off, or before JS runs.
        At 0px every rule below collapses to the vendor value, which is why
        none of this needs a desktop media query to stay out of the way.

     2. Stacking (fallback, no-JS). Without JS the clearance is 0px and the
        two elements overlap again, so the banner is also lifted above the
        bar's layer. The overlap then resolves the other way: the banner
        covers part of the bar until a choice is made, which is what the live
        old-UX site does today, rather than a consent control being
        unreachable. Consent is a blocking one-time interaction and booking
        stays reachable from the page itself, so that is the right way round
        to fail. Both mechanisms together mean neither element is covered.

   `!important` is deliberate and minimal. The vendor rules it overrides carry
   no `!important`, so this wins on order-independent grounds — the consent
   assets' load order relative to this stylesheet is not something to depend
   on. The site's own consent CSS (stored in the plugin's strictly-necessary
   header scripts, and it may arrive only after a choice) declares the same
   z-indexes with `!important` at values far above these; whichever of the two
   lands last, the banner and dialog both end up above the booking bar, so
   there is no outcome where this fights itself into a worse state.

   Not touched: the consent copy, the consent choices, the cookie categories,
   the booking bar itself, the footer, any template and any content.
   ========================================================================== */

:root {
    /* Replaced with the measured height by site-shell.js. 0px keeps every
       rule below equal to the stock consent styling until then. */
    --basuto-bookingbar-h: 0px;
}

/* `.moove-gdpr-info-bar-hidden` is how the plugin hides the banner after a
   choice — it animates `bottom` to -400px. Excluding it here is load-bearing:
   an unscoped `bottom` override would pin the banner on screen forever.
   `.gdpr_infobar_postion_top` is the top-of-page layout, which needs no
   bottom clearance at all. */
#moove_gdpr_cookie_info_bar:not(.moove-gdpr-info-bar-hidden):not(.gdpr_infobar_postion_top) {
    bottom: var(--basuto-bookingbar-h, 0px) !important;
    /* Short screens: keep the vendor 400px cap, and additionally never exceed
       what is left above the bar, so a tall banner scrolls inside itself
       instead of spilling behind the bar. */
    max-height: min(400px, calc(100vh - var(--basuto-bookingbar-h, 0px) - 16px)) !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
}

/* dvh tracks the collapsing mobile browser chrome; vh above is the fallback
   for engines without it. */
@supports (height: 100dvh) {
    #moove_gdpr_cookie_info_bar:not(.moove-gdpr-info-bar-hidden):not(.gdpr_infobar_postion_top) {
        max-height: min(400px, calc(100dvh - var(--basuto-bookingbar-h, 0px) - 16px)) !important;
    }
}

/* Mechanism 2. Scoped to "no core navigation overlay open": core puts
   `has-modal-open` on <html> and raises the open mobile menu to z-index
   100000, which is already below the booking bar's 1000002. Lifting the
   banner unconditionally would therefore float it over an open mobile menu,
   which is a layering change nobody asked for. While the menu is open the
   banner keeps its stock layer and the overlay covers it, exactly as now.
   Clearance is deliberately *not* scoped this way: it stays applied so the
   banner does not slide up and down each time the menu opens. */
html:not(.has-modal-open) #moove_gdpr_cookie_info_bar {
    z-index: 1000003 !important;
}

/* The dialog is a true modal — it must be on top even from an open menu, so
   this one is unscoped. 1000004 keeps the vendor relationship (lightbox above
   info bar) intact. */
.gdpr_lightbox {
    z-index: 1000004 !important;
}

/* The floating "Change cookie settings" button sits at `bottom: 20px;
   z-index: 1001` in stock 5.1.0, i.e. inside the booking bar's band and under
   it — the reopen path has the same defect as the banner. Same measured
   clearance, same 20px offset the vendor uses, and inert where the button is
   configured off or hidden on mobile. */
#moove_gdpr_save_popup_settings_button:not(.gdpr-floating-button-custom-position) {
    bottom: calc(var(--basuto-bookingbar-h, 0px) + 20px) !important;
}

html:not(.has-modal-open) #moove_gdpr_save_popup_settings_button {
    z-index: 1000003 !important;
}
