/*
 * The offer bar, and the fixed stack it forms with the site header.
 *
 * Loaded by layouts/master_home.blade.php on every page that can render the bar — not just
 * the landing page. It lived in landing.css until 2026-09-07, which was wrong in a way
 * nothing pointed at: the bar renders on the policy pages too (the view composer feeds the
 * shared chrome), but landing.css is only loaded on the home page, so on /terms, /privacy
 * and /refund-policy the bar arrived with no styling at all — unstyled black-on-white text
 * in the flow, sitting behind the fixed header.
 *
 * Colours are --jt-* tokens from theme.css, which is loaded ahead of this file everywhere.
 */

/* ---------- Promotional bar ---------- */

/*
 * Sits above the 90px header. Both are inside .site-top, which is the single fixed
 * element (see below) — so the bar itself only needs to look like a bar.
 *
 * A static bar, or margin on the header, was rejected when this was written: either one
 * scrolls away from the header it is attached to and leaves a gap over the hero.
 */
.promo-bar {
    background: var(--jt-accent);
    color: #fff;
    font-family: var(--jt-font-body);
    font-size: 14px;
    line-height: 1.3;
}

.promo-bar-inner {
    min-height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 8px 15px;
    text-align: center;
    flex-wrap: wrap;
}

.promo-bar-text {
    font-weight: 600;
    letter-spacing: 0.02em;
}

.promo-bar-link {
    color: #fff;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}

.promo-bar-link:hover {
    color: var(--jt-accent-soft);
}

/*
 * The bar and the header travel together as one fixed stack.
 *
 * This replaces `body:has(.promo-bar) #header { top: 40px }`, which hard-coded the bar's
 * height to match .promo-bar-inner's min-height. That number is only right while the offer
 * fits on one line: the live wording wraps to three lines below about 500px, making the bar
 * 85px tall while the header stayed at 40px, so the bar sat across the wordmark by 45px on
 * every phone. The height of a wrapped line of operator-configured text is not knowable in
 * CSS, so the offset is not computed any more — the header simply follows the bar in flow
 * inside a wrapper that is fixed for both, and any bar height works.
 *
 * :has() rather than a body class, so this is driven by the bar actually being in the
 * document. The bar takes itself down the day the offer expires
 * (App\Services\ExternalBooking::promoText()) and the header must go back to being fixed
 * on its own, with nothing else edited. Which is also why .site-top is left alone when
 * there is no bar: the wrapper is then an empty box around a header that is still
 * `position: fixed` from style.css, exactly as it was before the wrapper existed.
 */
body:has(.promo-bar) .site-top {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Above the header's own 997, and the 998 the bar used to carry itself. */
    z-index: 998;
}

body:has(.promo-bar) .site-top #header {
    position: static;
}

/*
 * How far page content has to start below the stack.
 *
 * The overlap fix above needs no height, but this does, and the height of a wrapped line
 * of operator-configured text is not something CSS can read. main.js publishes the bar's
 * measured height as --promo-h and keeps it current on resize; the 40px fallback here is
 * the one-line case, which is what desktop always renders and what the page shows for the
 * frame before main.js runs.
 *
 * 110px is .main-page's own padding-top from style.css, which clears the 70px inner
 * header. Written as an addition to it so the two cannot drift apart.
 */
:root {
    --promo-h: 40px;
}

body:has(.promo-bar) .main-page {
    padding-top: calc(110px + var(--promo-h));
}
