/*
 * Site announcement banner.
 *
 * Design source: "Pricing Launch Offer" canvas, treatment B (Launch banner) -
 * a full-width strip above the site header carrying a pill, a message and the
 * offer end date.
 *
 * WHY THE HEIGHT IS A FIXED TOKEN RATHER THAN INTRINSIC
 *
 * .qb-site-header is `position: fixed; top: 0` and body carries a matching
 * `padding-top`, so the banner cannot simply sit above it in flow - it has to be
 * fixed too, and everything below has to be offset by exactly its height. A
 * JS-measured height would mean the header and page content jump once the
 * measurement lands, on every navigation. Declaring the height per breakpoint
 * keeps the offset knowable to CSS alone, so the first painted frame is already
 * in the right place. The cost is that the message has to fit the band, which
 * is why it is capped at MAX_MESSAGE_LENGTH and clipped rather than allowed to
 * push the header down.
 *
 * The offsets below apply ONLY under html.qb-has-banner, which the server sets
 * when a banner resolved for this request and an inline head script removes
 * before first paint when the viewer has already dismissed it. Nothing here
 * changes layout when there is no banner.
 */

:root {
    --qb-banner-h: 44px;
    /*
     * The band is fixed over scrolling content, so it needs an opaque floor of
     * its own - the accent below is a low-alpha tint and would otherwise let
     * headings scroll through the message. Matches the base .qb-site-header
     * sits on, so the two strips read as one surface. Every variant layers its
     * tint over this, so none of them can go translucent.
     */
    --qb-banner-base: #070708;
    /* Treatment B accent. Overridden per variant below. */
    --qb-banner-bg: linear-gradient(90deg, rgba(45, 181, 255, .16), rgba(18, 136, 255, .1));
    --qb-banner-border: rgba(87, 199, 255, .28);
    --qb-banner-pill-bg: #57c7ff;
    --qb-banner-pill-fg: #070708;
    --qb-banner-fg: #f4f6fb;
    --qb-banner-meta: #9aa2b1;
}

.qb-site-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1001; /* Above .qb-site-header (1000). */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    /* Single line: wrapping inside a fixed-height overflow:hidden band clips the
     * CTA/pill. The message ellipsizes instead (see __message). */
    flex-wrap: nowrap;
    height: var(--qb-banner-h);
    /* Vertical space comes from the fixed height + align-items, not padding.
     * Body line-height is 1.5; combined with the old 11px vertical padding that
     * left a ~21px content box, so the flex line overflowed and packed toward
     * the bottom of the band. 1px top padding offsets the 1px bottom border so
     * the flex line's midpoint matches the border-box midpoint. */
    padding: 1px 24px 0;
    line-height: 1;
    /* Solid floor + accent tint on top; variants only swap the tint. */
    background-color: var(--qb-banner-base);
    background-image: var(--qb-banner-bg);
    border-bottom: 1px solid var(--qb-banner-border);
    box-sizing: border-box;
    overflow: hidden;
}

.qb-site-banner__pill {
    display: inline-flex;
    align-items: center;
    font-family: 'JetBrains Mono', monospace;
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--qb-banner-pill-fg);
    background: var(--qb-banner-pill-bg);
    border-radius: 999px;
    padding: .25rem .55rem;
    white-space: nowrap;
    flex-shrink: 0;
}

.qb-site-banner__message {
    font-size: .88rem;
    color: var(--qb-banner-fg);
    /* Clip rather than grow: the band height is fixed (see file header). */
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qb-site-banner__cta {
    display: inline-flex;
    align-items: center;
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: .8rem;
    color: var(--qb-banner-pill-fg);
    background: var(--qb-banner-pill-bg);
    border-radius: 6px;
    padding: .35rem .8rem;
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    transition: filter .15s ease;
}

.qb-site-banner__cta:hover,
.qb-site-banner__cta:focus-visible {
    filter: brightness(1.12);
    color: var(--qb-banner-pill-fg);
    text-decoration: none;
}

.qb-site-banner__meta {
    font-family: 'JetBrains Mono', monospace;
    font-size: .72rem;
    color: var(--qb-banner-meta);
    white-space: nowrap;
    flex-shrink: 0;
}

.qb-site-banner__dismiss {
    position: absolute;
    right: 10px;
    top: 1px; /* Match the 1px top padding that offsets the bottom border. */
    bottom: 0;
    margin-block: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--qb-banner-meta);
    cursor: pointer;
    line-height: 1;
    transition: color .15s ease, background .15s ease;
}

.qb-site-banner__dismiss:hover,
.qb-site-banner__dismiss:focus-visible {
    color: var(--qb-banner-fg);
    background: rgba(255, 255, 255, .08);
}

/* Variants ------------------------------------------------------------ */

.qb-banner--info {
    --qb-banner-bg: linear-gradient(90deg, rgba(154, 162, 177, .14), rgba(154, 162, 177, .08));
    --qb-banner-border: rgba(255, 255, 255, .16);
    --qb-banner-pill-bg: #c9cdd6;
    --qb-banner-pill-fg: #070708;
}

.qb-banner--warning {
    --qb-banner-bg: linear-gradient(90deg, rgba(243, 201, 107, .18), rgba(243, 201, 107, .08));
    --qb-banner-border: rgba(243, 201, 107, .32);
    --qb-banner-pill-bg: #f3c96b;
    --qb-banner-pill-fg: #070708;
}

.qb-banner--incident {
    --qb-banner-bg: linear-gradient(90deg, rgba(255, 127, 157, .2), rgba(255, 127, 157, .1));
    --qb-banner-border: rgba(255, 127, 157, .36);
    --qb-banner-pill-bg: #ff7f9d;
    --qb-banner-pill-fg: #070708;
}

/* Offsets -------------------------------------------------------------- */

html.qb-has-banner body {
    padding-top: calc(60px + var(--qb-banner-h)) !important;
}

html.qb-has-banner .qb-site-header {
    top: var(--qb-banner-h) !important;
}

/*
 * The query-history layout takes the header out of the fixed flow and puts it
 * in a right column, so body padding is zeroed there and the offset has to be
 * applied to the sidebar and the column instead.
 */
html.qb-has-banner body.with-query-history {
    padding-top: var(--qb-banner-h) !important;
}

html.qb-has-banner .query-history-sidebar {
    top: var(--qb-banner-h);
    height: calc(100vh - var(--qb-banner-h));
    max-height: calc(100vh - var(--qb-banner-h));
}

html.qb-has-banner body.with-query-history .right-column-with-history .qb-site-header {
    top: auto !important;
}

/* Dismissed before paint: no banner, no offsets. */
html:not(.qb-has-banner) .qb-site-banner {
    display: none;
}

@media (max-width: 991.98px) {
    :root { --qb-banner-h: 40px; }

    .qb-site-banner {
        gap: 10px;
        padding: 1px 40px 0 16px;
    }

    /* First thing to go: the end date is a nicety, the offer itself is not. */
    .qb-site-banner__meta {
        display: none;
    }
}

@media (max-width: 575.98px) {
    :root { --qb-banner-h: 38px; }

    .qb-site-banner__message {
        font-size: .78rem;
    }

    .qb-site-banner__pill {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .qb-site-banner__cta,
    .qb-site-banner__dismiss {
        transition: none;
    }
}
