/* ============================================================================
   ANNOUNCEMENT BAR - the site-wide gold strip under the header.
   ----------------------------------------------------------------------------
   Rendered by fragments/header immediately after </header>, so it sits in normal
   flow directly below the (sticky) header and scrolls away with the page. That
   is deliberate: the header is already sticky and already takes vertical space,
   and stacking a second permanent strip under it would eat a meaningful slice of
   a phone screen on every page for a week at a time.

   Linked from fragments/header.html alongside header.css rather than from each
   page, because the bar is part of the header, not part of any page.
   ========================================================================== */

/* ── Theme knobs ──────────────────────────────────────────────────────────────
   Everything the bar paints with is one of these five values, so recolouring it
   is a five-line edit here (or a one-line override anywhere later in the
   cascade) rather than a hunt through the rules below.

   They default to the site's gold tokens from base/root.css - --hue-gold and
   friends - so the bar tracks the palette instead of pinning its own hex codes.
   Change --announcement-bar-hue alone and the fill, border, glow and hover state
   all follow it, because the rest are color-mix()es OF that hue rather than
   independent colours that happen to look related today.

   Declared on :root, not on .announcement-bar, so a page can override them
   without having to out-specify the component. */
:root {
    /* The one colour everything else is derived from. */
    --announcement-bar-hue: var(--hue-gold);
    /* Gold is a light hue: dark text on it beats white for contrast. */
    --announcement-bar-text: #241a00;
    --announcement-bar-fill: linear-gradient(90deg,
        color-mix(in srgb, var(--announcement-bar-hue) 92%, white) 0%,
        var(--announcement-bar-hue) 45%,
        color-mix(in srgb, var(--announcement-bar-hue) 80%, #ff9f1a) 100%);
    --announcement-bar-border: color-mix(in srgb, var(--announcement-bar-hue) 60%, #7a5200);
    --announcement-bar-glow: 0 4px 22px color-mix(in srgb, var(--announcement-bar-hue) 45%, transparent);
}

.announcement-bar {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    /* Right padding clears the 40px × and its 0.75rem gutter. */
    padding: 0.7rem 3.75rem;
    min-height: 56px;
    background: var(--announcement-bar-fill);
    border-bottom: 2px solid var(--announcement-bar-border);
    box-shadow: var(--announcement-bar-glow);
    color: var(--announcement-bar-text);
    text-align: center;
    /* Under the header's z-index: 30, so the sticky header always wins the overlap. */
    z-index: 20;
}

.announcement-bar-icon {
    flex-shrink: 0;
    font-size: 1.15rem;
    line-height: 1;
}

/* THE WHOLE STRIP IS THE CLICK TARGET, but only the text is the <a>.
   A stretched ::after gives the link the bar's full area without nesting the
   dismiss button inside an anchor (invalid HTML, and browsers resolve it by
   making the close button navigate). The button gets a higher z-index below, so
   it stays clickable inside the stretched region - which is the entire reason
   this is done with a pseudo-element instead of an <a> wrapper. */
.announcement-bar-link {
    color: inherit;
    font-weight: 700;
    line-height: 1.4;
    text-decoration: none;
    /* The title is escaped and capped at 200 characters, but a long one still has
       to survive a narrow screen - wrapping rather than an ellipsis, because an
       announcement nobody can finish reading is worse than a two-line bar. */
    overflow-wrap: anywhere;
}

.announcement-bar-link::after {
    content: '';
    position: absolute;
    inset: 0;
}

.announcement-bar-link:hover,
.announcement-bar-link:focus-visible {
    text-decoration: underline;
}

/* Keyboard focus has to be visible on the bar itself, since the real hit area is
   a transparent pseudo-element and outlining that would draw nothing useful. */
.announcement-bar:has(.announcement-bar-link:focus-visible) {
    outline: 3px solid var(--announcement-bar-text);
    outline-offset: -3px;
}

/* ── Dismiss × ────────────────────────────────────────────────────────────────
   The canonical popup close button (.modal-close in base/popup-common.css):
   40px circle, spins 90° and turns red on hover. Restated rather than imported
   because popup-common.css is intentionally never linked site-wide - it carries
   global selectors that would break ordinary pages - and the bar is on every
   page. If the popup × is ever restyled, this is the copy to update with it. */
.announcement-bar-close {
    position: absolute;
    top: 50%;
    right: 0.75rem;
    /* translateY holds the vertical centring; the hover rule below has to repeat
       it, because transform is one property and `rotate` would replace it. */
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--announcement-bar-text) 35%, transparent);
    background: color-mix(in srgb, var(--announcement-bar-text) 10%, transparent);
    border-radius: 50%;
    color: var(--announcement-bar-text);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    transition: var(--transition);
    /* Above the link's stretched ::after, or the bar would swallow this click. */
    z-index: 2;
}

.announcement-bar-close:hover,
.announcement-bar-close:focus-visible {
    background: color-mix(in srgb, var(--hue-danger) 40%, transparent);
    border-color: var(--color-danger-text);
    color: white;
    transform: translateY(-50%) rotate(90deg);
}

@media (max-width: 700px) {
    .announcement-bar {
        padding: 0.65rem 3.25rem;
        font-size: 0.9rem;
        gap: 0.6rem;
    }

    .announcement-bar-close {
        right: 0.4rem;
        width: 34px;
        height: 34px;
        font-size: 1.25rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .announcement-bar-close { transition: none; }
    .announcement-bar-close:hover,
    .announcement-bar-close:focus-visible { transform: translateY(-50%); }
}

/* ── ERROR VARIANT ────────────────────────────────────────────────────────────
   Same strip, red instead of gold, used for the one message that has nowhere
   else to go: an upload that broke spring.servlet.multipart's ceiling. That
   failure happens while the request is still being PARSED, so no controller ran,
   no form is on screen to hang a field error on, and the visitor has just been
   bounced back to the page they posted from (see UploadSizeExceededAdvice).

   Only the two theme knobs are overridden - the fill, border and glow are
   color-mix()es OF the hue, so they follow it on their own. Danger is a dark
   hue, hence white text rather than the gold bar's near-black.

   The message is a <span>, not the <a>: there is nowhere to navigate to, so the
   bar carries no stretched ::after and the × is the only control on it. */
.announcement-bar--error {
    --announcement-bar-hue: var(--hue-danger);
    --announcement-bar-text: #fff;
}

.announcement-bar-message {
    color: inherit;
    font-weight: 700;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
