/* ==========================================================================
   Announcements chrome — the topbar bell's unread badge and the
   per-section what's-new strip. Loaded on every page from
   includes/assets/css.html; the archive page's own styles live in
   whats-new.css, loaded only there.

   Every color reads a token; the one literal white is a label on a
   solid accent, which is theme-invariant (see avatar.css).
   ========================================================================== */

/* ---- topbar bell ------------------------------------------------------- */

/* The bell is a .btn-ghost .btn-icon like every other topbar icon.
   .btn-icon is a fixed square that clips its overflow, so the button
   must let the count badge poke out of its corner. */
.btn.announcement-bell {
    position: relative;
    overflow: visible;
}

.announcement-bell-badge {
    position: absolute;
    top: 1px;
    right: 1px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    font-size: 0.65rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    background: var(--bs-danger);
    color: #fff;
    /* A ring of topbar frame behind the badge lifts it off the glyph. */
    box-shadow: 0 0 0 2px var(--chrome-surface);
}

/* ---- in-section what's-new strip --------------------------------------- */

/* One slim strip per section, however many releases it covers. It
   hugs its content instead of spanning the container, wears a
   quiet accent tint, and never grows taller than one line. */
.announcement-strip {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    max-width: 100%;
    margin-bottom: 1rem;
    padding: 0.3125rem 0.375rem;
    background:
        linear-gradient(
            rgba(var(--bs-primary-rgb), 0.06),
            rgba(var(--bs-primary-rgb), 0.06)
        ),
        var(--bg-surface);
    border: 1px solid rgba(var(--bs-primary-rgb), 0.22);
    /* 8px matches the app's cards (stat-card, tables, list-group). */
    border-radius: 8px;
    font-size: 0.875rem;
    line-height: 1.25;
    animation: announcement-strip-in 300ms ease-out;
    transition-property: opacity, transform;
    transition-duration: 150ms;
    transition-timing-function: ease-out;
}

@keyframes announcement-strip-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
}

/* The icon sits in a solid accent chip, which anchors the pill's
   left edge and centers the glyph. */
.announcement-strip-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: rgba(var(--bs-primary-rgb), 0.16);
    color: rgb(var(--bs-primary-rgb));
    font-size: 0.75rem;
}

.announcement-strip-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-secondary);
}

.announcement-strip-text strong {
    font-weight: 600;
    color: var(--text-primary);
}

/* A quiet inline link: hover speaks with color, never an underline —
   an underline would also run beneath the ::before separator dot. */
/* Same font size and line height as the strip text: flex centering
   of two different font sizes puts their baselines at different
   heights, and the line reads as crooked. */
.announcement-strip-link {
    flex: 0 0 auto;
    font-weight: 500;
    white-space: nowrap;
    color: rgb(var(--bs-primary-rgb));
    text-decoration: none;
    transition-property: color;
    transition-duration: 150ms;
    transition-timing-function: ease-out;
}

.announcement-strip-link:hover {
    color: var(--text-primary);
    text-decoration: none;
}

/* Reads as part of the sentence: a hairline dot ahead of the link. */
.announcement-strip-link::before {
    content: "·";
    margin-right: 0.625rem;
    color: var(--text-tertiary);
    font-weight: 400;
}

.announcement-dismiss {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--text-tertiary);
    transition-property: background-color, color;
    transition-duration: 150ms;
    transition-timing-function: ease-out;
}

/* The visible control is 30px; the hit area reaches 42px. */
.announcement-dismiss::after {
    content: "";
    position: absolute;
    inset: -6px;
}

.announcement-dismiss:hover {
    background: var(--surface-2);
    color: var(--text-secondary);
}

.announcement-dismiss:active {
    transform: scale(0.96);
}

/* Dismiss swaps the strip for an empty response: fade it out over
   the swap delay. */
.announcement-strip.htmx-swapping {
    opacity: 0;
    transform: translateY(-2px);
}
