/*
 * The site header: masthead wordmark, section navigation, breaking-news ticker.
 *
 * All three bands are full-bleed and stack in that order, matching the layout
 * sketch. Only the navigation is sticky - the masthead is allowed to scroll
 * away so the reader gets the full window back once they start reading.
 *
 * Colours, fonts and the container width all come from css/gazapost.css.
 */

.site-header {
    background-color: var(--gp-card);
}

/* ---- Masthead --------------------------------------------------------- */

/* The wordmark itself is a shared primitive, styled in css/gazapost.css - the
   standalone 500 page shows it without loading this stylesheet. */
.masthead {
    padding: 1.5rem 0 1.25rem;
}

/* ---- Section navigation ----------------------------------------------- */

.site-nav {
    position: sticky;
    top: 0;
    z-index: 999;
    background-color: var(--gp-nav);
}

.site-nav .site-container {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    min-height: 3.25rem;
}

/*
 * `display: contents` on the two wrappers removes them from the box tree, so on
 * desktop the tag list and the search form are direct flex children of the
 * container and lay out as if the wrappers were not there. Below the mobile
 * breakpoint the outer one becomes the collapsible panel instead.
 */
.site-nav-collapse,
.site-nav-collapse-inner {
    display: contents;
}

.site-nav-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.75rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-nav-tag {
    position: relative;
    padding: 1rem 0;
}

.site-nav-tag a {
    font-size: 0.82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #ffffff;
    text-decoration: none;
    white-space: nowrap;
}

/*
 * The underline is a scaled-down pseudo-element rather than a border so it can
 * grow out from the left edge on hover without shifting the text above it.
 */
.site-nav-tag a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0.7rem;
    height: 2px;
    background-color: #ffffff;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.25s ease;
}

.site-nav-tag a:hover::after,
.site-nav-tag.is-active a::after {
    transform: scaleX(1);
}

/* ---- Search ----------------------------------------------------------- */

.site-search {
    /* Pushes the box to the far right; the tags stay packed against the left. */
    margin-left: auto;
    display: flex;
    align-items: center;
    height: 2.125rem;
    padding: 0 0.25rem 0 0.875rem;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 999px;
    box-sizing: border-box;
    transition: border-color 0.2s ease;
}

.site-search:focus-within {
    border-color: #ffffff;
}

.site-search-input {
    width: 11rem;
    height: 100%;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
    font-size: 0.85rem;
    color: #ffffff;
}

.site-search-input::placeholder {
    color: rgba(255, 255, 255, 0.65);
}

/*
 * `<input type="search">` is not a plain text box: WebKit/Blink (Safari, Chrome,
 * Edge) inject two extra UI parts into the field's shadow DOM that we cannot
 * reach any other way. Both are non-standard vendor pseudo-elements - Firefox
 * implements neither, so these two rules are simply inert there.
 *
 *   ::-webkit-search-cancel-button  the small grey "x" that appears at the right
 *                                   of the field once it has text. We drop it
 *                                   because it would sit between our text and
 *                                   the lens button, giving the pill two
 *                                   competing icons.
 *   ::-webkit-search-decoration     a legacy Safari spacer reserved at the left
 *                                   edge of the field. It renders as a few stray
 *                                   pixels that break our left padding.
 *
 * `-webkit-appearance: none` is what actually strips a native control's built-in
 * rendering; the unprefixed `appearance` has no effect on a -webkit- pseudo-
 * element, so the prefixed property is the one doing the work here.
 */
.site-search-input::-webkit-search-cancel-button,
.site-search-input::-webkit-search-decoration {
    -webkit-appearance: none;
}

.site-search-button {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0 0.375rem;
    border: none;
    background: transparent;
    color: #ffffff;
    cursor: pointer;
}

.site-search-button .material-icons {
    font-size: 20px;
}

.site-nav-burger {
    display: none;
}

/* ---- Breaking-news ticker --------------------------------------------- */

.ticker {
    background-color: var(--gp-breaking);
    color: #ffffff;
    overflow: hidden;
}

.ticker .site-container {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    height: 2.5rem;
}

.ticker-label {
    flex: none;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    white-space: nowrap;
}

/*
 * The viewport clips the moving track. `min-width: 0` is what allows a flex item
 * to be narrower than its own content - without it the track would force the bar
 * wider than the page instead of being cropped by it.
 */
.ticker-viewport {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

/*
 * The marquee holds two identical copies of the headline list side by side, so
 * sliding it left by exactly half its width lands on a frame identical to the
 * one it started from - the loop closes with no visible jump.
 */
.ticker-marquee {
    display: flex;
    width: max-content;
    animation: ticker-scroll 45s linear infinite;
}

/* Let readers stop the text to finish reading it, or to click through. */
.ticker:hover .ticker-marquee,
.ticker:focus-within .ticker-marquee {
    animation-play-state: paused;
}

.ticker-track {
    display: flex;
    align-items: center;
    gap: 2.5rem;
    /* Keeps the last headline of one copy clear of the first of the next. */
    margin: 0 2.5rem 0 0;
    padding: 0;
    list-style: none;
}

.ticker-item a {
    font-size: 0.85rem;
    color: #ffffff;
    text-decoration: none;
    white-space: nowrap;
}

.ticker-item a:hover {
    text-decoration: underline;
}

@keyframes ticker-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/*
 * Motion a reader cannot stop is a barrier for anyone prone to motion sickness,
 * so when the system asks for reduced motion the headlines become an ordinary
 * scrollable row: the animation stops, and the duplicate copy - which exists
 * only to make the loop seamless - is taken out of the layout.
 */
@media (prefers-reduced-motion: reduce) {
    .ticker-marquee {
        animation: none;
        width: 100%;
    }

    .ticker-viewport {
        overflow-x: auto;
    }

    .ticker-track[aria-hidden='true'] {
        display: none;
    }
}

/* ---- Mobile: burger menu ---------------------------------------------- */

/*
 * Below this width the tags and the search box no longer fit on one row, so
 * they move into a panel that unfurls from the bottom edge of the nav bar.
 */
@media (max-width: 768px) {
    .site-nav-burger {
        display: flex;
        align-items: center;
        justify-content: center;
        /* Pushes the button to the far right, as the search box does on desktop. */
        margin-left: auto;
        padding: 0;
        border: none;
        background: transparent;
        color: #ffffff;
        cursor: pointer;
    }

    /*
     * The panel hangs off the bottom of the nav rather than sitting in the flow,
     * so opening it overlays the page instead of shoving it down. It is a
     * descendant of the sticky nav, so it shares that stacking context and stays
     * above the article content.
     */
    .site-nav-collapse {
        display: grid;
        grid-template-rows: 0fr;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background-color: var(--gp-nav);
        overflow: hidden;
        opacity: 0;
        transition: grid-template-rows 0.25s ease, opacity 0.25s ease;
    }

    .site-nav-collapse.is-open {
        grid-template-rows: 1fr;
        opacity: 1;
    }

    .site-nav-collapse-inner {
        display: flex;
        flex-direction: column;
        gap: 1.25rem;
        /* A grid item's automatic minimum size is its content height; without
           this the 0fr track could not collapse and nothing would animate. */
        min-height: 0;
        overflow: hidden;
        padding: 1.25rem var(--gp-gutter);
        box-sizing: border-box;
    }

    /* Search first, tags below - the DOM order is kept as-is for desktop. */
    .site-search {
        order: -1;
        margin-left: 0;
        width: 100%;
    }

    .site-search-input {
        width: 100%;
    }

    .site-nav-tags {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }

    .site-nav-tag {
        padding: 0.375rem 0;
    }

    .site-nav-tag a::after {
        bottom: 0.125rem;
    }

    .masthead {
        padding: 1rem 0 0.875rem;
    }
}
