.top-banner {
    width: 100%;
    background-color: #2e2e2e;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    top: 0;
    z-index: 999;
    padding: 5px 0;
}

    .top-banner .top-banner__content {
        max-width: 960px;
        margin: 0 auto;
        padding: 0 10px;
        display: grid;
        grid-template-columns: auto 1fr auto;
        grid-template-rows: 1fr;
        grid-column-gap: 50px;
        grid-row-gap: 0px;
        justify-content: center;
        align-items: center;
    }

    .top-banner .top-banner__image {
        grid-area: 1 / 1 / 2 / 2;
    }

    .top-banner .top-banner__image img {
        max-width: 92px;
        max-height: 92px;
    }

    .top-banner .top-banner__text {
        grid-area: 1 / 2 / 2 / 3;
        font-weight: bold;
        font-size: 16px;
        color: #ffffff;
    }

    .top-banner .top-banner__button {
        grid-area: 1 / 3 / 2 / 4;
    }

    .top-banner .top-banner__button .button {
        color: #fff;
    }

    /* Membership banners carry no image — collapse the empty first column. */
    .top-banner--no-image .top-banner__content {
        grid-template-columns: 1fr auto;
    }

    .top-banner--no-image .top-banner__text {
        grid-area: 1 / 1 / 2 / 2;
    }

    .top-banner--no-image .top-banner__button {
        grid-area: 1 / 2 / 2 / 3;
    }

    /* Compact mobile layout (#160): smaller image, tighter spacing,
       long copy clamped to two lines. */
    @media screen and (max-width: 782px) {
        .top-banner .top-banner__content {
            grid-template-columns: auto 1fr;
            grid-template-rows: repeat(2, auto);
            grid-column-gap: 12px;
            grid-row-gap: 2px;
            padding: 6px 10px;
        }

        .top-banner .top-banner__image {
            grid-area: 1 / 1 / 3 / 2;
        }

        .top-banner .top-banner__image img {
            max-width: 48px;
            max-height: 48px;
        }

        .top-banner .top-banner__text {
            grid-area: 1 / 2 / 2 / 3;
            justify-self: end;
            font-size: 13px;
            line-height: 1.3;
            text-align: right;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }

        .top-banner .top-banner__button {
            grid-area: 2 / 2 / 3 / 3;
            justify-self: end;
        }

        .top-banner .top-banner__button .button {
            padding: 4px 12px;
            font-size: 13px;
        }

        .top-banner--no-image .top-banner__content {
            grid-template-columns: 1fr;
        }

        .top-banner--no-image .top-banner__text {
            grid-area: 1 / 1 / 2 / 2;
        }

        .top-banner--no-image .top-banner__button {
            grid-area: 2 / 1 / 3 / 2;
        }
    }

/* Two-image rotation (#161): fixed-size box so a swap never changes the
   banner height (the offset engine measures banner heights). */
.top-banner .top-banner__image--rotating {
    position: relative;
    width: 92px;
    height: 92px;
}

.top-banner .top-banner__image--rotating .top-banner__image-slide {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    object-fit: contain;
    opacity: 0;
    transition: opacity 400ms ease;
}

.top-banner .top-banner__image--rotating .top-banner__image-slide--active {
    opacity: 1;
}

@media screen and (max-width: 782px) {
    .top-banner .top-banner__image--rotating {
        width: 48px;
        height: 48px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .top-banner .top-banner__image--rotating .top-banner__image-slide {
        transition: none;
    }
}

/* Several announcements share the bar (#639): text and CTA cross-fade as one,
   and the "1/2 ▸" control moves through them by hand. */
.top-banner .top-banner__text--cycling,
.top-banner .top-banner__button--cycling {
    display: grid;
}

/* Slides stack in a single grid cell, so the box keeps the size of the largest
   one: a swap never changes the banner height (the offset engine measures it)
   and never shifts the CTA sideways. Visibility keeps the inactive slides out
   of the tab order, and only steps back once the fade is over. */
.top-banner .top-banner__text-slide,
.top-banner .top-banner__button-slide {
    grid-area: 1 / 1;
    /* Without this a one-line slide would sit at the top of a cell sized for
       a two-line one, instead of on the bar's centre line. */
    align-self: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 400ms ease, visibility 0s linear 400ms;
}

.top-banner .top-banner__text-slide--active,
.top-banner .top-banner__button-slide--active {
    opacity: 1;
    visibility: visible;
    transition: opacity 400ms ease, visibility 0s;
}

/* Reads as a list index, muted against the banner fill — the CTA stays the
   only loud control in the bar. */
.top-banner .top-banner__cycle {
    grid-area: 1 / 1 / 2 / 2;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: normal;
    color: rgba(255, 255, 255, 0.7);
    text-decoration: none;
    white-space: nowrap;
}

.top-banner .top-banner__cycle:hover,
.top-banner .top-banner__cycle:focus {
    color: #ffffff;
    text-decoration: none;
}

.top-banner .top-banner__cycle::after {
    content: '';
    width: 6px;
    height: 6px;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
    transform: rotate(45deg);
    flex-shrink: 0;
}

/* Desktop: the CTA travels with its announcement instead of parking at the
   far edge — the pair reads as one message. Only the active slide takes part
   in layout, so the text box hugs the copy actually on screen and the button
   sits right after it; the others are lifted out of the flow. One line then
   keeps that box (and the banner) a constant height whatever an announcement's
   length, which the offset engine depends on. */
@media screen and (min-width: 783px) {
    .top-banner--cycling .top-banner__content {
        grid-template-columns: auto auto auto;
        /* Same gap the single-message bar uses, so adding a second webinar
           does not visibly re-space the bar. */
        grid-column-gap: 50px;
        /* Reserved on both sides so the centred pair never reaches the
           control pinned in the left inset. */
        padding: 0 56px;
    }

    .top-banner--cycling .top-banner__image {
        grid-area: 1 / 1 / 2 / 2;
    }

    /* The text track is the one allowed to give: without min-width the grid
       would honour the longest announcement's min-content and squeeze the CTA
       instead, wrapping its label and making the bar taller. */
    .top-banner--cycling .top-banner__text {
        grid-area: 1 / 2 / 2 / 3;
        min-width: 0;
        overflow: hidden;
    }

    .top-banner--cycling .top-banner__button {
        grid-area: 1 / 3 / 2 / 4;
    }

    /* Keeps the CTA's own track at the label's full width, so the ellipsis
       always lands in the announcement and never in the button. */
    .top-banner--cycling .top-banner__button-slide {
        white-space: nowrap;
    }

    /* Banners with slides carry no image (the webinar takeover drops promo
       content), so the empty first column and its gap go too. */
    .top-banner--no-image.top-banner--cycling .top-banner__content {
        grid-template-columns: auto auto;
    }

    .top-banner--no-image.top-banner--cycling .top-banner__text {
        grid-area: 1 / 1 / 2 / 2;
    }

    .top-banner--no-image.top-banner--cycling .top-banner__button {
        grid-area: 1 / 2 / 2 / 3;
    }

    /* The control is pinned to the bar's left inset rather than leading the
       row: inside the row it would sit against a short announcement again. */
    .top-banner--cycling .top-banner__cycle {
        position: absolute;
        left: 16px;
        top: 50%;
        transform: translateY(-50%);
    }

    .top-banner--cycling .top-banner__text--cycling {
        display: block;
        position: relative;
    }

    .top-banner--cycling .top-banner__text-slide {
        /* The slides are spans: without a block box text-overflow has nothing
           to work on and over-long copy would be cut mid-word with no ellipsis. */
        display: block;
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        max-width: 100%;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .top-banner--cycling .top-banner__text-slide--active {
        position: static;
        transform: none;
    }
}

/* Mobile has no room for another column: the control shares the CTA's row and
   takes the edge the CTA leaves free. */
@media screen and (max-width: 782px) {
    .top-banner--cycling .top-banner__content {
        grid-template-columns: auto 1fr;
        grid-column-gap: 12px;
    }

    .top-banner--cycling .top-banner__image {
        grid-area: 1 / 1 / 3 / 2;
    }

    .top-banner--cycling .top-banner__text {
        grid-area: 1 / 2 / 2 / 3;
    }

    .top-banner--cycling .top-banner__button,
    .top-banner--cycling .top-banner__cycle {
        grid-area: 2 / 2 / 3 / 3;
    }

    .top-banner--no-image.top-banner--cycling .top-banner__content {
        grid-template-columns: 1fr;
    }

    .top-banner--no-image.top-banner--cycling .top-banner__text {
        grid-area: 1 / 1 / 2 / 2;
    }

    .top-banner--no-image.top-banner--cycling .top-banner__button,
    .top-banner--no-image.top-banner--cycling .top-banner__cycle {
        grid-area: 2 / 1 / 3 / 2;
    }

    .top-banner--cycling .top-banner__cycle {
        justify-self: start;
    }

    /* The two-line clamp moves onto the slides — their container is a grid. */
    .top-banner .top-banner__text--cycling .top-banner__text-slide {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
}

@media (prefers-reduced-motion: reduce) {
    .top-banner .top-banner__text-slide,
    .top-banner .top-banner__button-slide {
        transition: none;
    }
}

/* Full-viewport base height; the offset engine slides the panel with a negative top. */
.bb-mobile-panel-wrapper {
    height: 100vh !important;
}
