* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Poppins', sans-serif;
    line-height: 1.6;
    color: #16203a;
    /* Light gray page, white cards: the gray is what gives the white panels an
       edge without needing a heavy border on every one of them. */
    background-color: #f5f7fb;
}

body.loading-locked {
    overflow: hidden;
    height: 100vh;
}

body.ui-locked {
    overflow: hidden;
    height: 100vh;
}

/* Loading Screen Styles */
.loading-screen {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0f2a6e;
    z-index: 9999;
    opacity: 1;
    /* The fade is triggered by the .is-hiding class rather than a fixed delay,
       so the intro clears as soon as the page is ready instead of always
       occupying the same two seconds. */
    transition: opacity 0.4s ease-out;
}

.loading-screen.is-hiding {
    opacity: 0;
    pointer-events: none;
}

.loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2rem;
}

.red-circle {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background-color: #ff0000;
    box-shadow: 0 0 30px rgba(255, 0, 0, 0.8), inset 0 0 30px rgba(255, 0, 0, 0.4);
    animation: pulseCircle 1.1s ease-in-out infinite;
}

@keyframes pulseCircle {
    0% {
        transform: scale(1);
        box-shadow: 0 0 30px rgba(255, 0, 0, 0.8), inset 0 0 30px rgba(255, 0, 0, 0.4);
    }
    50% {
        transform: scale(1.1);
        box-shadow: 0 0 50px #ff0000, inset 0 0 50px rgba(255, 0, 0, 0.6);
    }
    100% {
        transform: scale(1);
        box-shadow: 0 0 30px rgba(255, 0, 0, 0.8), inset 0 0 30px rgba(255, 0, 0, 0.4);
    }
}

.on-air-text {
    font-size: 3.5rem;
    font-weight: 800;
    color: #ffffff;
    letter-spacing: 3px;
    margin: 0;
    /* Shortened to match the now much briefer intro, so the text still finishes
       arriving before the overlay clears. */
    animation: textAppear 0.4s ease-in;
}

@keyframes textAppear {
    0% {
        opacity: 0;
        transform: translateY(10px);
    }
    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
        pointer-events: none;
    }
}

/* Header Styles */
header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 2rem;
    /* The header and footer are the one place the royal blue is the surface
       rather than the accent, so the strip at the top of every page reads as
       the brand and everything between them stays light. */
    background-color: #1a3fb0;
    box-shadow: 0 2px 5px rgba(16, 26, 56, 0.18);
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 3px solid #0f2a6e;
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.35s ease, transform 0.35s ease;
    will-change: opacity, transform;
}

header.header-hidden {
    opacity: 0;
    transform: translateY(-18px);
    pointer-events: none;
}

header .logo {
    background: transparent !important;
    padding: 0;
}

header .logo img {
    height: 150px;
    width: auto;
    filter: brightness(1.3);
}

header .menu {
    display: flex;
    list-style: none;
    gap: 1rem;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    position: relative;
    flex-direction: row;
    /* The menu takes the whole strip left over beside the logo so that its own
       justify-content actually has room to work: as a content-sized flex item it
       hugged its links and the header's space-between parked them on the right
       edge. Growing it first, then centring inside it, keeps the links in the
       middle of that strip whether or not the LIVE NOW button is showing.
       The mobile rule re-positions this menu absolutely, where flex does not
       apply, so the dropdown is unaffected. */
    flex: 1;
}

header .menu.active {
    display: flex;
}

header .menu a {
    text-decoration: none;
    color: #ffffff;
    font-weight: 500;
    transition: color 0.3s;
    font-size: 0.95rem;
    white-space: nowrap;
}

header .menu a:hover {
    color: #cfe0ff;
}

header .user-name-display {
    color: #ffffff;
    font-weight: 500;
    font-size: 0.95rem;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.3s;
}

header .user-name-display:hover {
    color: #cfe0ff;
}

header .user-name-display.streaming-active {
    color: #ffffff;
}

header .user-name-display.verified-name {
    color: #ffffff;
    font-weight: 700;
}

header .user-name-display.streaming-active.verified-name {
    color: #ffffff;
}

header .user-name-display.role-moderator-name,
header .user-name-display.streaming-active.role-moderator-name,
header .user-name-display.verified-name.role-moderator-name {
    color: #cfe0ff;
    font-weight: 700;
}

header .user-name-display.role-admin-name,
header .user-name-display.streaming-active.role-admin-name,
header .user-name-display.verified-name.role-admin-name {
    color: #ffffff;
    font-weight: 700;
}

header .user-name-display.streaming-active:hover {
    color: #cfe0ff;
}

/* The LIVE NOW button is an outlined box in the header. With nothing live it is an
   empty box with a white outline; once something is live the box fills solid red and
   stays that colour throughout — only the glow around it pulses, so the button never
   dims or reads as half-lit. It is clickable in both states: with nothing live it
   leads to highlights and past streams. */
header .live-btn {
    background-color: transparent;
    color: #ffffff;
    padding: 0.7rem 1.5rem;
    border-radius: 5px;
    border: 2px solid #ffffff;
    text-decoration: none;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}

header .live-btn:not(.is-live):hover {
    background-color: rgba(255, 255, 255, 0.16);
    color: #ffffff;
    border-color: #ffffff;
}

header .live-btn.is-live,
header .live-btn.is-live:hover {
    background-color: #ff0000;
    color: #ffffff;
    border-color: #ff0000;
    animation: liveNowGlow 1.4s ease-in-out infinite;
}

/* Only the glow moves. The fill is left out of the keyframes so the button holds a
   solid red for the whole cycle. */
@keyframes liveNowGlow {
    0%, 100% {
        box-shadow: 0 0 0 rgba(255, 0, 0, 0);
    }
    50% {
        box-shadow: 0 0 18px rgba(255, 0, 0, 0.85);
    }
}

@media (prefers-reduced-motion: reduce) {
    header .live-btn.is-live {
        animation: none;
        box-shadow: 0 0 14px rgba(255, 0, 0, 0.6);
    }
}

header .menu-toggle {
    display: none;
    font-size: 1.5rem;
    cursor: pointer;
    color: #ffffff;
    background: none;
    border: none;
}

header .profile-icon-container {
    display: none;
    align-items: center;
    justify-content: center;
}

header .profile-icon-container.signed-in {
    display: flex;
}

header .profile-icon {
    background: none;
    border: none;
    border-radius: 50%;
    width: auto;
    height: auto;
    font-size: 1.5rem;
    cursor: pointer;
    color: #ffffff;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

header .profile-icon:hover {
    background-color: transparent;
    color: #ffffff;
    transform: scale(1.15);
}

header .profile-icon.signed-in {
    border: none;
    color: #ffffff;
    width: auto;
    height: auto;
}

header .profile-icon.signed-in:hover {
    background-color: transparent;
    color: #ffffff;
    transform: scale(1.15);
}

/* Hero Section */
/* Front page only, and directly under the Our News box, so it is edged to
   match: same radius, same shadow, and space underneath so the sponsor strip
   and the stations below start clear of it. Two royal boxes with light page
   showing between them read as two boxes; touching, they read as one. */
.hero {
    margin: 0 auto 3.5rem;
    padding: 4rem 2rem;
    border-radius: 22px;
    background: linear-gradient(135deg, #12307f 0%, #2a5be0 100%);
    color: white;
    text-align: center;
    min-height: 600px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 22px 50px rgba(10, 27, 68, 0.26);
}

.hero-content {
    max-width: 800px;
}

.hero h1 {
    font-size: 3rem;
    margin-bottom: 1rem;
    font-weight: 800;
}

.hero h1 span {
    color: #cfe0ff;
}

.hero h1 .hero-title-line {
    color: inherit;
}

.hero p {
    font-size: 1.2rem;
    margin-bottom: 2rem;
    color: #cfe0ff;
}

.hero-buttons {
    display: flex;
    gap: 1rem;
    justify-content: center;
    flex-wrap: wrap;
}

.btn, .btn-outline {
    padding: 0.9rem 2rem;
    font-size: 1rem;
    border-radius: 5px;
    text-decoration: none;
    font-weight: 600;
    transition: all 0.3s;
    border: none;
    cursor: pointer;
}

/* Both of these only ever appear in the hero, which is itself royal blue, so
   they invert: white fill and white outline rather than blue on blue. */
.btn {
    background-color: #ffffff;
    color: #0f2a6e;
}

.btn:hover {
    background-color: #cfe0ff;
    transform: translateY(-2px);
}

.btn-outline {
    background-color: transparent;
    color: #ffffff;
    border: 2px solid #ffffff;
}

.btn-outline:hover {
    background-color: #ffffff;
    color: #0f2a6e;
    transform: translateY(-2px);
}

/* Sections */
section {
    padding: 4rem 2rem;
    max-width: 1200px;
    margin: 0 auto;
    background-color: transparent;
}

section h2 {
    font-size: 2.5rem;
    margin-bottom: 3rem;
    text-align: center;
    color: #1d4ed8;
}

/* Station Grid */
.station-grid, .news-grid, .event-grid, .live-now-grid, .local-listings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
    gap: 2rem;
}

.station-card, .news-card, .event-card, .local-listing-card {
    background: #ffffff;
    padding: 2rem;
    border-radius: 10px;
    /* A royal ring on every card at once turned the grid into a stack of
       boxes; the edge is gray and the blue is saved for the heading, with the
       ring coming back on hover. */
    border: 2px solid #dde3ee;
    box-shadow: 0 5px 15px rgba(16, 26, 56, 0.08);
    text-align: center;
    transition: transform 0.3s, box-shadow 0.3s;
}

.station-card:hover, .news-card:hover, .event-card:hover, .local-listing-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 25px rgba(29, 78, 216, 0.22);
    border-color: #1d4ed8;
}

.station-card h3, .news-card h3, .event-card h3, .local-listing-card h3 {
    color: #1d4ed8;
    margin-bottom: 0.5rem;
    font-size: 1.5rem;
}

.station-card p, .news-card p, .event-card p, .local-listing-card p {
    color: #64708c;
    margin-bottom: 1.5rem;
}

/* Ensure titles in Upcoming Events are gold */
.events,
.events .event-card,
.events .event-card h3 {
    color: #1d4ed8;
}

.events .event-card {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.events .event-card h3,
.events .event-card p {
    display: block;
    width: 100%;
}

.events .event-card h3 {
    margin-bottom: 0.65rem;
}

.events .event-card p:last-of-type {
    margin-bottom: 0;
}

.local-listing-link {
    display: inline-block;
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.6rem 1.2rem;
    border-radius: 5px;
    border: none;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    transition: background-color 0.3s, transform 0.2s ease;
}

.local-listing-link:hover,
.local-listing-link:focus-visible {
    background-color: #3b6ff2;
    transform: translateY(-2px);
}

.station-card .listen-btn {
    display: inline-block;
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.6rem 1.2rem;
    border-radius: 5px;
    border: none;
    font-weight: 600;
    font-size: 1rem;
    font-family: inherit;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color 0.3s;
}

.station-card .listen-btn:hover,
.station-card .listen-btn:focus-visible {
    background-color: #3b6ff2;
}

/* Player Section */
.player-card {
    --player-accent: #1d4ed8;
    --player-accent-soft: rgba(29, 78, 216, 0.28);
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.94));
    padding: 1rem;
    border-radius: 14px;
    border: 1px solid rgba(29, 78, 216, 0.72);
    box-shadow: 0 16px 34px rgba(16, 26, 56, 0.46);
    max-width: min(92vw, 720px);
    margin: 0 auto;
    text-align: left;
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    column-gap: 0.95rem;
    row-gap: 0.52rem;
    align-items: center;
    backdrop-filter: blur(5px);
}

.player-card h3 {
    color: var(--player-accent);
    margin: 0;
    font-size: 1.06rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    grid-column: 2;
    line-height: 1.2;
}

.player-art-wrap {
    width: 180px;
    height: 180px;
    margin: 0;
    border-radius: 11px;
    overflow: hidden;
    border: 1px solid rgba(29, 78, 216, 0.62);
    box-shadow: 0 10px 24px rgba(16, 26, 56, 0.38);
    background: radial-gradient(circle at center, #ffffff 0%, #ffffff 100%);
    grid-column: 1;
    grid-row: 1 / span 5;
}

.player-art {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.player-playback-wrap {
    grid-column: 2;
    display: grid;
    row-gap: 0.34rem;
    padding: 0.45rem 0.5rem 0.5rem;
    border-radius: 11px;
    border: 1px solid rgba(29, 78, 216, 0.2);
    background: linear-gradient(100deg, rgba(59, 111, 242, 0.1), rgba(22, 32, 58, 0.03));
}

.player-card audio {
    grid-column: auto;
    width: 100%;
    margin: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, rgba(59, 111, 242, 0.24), rgba(22, 32, 58, 0.04));
    border: 1px solid rgba(29, 78, 216, 0.35);
    padding: 0.1rem;
    accent-color: var(--player-accent);
}

.player-card audio::-webkit-media-controls-seek-back-button,
.player-card audio::-webkit-media-controls-seek-forward-button {
    display: none;
}

.player-volume-control {
    grid-column: 2;
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin: 0;
    padding: 0.42rem 0.66rem;
    border: 1px solid var(--player-accent-soft);
    border-radius: 999px;
    background: linear-gradient(90deg, rgba(59, 111, 242, 0.18), rgba(22, 32, 58, 0.03));
}

.player-volume-label {
    color: var(--player-accent);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.sound-icon-button {
    width: 28px;
    height: 28px;
    border: 1px solid rgba(29, 78, 216, 0.45);
    border-radius: 999px;
    background: rgba(29, 78, 216, 0.08);
    color: #0f2a6e;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.sound-icon-button.compact {
    width: 24px;
    height: 24px;
}

.sound-icon-button:hover,
.sound-icon-button:focus-visible {
    background: rgba(59, 111, 242, 0.2);
    border-color: rgba(29, 78, 216, 0.8);
    transform: scale(1.03);
}

.sound-icon-svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.sound-icon-svg .speaker {
    fill: currentColor;
    stroke: none;
}

.sound-icon-svg .mute-slash {
    display: none;
}

.sound-icon-button[data-volume-state="low"] .wave-2 {
    opacity: 0.3;
}

.sound-icon-button[data-volume-state="muted"] .wave {
    display: none;
}

.sound-icon-button[data-volume-state="muted"] .mute-slash {
    display: inline;
}

.player-volume {
    --player-volume-fill: 100%;
    flex: 1;
    min-width: 120px;
    height: 18px;
    -webkit-appearance: none;
    appearance: none;
    border-radius: 999px;
    background: linear-gradient(to right, var(--player-accent) 0%, var(--player-accent) var(--player-volume-fill), rgba(22, 32, 58, 0.06) var(--player-volume-fill), rgba(22, 32, 58, 0.06) 100%);
    cursor: pointer;
}

.player-volume:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.player-volume::-webkit-slider-runnable-track {
    height: 5px;
    background: transparent;
    border-radius: 999px;
}

.player-volume::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #ffffff;
    border: 1px solid rgba(22, 32, 58, 0.2);
    box-shadow: 0 2px 8px rgba(16, 26, 56, 0.35);
    margin-top: -5.5px;
}

.player-volume::-moz-range-track {
    height: 5px;
    background: transparent;
    border-radius: 999px;
    border: none;
}

.player-volume::-moz-range-thumb {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #ffffff;
    border: 1px solid rgba(22, 32, 58, 0.2);
    box-shadow: 0 2px 8px rgba(16, 26, 56, 0.35);
}

.player-card p {
    color: #44506b;
}

#station-info {
    grid-column: 2;
    margin: 0;
    font-size: 0.86rem;
    font-weight: 600;
    line-height: 1.3;
    color: #44506b;
    opacity: 0.92;
}

.live-broadcast-description {
    grid-column: auto;
    margin: 0;
    padding: 0.02rem 0.2rem;
    border: none;
    background: transparent;
    color: #0f2a6e;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.48rem;
}

.live-broadcast-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.11rem 0.38rem;
    border-radius: 999px;
    background: rgba(255, 70, 70, 0.2);
    border: 1px solid rgba(255, 120, 120, 0.44);
    color: #c62828;
    font-size: 0.56rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1;
}

.live-broadcast-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}

.live-broadcast-primary {
    color: #44506b;
    font-size: 0.77rem;
    font-weight: 700;
    line-height: 1.18;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.live-broadcast-secondary {
    color: rgba(15, 42, 110, 0.8);
    font-size: 0.66rem;
    font-weight: 500;
    line-height: 1.16;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.live-broadcast-time {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 58px;
    padding: 0.12rem 0.4rem;
    border-radius: 999px;
    border: 1px solid rgba(29, 78, 216, 0.38);
    background: rgba(59, 111, 242, 0.12);
    color: #0f2a6e;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
}

.live-broadcast-time:empty {
    display: none;
}

.mini-player {
    position: fixed;
    left: 1rem;
    bottom: 1rem;
    width: min(92vw, 430px);
    display: grid;
    grid-template-columns: 54px 1fr auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.58rem 0.7rem;
    border-radius: 14px;
    border: 1px solid rgba(29, 78, 216, 0.76);
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.97), rgba(245, 247, 251, 0.95));
    box-shadow: 0 16px 34px rgba(16, 26, 56, 0.46);
    backdrop-filter: blur(5px);
    z-index: 2000;
    opacity: 0;
    transform: translateY(16px);
    pointer-events: none;
    transition: opacity 0.24s ease, transform 0.24s ease;
}

.mini-player.show {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.mini-player.show.idle-hidden {
    opacity: 0;
    transform: translateY(14px) scale(0.985);
    pointer-events: none;
}

.mini-player-art-wrap {
    width: 54px;
    height: 54px;
    border-radius: 9px;
    overflow: hidden;
    border: 1px solid rgba(29, 78, 216, 0.55);
    background: #ffffff;
    flex-shrink: 0;
}

.mini-player-art {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.mini-player-meta {
    min-width: 0;
    display: grid;
    gap: 0.35rem;
}

.mini-player-station {
    margin: 0;
    color: #0f2a6e;
    font-size: 0.84rem;
    font-weight: 700;
    line-height: 1.2;
}

.mini-player-playback-wrap {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.4rem;
    margin: 0;
    min-width: 0;
    padding: 0.2rem 0.3rem;
    border-radius: 10px;
    border: 1px solid rgba(29, 78, 216, 0.22);
    background: linear-gradient(100deg, rgba(59, 111, 242, 0.1), rgba(22, 32, 58, 0.03));
}

.mini-player-playback-wrap .live-broadcast-pill {
    padding: 0.1rem 0.32rem;
    font-size: 0.5rem;
}

.mini-player-playback-wrap .live-broadcast-primary {
    font-size: 0.69rem;
}

.mini-player-playback-wrap .live-broadcast-secondary {
    font-size: 0.6rem;
}

.mini-player-playback-wrap .live-broadcast-time {
    min-width: 48px;
    font-size: 0.53rem;
    padding: 0.1rem 0.3rem;
}

.mini-player-toggle {
    border: none;
    border-radius: 50%;
    width: 34px;
    height: 34px;
    background: #1d4ed8;
    color: #ffffff;
    font-family: 'Poppins', sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.2s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.mini-player-toggle-icon {
    width: 14px;
    height: 14px;
    fill: currentColor;
    display: block;
}

.mini-player-toggle:hover,
.mini-player-toggle:focus-visible {
    background: #3b6ff2;
    transform: scale(1.04);
}

.mini-player-controls {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    gap: 0.45rem;
}

@media (max-width: 768px) {
    .mini-player {
        padding: 0.65rem 0.75rem;
        gap: 0.65rem;
    }

    .mini-player-toggle {
        width: 38px;
        height: 38px;
        background: linear-gradient(180deg, #3b6ff2 0%, #1d4ed8 100%);
        box-shadow: 0 8px 18px rgba(16, 26, 56, 0.18);
    }

    .mini-player-toggle:active {
        transform: scale(0.98);
    }

    .mini-player-toggle-icon {
        width: 15px;
        height: 15px;
    }
}

.mini-player-volume-inline {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: 0;
}

.mini-player-volume {
    --volume-fill: 100%;
    width: 124px;
    height: 18px;
    -webkit-appearance: none;
    appearance: none;
    border-radius: 999px;
    background: linear-gradient(to right, #3b6ff2 0%, #3b6ff2 var(--volume-fill), rgba(22, 32, 58, 0.06) var(--volume-fill), rgba(22, 32, 58, 0.06) 100%);
    cursor: pointer;
}

.mini-player-volume:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.mini-player-volume::-webkit-slider-runnable-track {
    height: 5px;
    background: transparent;
    border-radius: 999px;
}

.mini-player-volume::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ffffff;
    border: 1px solid rgba(22, 32, 58, 0.2);
    box-shadow: 0 1px 5px rgba(16, 26, 56, 0.35);
    margin-top: -4.5px;
}

.mini-player-volume::-moz-range-track {
    height: 5px;
    border-radius: 999px;
    background: transparent;
    border: none;
}

.mini-player-volume::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ffffff;
    border: 1px solid rgba(22, 32, 58, 0.2);
    box-shadow: 0 1px 5px rgba(16, 26, 56, 0.35);
}

@media (max-width: 720px) {
    .mini-player {
        left: 0.75rem;
        right: 0.75rem;
        width: auto;
        bottom: 0.75rem;
        grid-template-columns: 48px 1fr auto;
        gap: 0.58rem;
    }

    .mini-player-art-wrap {
        width: 48px;
        height: 48px;
    }

    .mini-player-playback-wrap {
        column-gap: 0.32rem;
        padding: 0.18rem 0.24rem;
    }

    .mini-player-playback-wrap .live-broadcast-primary {
        font-size: 0.66rem;
    }

    .mini-player-playback-wrap .live-broadcast-secondary {
        font-size: 0.58rem;
    }

    .mini-player-playback-wrap .live-broadcast-time {
        min-width: 42px;
        font-size: 0.5rem;
    }

    .mini-player-volume {
        width: 102px;
        height: 16px;
    }

    .player-card {
        grid-template-columns: 1fr;
        max-width: min(94vw, 430px);
        row-gap: 0.66rem;
        padding: 0.84rem;
        text-align: left;
    }

    .player-art-wrap {
        grid-column: 1;
        grid-row: auto;
        width: 100%;
        height: auto;
        aspect-ratio: 1 / 1;
        max-width: 190px;
        justify-self: center;
    }

    .player-card h3,
    .player-playback-wrap,
    .player-volume-control,
    #station-info,
    .player-card audio,
    .live-broadcast-description {
        grid-column: 1;
    }

    .player-playback-wrap {
        row-gap: 0.28rem;
        padding: 0.4rem 0.45rem 0.45rem;
    }

    .live-broadcast-description {
        column-gap: 0.38rem;
    }

    .live-broadcast-primary {
        font-size: 0.74rem;
    }

    .live-broadcast-secondary {
        font-size: 0.64rem;
    }

    .live-broadcast-time {
        min-width: 52px;
        font-size: 0.58rem;
    }

    .player-volume-control {
        gap: 0.5rem;
    }
}

/* Contact Form */
#contactForm {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 600px;
    margin: 0 auto;
    background: #ffffff;
    padding: 2rem;
    border-radius: 10px;
    border: 2px solid #1d4ed8;
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.2);
}

#contactForm input, #contactForm textarea {
    /* Sized by the tile rather than by the browser's default field width,
       which is wider than the tile in the slim column between the sponsor
       rails on a phone. */
    width: 100%;
    min-width: 0;
    padding: 0.8rem;
    border: 1px solid #1d4ed8;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
    font-size: 1rem;
    background-color: #ffffff;
    color: #44506b;
}

#contactForm input::placeholder, #contactForm textarea::placeholder {
    color: #64708c;
}

#contactForm input:focus, #contactForm textarea:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 5px rgba(29, 78, 216, 0.5);
}

#contactForm button {
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.9rem;
    border: none;
    border-radius: 5px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.3s;
}

#contactForm button:hover {
    background-color: #3b6ff2;
}

/* Contact Section */
.contact-container {
    display: grid;
    /* minmax(0, ...) so neither tile can hold its column open wider than the
       page - a plain 1fr will not shrink below its content's widest line. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 3rem;
    max-width: 1200px;
    margin: 0 auto;
}

.contact-info {
    background: #ffffff;
    padding: 2rem;
    border: 2px solid #1d4ed8;
    border-radius: 10px;
}

.contact-info h3 {
    color: #1d4ed8;
    font-size: 1.5rem;
    margin-bottom: 2rem;
}

.info-block {
    margin-bottom: 2rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid #dde3ee;
}

.info-block:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

.info-block h4 {
    color: #1d4ed8;
    margin-bottom: 1rem;
    font-size: 1.1rem;
}

.info-block p {
    color: #64708c;
    margin: 0.5rem 0;
}

.info-block a {
    color: #1d4ed8;
    text-decoration: none;
    transition: color 0.3s;
}

.info-block a:hover {
    color: #0f2a6e;
}

.contact-form {
    background: #ffffff;
    padding: 2rem;
    border: 2px solid #1d4ed8;
    border-radius: 10px;
}

.contact-form h3 {
    color: #1d4ed8;
    font-size: 1.5rem;
    margin-bottom: 1.5rem;
}

/* A long address wraps inside the tile instead of pushing it wider. */
.info-block a {
    overflow-wrap: anywhere;
}

@media (max-width: 768px) {
    .contact-container {
        grid-template-columns: minmax(0, 1fr);
        gap: 2rem;
    }

    .contact-info,
    .contact-form,
    #contactForm {
        padding: 1.25rem 1rem;
    }

    .contact-info h3,
    .contact-form h3 {
        font-size: 1.25rem;
    }
}

/* Song Requests Section */
.song-request-intro {
    text-align: center;
    font-size: 1.1rem;
    color: #64708c;
    max-width: 720px;
    margin: -1.5rem auto 3rem;
}

.song-request-container {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 2rem;
    align-items: start;
}

/* The signed-out prompt stands in for the form, so it takes the whole width. */
.song-request-container > .song-request-locked {
    grid-column: 1 / -1;
    max-width: 640px;
    margin: 0 auto;
    text-align: center;
}

.song-request-card {
    background: #ffffff;
    border: 2px solid #1d4ed8;
    border-radius: 10px;
    padding: 2rem;
}

.song-request-card h3 {
    color: #1d4ed8;
    font-size: 1.5rem;
    margin-bottom: 1rem;
}

.song-request-locked p {
    color: #64708c;
    margin-bottom: 1.5rem;
}

.song-request-locked-actions {
    display: flex;
    gap: 1rem;
    justify-content: center;
    flex-wrap: wrap;
}

.song-request-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.song-request-whoami {
    color: #64708c;
    margin-bottom: 1rem;
}

.song-request-who {
    color: #1d4ed8;
    font-weight: 600;
}

.song-request-form label {
    color: #44506b;
    font-size: 0.95rem;
    font-weight: 500;
    margin-top: 0.6rem;
}

.song-request-optional {
    color: #64708c;
    font-weight: 400;
}

.song-request-form input[type="text"],
.song-request-form textarea,
.song-request-select {
    padding: 0.8rem;
    border: 1px solid #1d4ed8;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
    font-size: 1rem;
    background-color: #ffffff;
    color: #44506b;
    width: 100%;
}

.song-request-form input::placeholder,
.song-request-form textarea::placeholder {
    color: #64708c;
}

.song-request-form input:focus,
.song-request-form textarea:focus,
.song-request-select:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 5px rgba(29, 78, 216, 0.5);
}

.song-request-form textarea {
    resize: vertical;
}

.song-request-counter {
    color: #64708c;
    font-size: 0.8rem;
    text-align: right;
    margin: 0;
}

.song-request-note {
    color: #64708c;
    font-size: 0.85rem;
    margin: 0.4rem 0 0;
}

.btn-song-request {
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.9rem 1.4rem;
    border: 2px solid #1d4ed8;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}

.btn-song-request:hover:not(:disabled) {
    background-color: #3b6ff2;
    border-color: #1d4ed8;
}

.btn-song-request:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.btn-song-request.is-secondary {
    background-color: transparent;
    color: #1d4ed8;
}

.btn-song-request.is-secondary:hover:not(:disabled) {
    background-color: rgba(29, 78, 216, 0.15);
    color: #0f2a6e;
}

.btn-song-request.is-danger {
    background-color: transparent;
    border-color: rgba(220, 90, 90, 0.7);
    color: #c62828;
}

.btn-song-request.is-danger:hover:not(:disabled) {
    background-color: rgba(220, 90, 90, 0.18);
    border-color: #e08585;
    color: #c62828;
}

.btn-song-request.is-compact {
    padding: 0.45rem 0.8rem;
    font-size: 0.85rem;
    border-width: 1px;
}

/* A member's own requests, and the studio's answer to each one. */
.song-request-mine .song-request-list {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    max-height: 30rem;
    overflow-y: auto;
}

.song-request-row,
.song-request-studio-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    padding: 0.9rem 1rem;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 8px;
}

.song-request-row-main {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.song-request-song {
    color: #44506b;
    font-size: 1rem;
    overflow-wrap: anywhere;
}

.song-request-artist {
    color: #1d4ed8;
    font-size: 0.9rem;
    overflow-wrap: anywhere;
}

.song-request-meta {
    color: #64708c;
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

.song-request-message {
    color: #64708c;
    font-size: 0.85rem;
    font-style: italic;
    margin-top: 0.25rem;
    overflow-wrap: anywhere;
}

.song-request-status {
    flex: 0 0 auto;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    background: rgba(29, 78, 216, 0.12);
    border: 1px solid rgba(29, 78, 216, 0.5);
    color: #1d4ed8;
}

.song-request-status.is-queued {
    background: rgba(29, 78, 216, 0.14);
    border-color: rgba(29, 78, 216, 0.6);
    color: #1d4ed8;
}

.song-request-status.is-played {
    background: rgba(90, 200, 130, 0.14);
    border-color: rgba(110, 210, 150, 0.6);
    color: #2e7d32;
}

.song-request-status.is-declined {
    background: rgba(200, 100, 100, 0.14);
    border-color: rgba(220, 130, 130, 0.6);
    color: #c62828;
}

.song-request-empty {
    color: #64708c;
    text-align: center;
    margin: 0;
    padding: 1rem 0;
}

/* Studio queue - admins and moderators only. */
.song-request-studio {
    margin-top: 2.5rem;
    padding: 2rem;
    background: #ffffff;
    border: 2px solid rgba(29, 78, 216, 0.55);
    border-radius: 10px;
}

.song-request-studio[hidden] {
    display: none;
}

/* The form is a flex column, and an explicit display beats the hidden attribute,
   so every part of this section that is shown or hidden by script says so here.
   Without this the form stays on screen for signed-out visitors. */
/* .form-message reserves a boxed row even when it is empty, and the rest of the
   site hides those boxes by id until there is something to say. Same here, so
   the form does not open with a blank gold panel under the button. */
#songRequestMessage {
    display: none;
}

#songRequestMessage.error,
#songRequestMessage.success,
#songRequestMessage.info {
    display: flex;
}

#songRequestSignedOut[hidden],
#songRequestForm[hidden],
#songRequestMine[hidden],
#songRequestStudio[hidden] {
    display: none !important;
}

.song-request-studio-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.song-request-studio-head h3 {
    color: #1d4ed8;
    font-size: 1.5rem;
    margin: 0;
}

.song-request-studio-list {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    max-height: 34rem;
    overflow-y: auto;
    margin-top: 1rem;
}

.song-request-studio-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.6rem;
}

.song-request-decline-reason {
    color: #c62828;
    font-size: 0.85rem;
    margin-top: 0.25rem;
    overflow-wrap: anywhere;
}

.song-request-decline-form {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: min(100%, 260px);
}

.song-request-decline-input {
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: 1px solid #c9d2e3;
    border-radius: 5px;
    font-family: inherit;
    font-size: 0.9rem;
    box-sizing: border-box;
}

.song-request-decline-input:focus {
    outline: 2px solid #1d4ed8;
    outline-offset: 1px;
}

.song-request-studio-buttons {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

@media (max-width: 900px) {
    .song-request-container {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 600px) {
    .song-request-card,
    .song-request-studio {
        padding: 1.25rem;
    }

    .song-request-row,
    .song-request-studio-row {
        flex-direction: column;
        align-items: stretch;
    }

    .song-request-studio-actions {
        align-items: stretch;
    }

    .song-request-studio-buttons {
        justify-content: stretch;
    }

    .song-request-studio-buttons .btn-song-request {
        flex: 1 1 auto;
    }
}

/* Advertising Section */
.advertise {
    background-color: #ffffff;
}

.advertise-intro {
    text-align: center;
    font-size: 1.1rem;
    color: #64708c;
    margin-bottom: 3rem;
}

.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 2rem;
    margin-bottom: 3rem;
}

.pricing-card {
    background: #ffffff;
    border: 2px solid #1d4ed8;
    padding: 2rem;
    border-radius: 10px;
    text-align: center;
    position: relative;
    /* The photo behind the words is a layer filling the card, so it has to be
       cut to the card's own corners. */
    overflow: hidden;
    transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
    cursor: pointer;
}

.pricing-card:hover {
    transform: translateY(-8px);
    box-shadow: 0 15px 40px rgba(29, 78, 216, 0.4);
    border-color: #1d4ed8;
}

/*
    The picture behind the words.

    A layer of its own rather than a background on the card, because the scrim
    that keeps the text readable has to sit between the two - and because a card
    with no picture set should look like a finished card rather than a broken
    one, which it does: the layer stays empty and the white card shows through.

    The scrim is on the layer's own ::after, so it arrives and leaves with the
    photo. It is heavier at the bottom, where the list of what is included runs
    longest and needs the most help.
*/
.pricing-photo {
    position: absolute;
    inset: 0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    /* Nothing to see until a photo is set; the card's own white is the backdrop
       in the meantime. */
    background-image: none;
}

.pricing-card.has-photo .pricing-photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(15, 42, 110, 0.62) 0%, rgba(15, 42, 110, 0.78) 55%, rgba(15, 42, 110, 0.9) 100%);
}

/* Above the picture, and the reason the picture can be full-bleed while the
   text keeps the card's padding. */
.pricing-body {
    position: relative;
    z-index: 1;
}

.pricing-tagline {
    margin: 0 0 1.25rem;
    color: #44506b;
    font-size: 0.95rem;
    line-height: 1.5;
}

.pricing-card h3 {
    color: #1d4ed8;
    font-size: 1.8rem;
    margin-bottom: 1rem;
}

/*
    There is deliberately no rule here for a price or a "most popular" ribbon on
    these cards. The markup has no element for either, the renderer writes
    neither, and leaving the styling behind would only invite one back.
*/

/*
    With a photo behind it the card is dark, so the type inverts. Only the
    colours change - the sizes, spacing and the hairlines between benefits are
    the same either way, so a card with a picture and a card without still read
    as the same card.
*/
.pricing-card.has-photo h3 {
    color: #ffffff;
    text-shadow: 0 1px 12px rgba(10, 27, 68, 0.55);
}

.pricing-card.has-photo .pricing-tagline {
    color: rgba(255, 255, 255, 0.88);
}

.pricing-card.has-photo .benefits li {
    color: #ffffff;
    border-bottom-color: rgba(255, 255, 255, 0.28);
}

.pricing-card .benefits {
    list-style: none;
    text-align: left;
    margin: 2rem 0;
    padding: 0;
}

.pricing-card .benefits li {
    padding: 0.7rem 0;
    color: #44506b;
    border-bottom: 1px solid #dde3ee;
}

.pricing-card .benefits li:last-child {
    border-bottom: none;
}

.cta-btn {
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.8rem 2rem;
    border: none;
    border-radius: 5px;
    font-weight: 600;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s;
    width: 100%;
    margin-top: 1.5rem;
}

.cta-btn:hover {
    background-color: #3b6ff2;
}

.cta-btn.featured-btn {
    background-color: #3b6ff2;
}

.cta-btn.featured-btn:hover {
    background-color: #1d4ed8;
}

/*
    The sales team, under the packages.

    The tiles are drawn from a list an admin keeps, so the styling has to hold
    for one person or for a dozen: the grid fills the row and wraps, and a tile
    is the same shape whether the person has a photo, a role line, or neither.
    The admin buttons and the form are styled here too, so the section can be
    edited in place instead of from the panel.
*/
.sales-team {
    margin-top: 2.5rem;
}

.sales-head {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.75rem;
}

.sales-head h3 {
    margin: 0;
    color: #0f2a6e;
    font-size: 1.35rem;
}

.sales-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: 1.5rem;
}

.sales-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1rem;
    padding: 1.75rem 1.5rem;
    background: #ffffff;
    border: 1px solid #dde3ee;
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(22, 32, 58, 0.07);
}

/* Square and cropped to a circle, so photos taken at any size or shape still
   line up across a row. */
.sales-photo {
    width: 104px;
    height: 104px;
    border-radius: 50%;
    object-fit: cover;
    background: #eef2fb;
    border: 3px solid #e3e9f6;
}

/* Initials, for a person with no photo yet - the same circle, so the row does
   not change shape while photos are still being collected. */
.sales-photo-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #1d4ed8;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}

.sales-tile-body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    width: 100%;
}

.sales-name {
    margin: 0;
    color: #0f2a6e;
    font-size: 1.15rem;
}

.sales-role {
    margin: 0;
    color: #64708c;
    font-size: 0.9rem;
}

.sales-contact {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.sales-contact a {
    color: #1d4ed8;
    font-size: 0.95rem;
    text-decoration: none;
    /* An email address is one long unbreakable word, and a narrow tile would
       otherwise be widened by it. */
    overflow-wrap: anywhere;
}

.sales-contact a:hover {
    text-decoration: underline;
}

.sales-tile-admin {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    margin-top: 0.85rem;
}

.sales-btn {
    padding: 0.45rem 1rem;
    border: 1px solid #1d4ed8;
    border-radius: 999px;
    background: #ffffff;
    color: #1d4ed8;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
}

.sales-btn:hover:not([disabled]) {
    background: #1d4ed8;
    color: #ffffff;
}

.sales-btn[disabled] {
    opacity: 0.45;
    cursor: default;
}

.sales-btn-primary {
    background: #1d4ed8;
    color: #ffffff;
}

.sales-btn-primary:hover:not([disabled]) {
    background: #0f2a6e;
    border-color: #0f2a6e;
}

.sales-btn-quiet {
    border-color: #c9d3e8;
    color: #64708c;
}

.sales-btn-quiet:hover:not([disabled]) {
    background: #64708c;
    border-color: #64708c;
}

.sales-notice {
    margin: 0 0 1.25rem;
    padding: 0.7rem 1rem;
    border-radius: 10px;
    font-size: 0.9rem;
    text-align: center;
}

.sales-notice-ok {
    background: #eef4ff;
    color: #0f2a6e;
}

.sales-notice-error {
    background: #fdecec;
    color: #9a2222;
}

.sales-form {
    display: grid;
    gap: 0.9rem;
    max-width: 520px;
    margin: 0 auto 2rem;
    padding: 1.75rem;
    background: #ffffff;
    border: 1px solid #dde3ee;
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(22, 32, 58, 0.07);
    text-align: left;
}

.sales-form h3 {
    margin: 0;
    color: #0f2a6e;
    font-size: 1.15rem;
}

.sales-form label {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    color: #44506b;
    font-size: 0.85rem;
    font-weight: 600;
}

.sales-form input {
    padding: 0.65rem 0.8rem;
    border: 1px solid #c9d3e8;
    border-radius: 8px;
    font-size: 0.95rem;
    font-family: inherit;
    color: #1a2338;
    background: #ffffff;
}

.sales-form input:focus {
    outline: 2px solid #1d4ed8;
    outline-offset: 1px;
    border-color: #1d4ed8;
}

.sales-form-hint {
    margin: 0;
    color: #64708c;
    font-size: 0.8rem;
}

.sales-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 0.4rem;
}

.sales-empty {
    margin: 0;
    text-align: center;
    color: #64708c;
    font-size: 0.95rem;
}

/* What the box said before there were tiles, kept for when there are none. */
.sales-empty-cta {
    text-align: center;
    padding: 2rem;
    background: #ffffff;
    border: 2px solid #1d4ed8;
    border-radius: 10px;
}

.sales-empty-cta p {
    color: #64708c;
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

@media (max-width: 768px) {
    .sales-grid {
        grid-template-columns: 1fr;
    }

    .sales-head {
        flex-direction: column;
    }
}

/* Sports Section */
.sports-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
    gap: 2rem;
}

.sports-card {
    background: #ffffff;
    padding: 0;
    border-radius: 10px;
    border: 2px solid #1d4ed8;
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.2);
    text-align: center;
    transition: transform 0.3s, box-shadow 0.3s;
    overflow: hidden;
}

.sports-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 25px rgba(29, 78, 216, 0.4);
    border-color: #1d4ed8;
}

.sports-thumbnail {
    position: relative;
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #ffffff 0%, #1d4ed8 100%);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

.sports-thumbnail.has-preview::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(14, 25, 55, 0.18), rgba(14, 25, 55, 0.48));
}

.play-button {
    position: relative;
    z-index: 1;
    font-size: 2rem;
    color: #ffffff;
    cursor: pointer;
    transition: transform 0.3s, text-shadow 0.3s;
    text-shadow: 0 0 10px rgba(29, 78, 216, 0.5);
}

.sports-thumbnail:hover .play-button {
    transform: scale(1.2);
    text-shadow: 0 0 20px rgba(29, 78, 216, 0.8);
}

.sports-card h3 {
    color: #1d4ed8;
    margin: 1rem 0 0.3rem 0;
    font-size: 1.1rem;
    padding: 0 1rem;
}

.sports-card p {
    color: #64708c;
    margin-bottom: 1rem;
    padding: 0 1rem;
    font-size: 0.85rem;
}

.watch-btn {
    display: inline-block;
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.5rem 1.2rem;
    border-radius: 5px;
    text-decoration: none;
    font-weight: 600;
    transition: background-color 0.3s;
    border: none;
    cursor: pointer;
    margin-bottom: 1rem;
}

.watch-btn:hover {
    background-color: #3b6ff2;
}

/* ---------------------------------------------------------------------------
   Watch Now, live score banner and scoreboard — hidden site-wide
   -------------------------------------------------------------
   These blocks are hidden by attribute rather than deleted, so the markup and
   the scripts that read it stay intact and one `hidden` attribute per element
   brings a section back.

   The !important follows the pattern the notification bell and song request
   cards use: `header .menu li`, `header .live-btn` and the mobile
   `header .menu a` rules carry layout that would otherwise win against the
   browser's own [hidden] rule. Because display:none takes each element out of
   the layout flow entirely, its padding and margins go with it and the
   sections below simply move up — no leftover gaps.
   --------------------------------------------------------------------------- */
/* The Live Now add button carries an inline display of its own, written by
   showContentAddButtons(), which would beat the attribute on its own. */
#addLiveBtn[hidden] {
    display: none !important;
}

.watch-now-menu-item[hidden],
.hero-buttons .watch-now-trigger[hidden],
.live-now-btn[hidden],
#sports[hidden],
#gameScoreBanner[hidden],
#liveScoreboard[hidden] {
    display: none !important;
}

/* Live Scoreboard */
.live-scoreboard {
    background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
}

.scoreboard-subtitle {
    text-align: center;
    color: #64708c;
    margin-bottom: 2rem;
    font-size: 0.98rem;
}

.scoreboard-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 1.3rem;
}

.scoreboard-card {
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.45);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    box-shadow: 0 6px 18px rgba(16, 26, 56, 0.25);
}

.scoreboard-card.highlight {
    border-color: #1d4ed8;
    box-shadow: 0 10px 25px rgba(29, 78, 216, 0.25);
}

.scoreboard-card h3 {
    color: #0f2a6e;
    margin: 0 0 0.7rem;
    font-size: 1.02rem;
}

.score-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.65rem;
}

.score-pill {
    background: rgba(29, 78, 216, 0.15);
    border: 1px solid rgba(29, 78, 216, 0.45);
    color: #0f2a6e;
    border-radius: 999px;
    padding: 0.28rem 0.62rem;
    font-size: 0.82rem;
    font-weight: 600;
}

.score-note {
    color: #64708c;
    font-size: 0.88rem;
    margin: 0;
}

.score-list {
    margin: 0;
    padding-left: 1rem;
    color: #44506b;
    line-height: 1.55;
    font-size: 0.9rem;
}

.scoreboard-actions {
    margin-top: 1.25rem;
    text-align: center;
}

/* TV-style Game Score Banner */
.game-score-banner {
    position: relative;
    width: min(1200px, 92%);
    margin: 1.2rem auto 1.8rem;
    border: 1px solid rgba(29, 78, 216, 0.75);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.97), rgba(255, 255, 255, 0.98));
    box-shadow: 0 10px 24px rgba(16, 26, 56, 0.35);
    overflow: hidden;
}

.score-main-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 0.9rem;
    align-items: center;
    padding: 0.42rem 0.85rem;
}

.score-team {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 0;
}

.team-logo-wrap {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid rgba(29, 78, 216, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    overflow: hidden;
    flex-shrink: 0;
}

.team-logo {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.badge-logo {
    color: #0f2a6e;
    font-weight: 800;
    font-size: 0.95rem;
}

.team-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
}

.team-meta.right {
    text-align: right;
}

.team-name {
    color: #44506b;
    font-weight: 700;
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.team-record {
    color: #64708c;
    font-size: 0.67rem;
}

.team-score {
    font-size: 1.65rem;
    font-weight: 800;
    color: #0f2a6e;
    line-height: 1;
}

.away-team {
    justify-content: flex-end;
}

.score-center-meta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.08rem;
    min-width: 180px;
}

.game-state {
    font-size: 0.63rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    padding: 0.1rem 0.46rem;
    border-radius: 999px;
}

.game-state.live {
    color: #c62828;
    background: rgba(255, 0, 0, 0.28);
    border: 1px solid rgba(255, 0, 0, 0.56);
}

.game-state.ended {
    color: #2e7d32;
    background: rgba(76, 175, 80, 0.24);
    border: 1px solid rgba(76, 175, 80, 0.58);
}

.game-state.scheduled {
    color: #0f2a6e;
    background: rgba(29, 78, 216, 0.2);
    border: 1px solid rgba(29, 78, 216, 0.56);
}

.game-clock {
    color: #44506b;
    font-size: 0.87rem;
    font-weight: 700;
}

.game-kickoff,
.game-local-time {
    color: #44506b;
    font-size: 0.66rem;
}

.game-date {
    color: #0f2a6e;
    font-size: 0.68rem;
    font-weight: 600;
}

.score-ticker-row {
    border-top: 1px solid rgba(29, 78, 216, 0.34);
    overflow: hidden;
    white-space: nowrap;
    padding: 0.28rem 0;
    background: rgba(29, 78, 216, 0.08);
    position: relative;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 7%, #000 93%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0%, #000 7%, #000 93%, transparent 100%);
}

.score-ticker-track {
    display: flex;
    width: max-content;
    gap: 1.35rem;
    align-items: center;
    animation: scoreTickerMove 32s linear infinite;
    color: #44506b;
    font-size: 0.72rem;
    font-weight: 500;
    will-change: transform;
}

.score-ticker-track span:first-child,
.score-ticker-track span:nth-child(6) {
    color: #0f2a6e;
    font-weight: 700;
}

@keyframes scoreTickerMove {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(-50%);
    }
}

@media (max-width: 900px) {
    .score-main-row {
        grid-template-columns: 1fr;
        gap: 0.4rem;
    }

    .score-team,
    .away-team {
        justify-content: center;
    }

    .team-meta.right {
        text-align: left;
    }
}

/* Subscribe Section */
.subscribe {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    padding: 4rem 2rem;
    text-align: center;
    border-top: 2px solid #1d4ed8;
    border-bottom: 2px solid #1d4ed8;
}

.subscribe h2 {
    color: #1d4ed8;
    font-size: 2.5rem;
    margin-bottom: 1rem;
}

.subscribe p {
    color: #64708c;
    font-size: 1.1rem;
    margin-bottom: 2rem;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
}

.btn-subscribe {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
    border: none;
    padding: 1rem 2.5rem;
    font-size: 1.1rem;
    font-weight: 600;
    border-radius: 50px;
    cursor: pointer;
    transition: transform 0.3s, box-shadow 0.3s;
}

.btn-subscribe:hover {
    transform: scale(1.05);
    box-shadow: 0 8px 25px rgba(29, 78, 216, 0.5);
}

.btn-subscribe.disabled,
.btn-subscribe:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
    filter: grayscale(0.2);
}

.subscribe-modal-content {
    max-width: 500px;
}

#signInModal .subscribe-modal-content {
    max-width: 620px;
    width: 92%;
}

.subscribe-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.form-message {
    margin-top: 1rem;
    text-align: center;
    font-size: 0.92rem;
    font-weight: 600;
    padding: 0.7rem 0.85rem;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.3);
    background: rgba(29, 78, 216, 0.08);
    color: #1d4ed8;
    min-height: 2.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.form-message.error {
    color: #c62828;
    border-color: rgba(255, 0, 0, 0.55);
    background: rgba(255, 0, 0, 0.12);
}

.form-message.success {
    color: #2e7d32;
    border-color: rgba(76, 175, 80, 0.55);
    background: rgba(76, 175, 80, 0.14);
}

.form-message.info {
    color: #0f2a6e;
    border-color: rgba(29, 78, 216, 0.55);
    background: rgba(29, 78, 216, 0.12);
}

#signInMessage {
    display: none;
}

#signInMessage.error,
#signInMessage.success,
#signInMessage.info {
    display: flex;
}

/* Keep sign-up feedback text visible, but remove the boxed alert look. */
#subscribeMessage {
    margin-top: 0.35rem;
    padding: 0;
    border: none;
    background: transparent;
    min-height: 1.2rem;
    display: block;
    text-align: left;
    justify-content: flex-start;
    align-items: flex-start;
    font-size: 0.84rem;
    font-weight: 500;
    color: rgba(68, 80, 107, 0.55);
    border-radius: 0;
}

#subscribeMessage.error,
#subscribeMessage.success,
#subscribeMessage.info {
    display: block;
    background: transparent;
    border: none;
    padding: 0;
    box-shadow: none;
    min-height: 1.2rem;
}

#subscribeMessage.error {
    color: #c62828;
}

#subscribeMessage.success {
    color: #2e7d32;
}

#subscribeMessage.info {
    color: #0f2a6e;
}

#paymentMessage {
    display: none;
}

#paymentMessage.error,
#paymentMessage.success,
#paymentMessage.info {
    display: flex;
}

#subscriptionsAccessMessage {
    display: none;
    margin-bottom: 1.25rem;
}

#subscriptionsAccessMessage.error,
#subscriptionsAccessMessage.success,
#subscriptionsAccessMessage.info {
    display: flex;
}

#subscriptionsAccessMessage.payment-shortcut-enabled {
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

#subscriptionsAccessMessage.payment-shortcut-enabled:hover {
    border-color: rgba(255, 0, 0, 0.7);
    background: rgba(255, 0, 0, 0.16);
}

.site-toast {
    position: fixed;
    right: 1.25rem;
    bottom: 1.25rem;
    max-width: min(88vw, 420px);
    padding: 0.85rem 1rem;
    border-radius: 10px;
    border: 1px solid rgba(29, 78, 216, 0.55);
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.97), rgba(245, 247, 251, 0.97));
    color: #0f2a6e;
    font-family: 'Poppins', sans-serif;
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.35;
    box-shadow: 0 12px 26px rgba(16, 26, 56, 0.45);
    z-index: 2100;
    opacity: 0;
    transform: translateY(10px);
    pointer-events: none;
    transition: opacity 0.24s ease, transform 0.24s ease;
}

.site-toast.show {
    opacity: 1;
    transform: translateY(0);
}

.site-toast.success {
    color: #ffffff;
    border-color: rgba(76, 175, 80, 0.6);
    background: linear-gradient(135deg, rgba(18, 56, 28, 0.95), rgba(32, 92, 46, 0.95));
}

.site-toast.error {
    color: #ffffff;
    border-color: rgba(255, 0, 0, 0.58);
    background: linear-gradient(135deg, rgba(82, 20, 20, 0.94), rgba(130, 36, 36, 0.94));
}

.subscribe-form input[type="text"],
.subscribe-form input[type="email"],
.subscribe-form input[type="tel"],
.subscribe-form input[type="password"] {
    padding: 0.75rem;
    border: 2px solid #1d4ed8;
    background-color: #ffffff;
    color: #44506b;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
}

.subscribe-form input:focus {
    outline: none;
    background-color: #ffffff;
    box-shadow: 0 0 10px rgba(29, 78, 216, 0.3);
}

.auth-switch-text {
    margin-top: 0.35rem;
    text-align: center;
    color: #64708c;
    font-size: 0.9rem;
}

.auth-switch-link {
    background: none;
    border: none;
    color: #0f2a6e;
    font-weight: 700;
    cursor: pointer;
    text-decoration: underline;
    font-family: 'Poppins', sans-serif;
    padding: 0;
}

.auth-switch-link:hover {
    color: #1d4ed8;
}

.password-requirements {
    margin-top: -0.2rem;
    margin-bottom: 0.2rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 8px;
    background: rgba(14, 25, 55, 0.39);
}

.password-requirements p {
    margin: 0 0 0.35rem;
    font-size: 0.85rem;
    color: #1d4ed8;
    font-weight: 600;
}

.password-requirements ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.2rem;
}

.requirement-item {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.84rem;
}

.requirement-item .req-icon {
    width: 1rem;
    display: inline-flex;
    justify-content: center;
    font-weight: 800;
}

.requirement-item.invalid {
    color: #c62828;
}

.requirement-item.invalid .req-icon {
    color: #c62828;
}

.requirement-item.valid {
    color: #2e7d32;
}

.requirement-item.valid .req-icon {
    color: #4caf50;
}

.password-field {
    position: relative;
    display: flex;
    align-items: center;
}

.password-field input[type="password"],
.password-field input[type="text"] {
    flex: 1;
    padding-right: 2.5rem;
}

/* Hide the browser's built-in password reveal / autofill icons so only the
   site's own eye toggle shows inside the field (Edge, Safari, Chrome). */
.password-field input[type="password"]::-ms-reveal,
.password-field input[type="password"]::-ms-clear,
.input-wrap input[type="password"]::-ms-reveal,
.input-wrap input[type="password"]::-ms-clear {
    display: none;
    width: 0;
    height: 0;
}

.password-field input[type="password"]::-webkit-credentials-auto-fill-button,
.password-field input[type="password"]::-webkit-strong-password-auto-fill-button,
.input-wrap input[type="password"]::-webkit-credentials-auto-fill-button,
.input-wrap input[type="password"]::-webkit-strong-password-auto-fill-button {
    visibility: hidden;
    pointer-events: none;
    width: 0;
    margin: 0;
}

.show-password-label {
    position: absolute;
    right: 0.75rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
    background: none;
    border: none;
}

.password-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #44506b;
    opacity: 0.9;
    transition: opacity 0.25s, color 0.25s, box-shadow 0.25s, background-color 0.25s;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 999px;
    background: rgba(29, 78, 216, 0.08);
    border: 1px solid rgba(29, 78, 216, 0.45);
    box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.4);
}

.show-password-label:hover .password-icon {
    opacity: 1;
    color: #44506b;
    background: rgba(14, 25, 55, 0.43);
    box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.55), 0 0 10px rgba(29, 78, 216, 0.28);
}

.show-password-toggle:checked + .password-icon {
    color: #cfe0ff;
    background: rgba(14, 25, 55, 0.5);
    border-color: rgba(29, 78, 216, 0.85);
    box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.62), 0 0 12px rgba(29, 78, 216, 0.26);
}

.show-password-toggle {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 1px;
    height: 1px;
}

.subscribe-preferences {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 1rem 0;
    text-align: left;
}

.subscribe-preferences label {
    display: flex;
    align-items: center;
    cursor: pointer;
    color: #44506b;
    font-size: 0.95rem;
}

.subscribe-preferences input[type="checkbox"] {
    margin-right: 0.75rem;
    cursor: pointer;
    width: 18px;
    height: 18px;
    accent-color: #1d4ed8;
}

.subscribe-form .btn-submit {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
    border: none;
    padding: 0.9rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 5px;
    cursor: pointer;
    transition: transform 0.3s;
    margin-top: 0.5rem;
}

.subscribe-form .btn-submit:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.3);
}

/* Navigation Sign In Button */
.nav-sign-in-btn,
.nav-sign-up-btn,
.nav-profile-btn {
    background: #ffffff;
    color: #0f2a6e;
    border: none;
    padding: 0.6rem 1.2rem;
    font-size: 0.9rem;
    font-weight: 600;
    border-radius: 25px;
    cursor: pointer;
    transition: transform 0.3s, box-shadow 0.3s;
    font-family: 'Poppins', sans-serif;
}

#signInMenuItem,
#signUpMenuItem,
#profileMenuItem {
    position: static !important;
    transform: none !important;
    left: auto !important;
    margin: 0 !important;
}

.nav-sign-in-btn:hover,
.nav-sign-up-btn:hover,
.nav-profile-btn:hover {
    transform: scale(1.05);
    background: #cfe0ff;
    box-shadow: 0 5px 15px rgba(15, 42, 110, 0.35);
}

/* Profile Info */
.profile-info {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem 0;
    color: #44506b;
}

.profile-info p {
    margin: 0;
    font-size: 0.95rem;
}

.profile-info strong {
    color: #1d4ed8;
}

.profile-preferences {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 2px solid #1d4ed8;
}

.profile-preferences h3 {
    color: #1d4ed8;
    margin: 0 0 0.75rem 0;
    font-size: 1rem;
}

.profile-preferences label {
    display: flex;
    align-items: center;
    cursor: pointer;
    color: #44506b;
    margin-bottom: 0.75rem;
    font-size: 0.95rem;
}

.profile-preferences input[type="checkbox"] {
    margin-right: 0.75rem;
    cursor: pointer;
    width: 18px;
    height: 18px;
    accent-color: #1d4ed8;
}

/* Profile Modal - Redesigned */
.profile-modal-content {
    max-width: 700px !important;
    width: 90% !important;
    max-height: 85vh !important;
}

.profile-section {
    margin-bottom: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.profile-section:last-of-type {
    margin-bottom: 1.5rem;
}

.profile-section h3 {
    color: #0f2a6e;
    font-size: 1.3rem;
    font-weight: 600;
    margin: 0;
    padding-bottom: 1rem;
    border-bottom: 2px solid #1d4ed8;
}

.profile-info-card {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.3);
    display: flex;
    flex-direction: column;
    gap: 1.2rem;
}

.profile-field {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 0;
    border-bottom: 1px solid rgba(29, 78, 216, 0.15);
}

.profile-field:last-child {
    border-bottom: none;
}

.profile-label {
    color: #1d4ed8;
    font-weight: 600;
    font-size: 0.95rem;
}

.profile-value {
    color: #44506b;
    font-size: 0.95rem;
    text-align: right;
}

.profile-verification-field {
    align-items: center;
}

.profile-verification-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-weight: 700;
}

.profile-verification-status.verified {
    color: #4caf50;
}

.profile-verification-status.unverified {
    color: #c62828;
}

/*
    The tick beside "Verified" is drawn as a plain glyph: no pill, no border, no
    fill. The badge it replaced read as a status chip competing with the word
    next to it, when all it needs to do is mark the word.
*/
.verification-checkmark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1;
}

.profile-verification-status.verified .verification-checkmark {
    color: #2e7d32;
}

.profile-verification-status.unverified .verification-checkmark {
    color: #c62828;
}

.profile-verification-actions {
    margin-top: 0.7rem;
}

/*
    The "please verify your email" panel shown once after sign-up.

    Centred and narrow on purpose: it carries one instruction and the steps to
    carry it out, so there is nothing to scan sideways for. The numbered list is
    left-aligned even though the heading is centred, because steps are read in
    order and a centred list gives every line a different starting point.
*/
.verify-prompt-content {
    max-width: 480px;
    width: 100%;
    text-align: center;
    border-color: #1d4ed8;
}

.verify-prompt-mark {
    font-size: 2.4rem;
    line-height: 1;
    color: #1d4ed8;
    margin-bottom: 0.6rem;
}

.verify-prompt-title {
    color: #0f2a6e;
    font-size: 1.5rem;
    margin-bottom: 0.7rem;
}

.verify-prompt-lead {
    color: #44506b;
    font-size: 0.98rem;
    line-height: 1.6;
    margin-bottom: 1.3rem;
}

/* Only one of the two leads is shown at a time. */
.verify-prompt-lead[hidden] {
    display: none;
}

.verify-prompt-lead strong {
    color: #0f2a6e;
    word-break: break-word;
}

.verify-prompt-steps {
    text-align: left;
    margin: 0 0 1.2rem;
    padding: 1rem 1.1rem 1rem 2.2rem;
    border: 1px solid #dde3ee;
    border-radius: 10px;
    background: #f5f7fb;
    color: #16203a;
    font-size: 0.94rem;
    line-height: 1.55;
}

.verify-prompt-steps li + li {
    margin-top: 0.55rem;
}

.verify-prompt-steps strong {
    color: #1d4ed8;
}

.verify-prompt-note {
    color: #64708c;
    font-size: 0.86rem;
    line-height: 1.55;
    margin-bottom: 0.4rem;
}

.verify-prompt-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1.1rem;
}

/* The resend sits beside "Got it" as the second choice, so it is outlined rather
   than filled: asking for another link is the thing to do only when the first
   one never arrived. */
.verify-prompt-resend {
    background: #ffffff;
    color: #1d4ed8;
    border: 1px solid #1d4ed8;
}

.verify-prompt-resend:hover:not(:disabled) {
    background: #eef3ff;
}

/* The wait between verification emails, shown wherever one can be asked for.
   Kept quiet: it is a clock, not a warning, and it disappears when it runs out. */
.verify-countdown {
    margin: 0.45rem 0 0;
    color: #64708c;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.5;
}

.verify-countdown[hidden] {
    display: none;
}

/* A resend control counting down reads as "not yet", not as "broken". */
#resendVerificationBtn:disabled,
#profileVerifyAgainBtn:disabled,
#verifyPromptResendBtn:disabled {
    cursor: default;
    opacity: 0.65;
}

.profile-verification-actions .verify-countdown {
    text-align: left;
}

@media (max-width: 480px) {
    .verify-prompt-content {
        padding: 1.6rem 1.2rem;
    }

    .verify-prompt-title {
        font-size: 1.28rem;
    }
}

.profile-value.streaming-active {
    color: #4caf50;
    font-weight: 600;
}

.profile-value.verified-name {
    color: #1d4ed8;
    font-weight: 700;
}

.profile-value.streaming-active.verified-name,
.profile-value.streaming-inactive.verified-name {
    color: #1d4ed8;
}

.profile-value.role-moderator-name,
.profile-value.streaming-active.role-moderator-name,
.profile-value.streaming-inactive.role-moderator-name,
.profile-value.verified-name.role-moderator-name {
    color: #1d4ed8;
}

.profile-value.role-admin-name,
.profile-value.streaming-active.role-admin-name,
.profile-value.streaming-inactive.role-admin-name,
.profile-value.verified-name.role-admin-name {
    color: #ff9800;
}

.profile-value.streaming-inactive {
    color: #ff0000;
    font-weight: 600;
}

.preferences-card {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.3);
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.preference-checkbox {
    display: flex;
    align-items: center;
    cursor: pointer;
    padding: 0.75rem;
    border-radius: 5px;
    transition: background-color 0.3s;
}

.preference-checkbox:hover {
    background-color: rgba(29, 78, 216, 0.1);
}

.preference-checkbox input[type="checkbox"] {
    margin-right: 0.75rem;
    cursor: pointer;
    width: 20px;
    height: 20px;
    accent-color: #1d4ed8;
}

.checkbox-label {
    color: #44506b;
    font-size: 0.95rem;
    font-weight: 500;
}

.btn-update-prefs {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
    border: none;
    padding: 0.8rem 1.5rem;
    font-size: 0.95rem;
    font-weight: 600;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s;
    margin-top: 0.5rem;
    font-family: 'Poppins', sans-serif;
}

.btn-update-prefs:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.4);
}

.profile-actions {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 2px solid #1d4ed8;
    display: flex;
    justify-content: center;
    gap: 0.85rem;
    flex-wrap: wrap;
}

.btn-sign-out {
    background: linear-gradient(135deg, #ff6b6b 0%, #ff5252 100%);
    color: #ffffff;
    border: none;
    padding: 0.8rem 2rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s;
    font-family: 'Poppins', sans-serif;
}

.btn-sign-out:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4);
}

.btn-delete-account {
    background: linear-gradient(135deg, #fdecec 0%, #fdecec 100%);
    color: #c62828;
    border: 1px solid rgba(255, 107, 107, 0.45);
    padding: 0.8rem 1.35rem;
    font-size: 0.95rem;
    font-weight: 600;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s;
    font-family: 'Poppins', sans-serif;
}

.btn-delete-account:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(255, 82, 82, 0.35);
}

.admin-panel-modal-content {
    max-width: 1040px !important;
    width: 94% !important;
}

.admin-panel-note {
    margin: 0 0 1rem;
    color: #0f2a6e;
    font-size: 0.95rem;
}

.admin-panel-actions {
    display: flex;
    align-items: stretch;
    gap: 0.85rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

/* Keep all admin panel action buttons the same size. */
.admin-panel-actions .btn-update-prefs,
.admin-panel-actions .btn-sign-out {
    padding: 0.8rem 1.5rem;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.2;
    border-radius: 5px;
    margin-top: 0.5rem;
    min-width: 170px;
    text-align: center;
}

.admin-users-summary {
    color: #0f2a6e;
    font-weight: 700;
    margin-bottom: 0.8rem;
}

.admin-danger-zone {
    margin-top: 2rem;
    padding-top: 1.2rem;
    border-top: 1px solid rgba(29, 78, 216, 0.3);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.admin-danger-link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-size: 0.95rem;
    color: #c62828;
    text-decoration: underline;
    cursor: pointer;
    align-self: flex-start;
}

.admin-danger-link:hover,
.admin-danger-link:focus-visible {
    color: #c62828;
}

.admin-danger-hint {
    color: #64708c;
    font-size: 0.82rem;
}

.admin-users-table-wrap {
    max-height: 52vh;
    overflow: auto;
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 8px;
}

#accountPortalSection[hidden],
#portalTabs[hidden],
.btn-account-portal[hidden],
.account-portal-tab[hidden],
.business-account-badge[hidden] {
    display: none !important;
}

.admin-users-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 980px;
}

.admin-users-table th,
.admin-users-table td {
    border-bottom: 1px solid rgba(29, 78, 216, 0.2);
    padding: 0.7rem 0.6rem;
    text-align: left;
    font-size: 0.86rem;
    color: #44506b;
    vertical-align: top;
}

.admin-users-table th {
    position: sticky;
    top: 0;
    background: #ffffff;
    color: #0f2a6e;
    z-index: 1;
}

.admin-users-table tbody tr:nth-child(odd) {
    background: rgba(29, 78, 216, 0.06);
}

/* Per-row admin controls: open a member's account, or remove it. */
.admin-row-actions {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    align-items: flex-start;
}

.admin-account-type {
    display: inline-flex;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    color: #44506b;
    background: rgba(22, 32, 58, 0.04);
    border: 1px solid rgba(22, 32, 58, 0.12);
    font-size: 0.78rem;
    font-weight: 600;
}

.admin-account-type.is-business {
    color: #2e7d32;
    background: rgba(33, 150, 83, 0.14);
    border-color: rgba(78, 194, 117, 0.45);
}

/* Staff roles read at a glance: admin is red, moderator is blue and sales is
   amber. Distinct colours keep different access levels easy to scan. */
.admin-account-type.is-admin {
    color: #c62828;
    background: rgba(214, 48, 49, 0.18);
    border-color: rgba(255, 107, 107, 0.55);
}

.admin-account-type.is-moderator {
    color: #1d4ed8;
    background: rgba(29, 78, 216, 0.18);
    border-color: rgba(29, 78, 216, 0.55);
}

.admin-account-type.is-sales {
    color: #8a4b08;
    background: rgba(217, 139, 32, 0.17);
    border-color: rgba(184, 106, 18, 0.5);
}

.admin-account-type.is-dj {
    color: #6b21a8;
    background: rgba(147, 51, 234, 0.15);
    border-color: rgba(126, 34, 206, 0.5);
}

/* ==========================================================================
   Role picker in the admin user list

   Roles are set from the row that already names the person, so the control is a
   small "+" sitting against their name rather than a separate form elsewhere on
   the page. The menu is absolutely positioned and lifted above the table so it
   is never clipped by a row's own height.
   ========================================================================== */

.admin-name-cell {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.admin-name-owner {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #1d4ed8;
    border: 1px solid rgba(29, 78, 216, 0.45);
    border-radius: 999px;
    padding: 0.05rem 0.4rem;
    white-space: nowrap;
}

.admin-role-picker {
    position: relative;
    flex-shrink: 0;
}

.btn-role-menu {
    width: 1.4rem;
    height: 1.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(29, 78, 216, 0.5);
    background: rgba(29, 78, 216, 0.12);
    color: #0f2a6e;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.18s ease, transform 0.18s ease;
}

.btn-role-menu:hover,
.btn-role-menu:focus-visible {
    background: #1d4ed8;
    color: #ffffff;
    transform: scale(1.08);
}

.admin-role-picker.is-open .btn-role-menu {
    background: #1d4ed8;
    color: #ffffff;
}

.admin-role-menu {
    position: absolute;
    top: calc(100% + 0.35rem);
    left: 0;
    z-index: 40;
    min-width: 15rem;
    padding: 0.5rem;
    text-align: left;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.45);
    border-radius: 8px;
    box-shadow: 0 14px 30px rgba(16, 26, 56, 0.55);
}

.admin-role-menu[hidden] {
    display: none;
}

.admin-role-picker.drops-up .admin-role-menu {
    top: auto;
    bottom: calc(100% + 0.35rem);
}

.admin-role-menu-name {
    margin: 0 0 0.35rem;
    color: #44506b;
    font-size: 0.85rem;
    font-weight: 700;
    white-space: normal;
}

.admin-role-menu-label {
    margin: 0.45rem 0 0.25rem;
    color: #64708c;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.admin-role-option {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.4rem 0.5rem;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: #44506b;
    font-family: 'Poppins', sans-serif;
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.admin-role-option:hover,
.admin-role-option:focus-visible {
    background: rgba(29, 78, 216, 0.18);
}

.admin-role-option.is-active {
    color: #0f2a6e;
    font-weight: 600;
    cursor: default;
}

.admin-role-option:disabled {
    cursor: wait;
    opacity: 0.6;
}

.admin-role-check {
    width: 0.9rem;
    flex-shrink: 0;
    color: #1d4ed8;
    font-weight: 700;
}

.btn-open-user-account {
    background: linear-gradient(135deg, #eaf0ff 0%, #eaf0ff 100%);
    color: #0f2a6e;
    border: 1px solid rgba(29, 78, 216, 0.5);
    padding: 0.45rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 600;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.25s;
    font-family: 'Poppins', sans-serif;
    white-space: nowrap;
}

.btn-open-user-account:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(29, 78, 216, 0.3);
}

.admin-users-table .btn-delete-account {
    padding: 0.45rem 0.85rem;
    font-size: 0.8rem;
}

/* Card details are shown the way a statement shows them: brand, last four
   digits and expiry. The full number and CVV are never rendered. */
.admin-billing-cell {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.admin-card-number {
    color: #0f2a6e;
    font-weight: 600;
    letter-spacing: 0.05em;
    white-space: nowrap;
}

.admin-card-meta {
    color: #44506b;
    font-size: 0.78rem;
}

.admin-billing-empty {
    color: #64708c;
    font-size: 0.82rem;
}

/* Banner shown while an admin is inside a member's account. */
.admin-impersonation-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20000;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.6rem 1rem;
    background: linear-gradient(135deg, #eaf0ff 0%, #eaf0ff 100%);
    border-bottom: 2px solid #1d4ed8;
    color: #0f2a6e;
    font-family: 'Poppins', sans-serif;
    font-size: 0.9rem;
    box-shadow: 0 4px 18px rgba(16, 26, 56, 0.45);
}

.admin-impersonation-text strong {
    color: #0f2a6e;
}

.admin-impersonation-exit {
    background: #3b6ff2;
    color: #ffffff;
    border: none;
    padding: 0.4rem 0.95rem;
    border-radius: 4px;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    font-family: 'Poppins', sans-serif;
}

.admin-impersonation-exit:hover {
    background: #eaf0ff;
}

body.admin-impersonating {
    padding-top: 46px;
}

/* Contract and subscription plan PDFs. */
.admin-documents-section {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(29, 78, 216, 0.3);
}

.admin-document-form {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    background: rgba(29, 78, 216, 0.04);
    padding: 1rem;
    border-radius: 6px;
    margin-bottom: 1rem;
}

.admin-document-form input[type="text"],
.admin-document-form input[type="file"] {
    padding: 0.6rem;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.4);
    color: #44506b;
    border-radius: 4px;
    font-family: 'Poppins', sans-serif;
}

.admin-document-form-row {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.admin-document-form-row .admin-plan-select {
    flex: 1 1 200px;
}

.admin-documents-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-height: 30vh;
    overflow-y: auto;
}

.admin-document-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    background: rgba(29, 78, 216, 0.04);
    border-left: 3px solid #1d4ed8;
    border-radius: 4px;
    padding: 0.8rem;
}

.admin-document-details {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.admin-document-details strong {
    color: #0f2a6e;
}

.admin-document-meta {
    color: #44506b;
    font-size: 0.8rem;
}

.admin-document-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.btn-document-view {
    background: linear-gradient(135deg, #eaf0ff 0%, #eaf0ff 100%);
    color: #0f2a6e;
    border: 1px solid rgba(29, 78, 216, 0.5);
    padding: 0.4rem 0.9rem;
    border-radius: 4px;
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

.btn-document-view:hover {
    box-shadow: 0 4px 12px rgba(29, 78, 216, 0.3);
}

.btn-delete-document {
    background: #ff6b6b;
    color: #ffffff;
    border: none;
    padding: 0.4rem 0.8rem;
    border-radius: 4px;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    font-family: 'Poppins', sans-serif;
}

.admin-documents-empty {
    color: #64708c;
    margin: 0;
    font-size: 0.9rem;
}

/* ============================================================
   Sponsor strip - the advertisement logos an admin publishes.

   The brief was explicit that this must not turn the site into a
   race track wall of logos, so the restraint is in the CSS as
   much as in the six-logo cap on the server:

     - One band per page, sharing the same panel background and
       width as every other section, so it reads as part of the
       page rather than as an advert rail bolted to it.
     - Every logo gets an identical tile and is scaled to fit
       inside it. Mixed logo sizes are what makes a sponsor row
       look like hoardings; a fixed tile makes six unrelated
       logos read as one deliberate row.
     - The tiles are light because the site is dark and sponsor
       artwork is usually black on transparent. Without the tile
       half the logos would be invisible.
     - Muted until hovered. At rest the strip is quiet and the
       page's own content keeps the attention; pointing at a logo
       brings it fully forward.

   The section itself ships with [hidden] and sponsors.js only
   removes it once there is something to show, so a site with no
   sponsors has no empty band. The !important follows the same
   convention as the rules above it - the section padding here
   would otherwise beat the browser's own [hidden] rule.
   ============================================================ */

.sponsor-board[hidden] {
    display: none !important;
}

.sponsor-board {
    padding: 2.5rem 2rem;
}

/* The strip sits directly under the header, above the hero, so it is the first
   thing below the menu. That position has to be earned quietly: a full-height
   section there would push the page's own opening out of view and read as the
   site's headline. So near the top it becomes a band rather than a section -
   less air around it, shorter tiles, and a hairline underneath to separate it
   from the page proper. */
.sponsor-board-top {
    /* Air underneath as well as the hairline: the box below it is edged and
       shadowed now, and a strip pressed against that edge reads as part of it.
       Hidden boards are display:none above, so an empty strip leaves no gap. */
    margin-bottom: 2rem;
    padding: 1.25rem 2rem 1.1rem;
    border-bottom: 1px solid rgba(29, 78, 216, 0.15);
}

.sponsor-board-top .sponsor-board-title {
    margin-bottom: 0.9rem;
}

.sponsor-board-top .sponsor-item {
    --sponsor-basis: 160px;
    --sponsor-basis-max: 240px;
}

.sponsor-board-top .sponsor-tile {
    --sponsor-height: 84px;
}

/*
    The side rails: a column of square sponsor spots down the white margins at
    the left and right of the page.

    This is the answer to "put the ads in the empty space either side of the
    site". The rails are fixed rather than sticky because they belong to the
    window, not to any one section - an ad at the side of the page should be
    beside whatever the reader has scrolled to.

    Three rules hold the whole thing together:

      - A rail never costs the page any width. The content column is 1200px, so
        the rails only appear once the window is wide enough to hold that column
        plus two rails plus air, and below that they are simply not displayed.
        That is why the default here is `display: none` and the media query turns
        them on rather than the other way round: a breakpoint nobody remembers
        would otherwise leave a rail lying across the text.

      - The panel belongs to each square, not to the rail. An empty square ships
        `hidden` like every other slot, so a rail nobody has put a sponsor in
        draws nothing at all, rather than an empty white box waiting in the
        margin.

      - Every rail spot is a square, whatever shape the artwork is. A rail is a
        column of equal boxes and one tall logo would push the rest off the
        screen; a square is also a predictable canvas, which is what is being
        sold here.
*/
.sponsor-rail {
    display: none;
}

/*
    Where the rails go, and the room the page gives up for them.

    This used to be measured by sponsors.js on every load: it found the widest
    content box, squeezed a rail into whatever margin that left, and counted how
    many squares the page was tall enough for. Every one of those numbers moved
    with whatever had finished loading, so a rail could land on top of a panel
    and a logo could be in a different square, or hidden, on the next reload.

    Now it is fixed geometry, decided by the window's width alone. Above the
    breakpoint each rail is a column of a set width at the window's edge, and
    the body is padded by exactly the rail plus the air either side of it, so
    everything between them - sections, panels, the page's own wrappers - is
    laid out in what is left and cannot run under a rail. The header and footer
    keep the full width with negative margins: the rails start under the one
    and the footer is pushed below the other (`--rail-clearance`, written by
    sponsors.js only when a short page would otherwise meet them).

    The rails are drawn on phones and tablets too, not just on wide screens:
    under 1100px the columns and the air around them slim down (see the
    narrow-screen block below) and the page between them narrows with them,
    so a sponsor down the side of the page is seen on every device. Only a
    window under 300px, where there is no page left to narrow, falls back to
    the stacked layout. Pages without rails (the account portal, the public
    file) match none of this and keep their full width. Keep the 300px floor in
    step with RAIL_QUERY in sponsors.js.
*/
:root {
    --rail-width: clamp(112px, 8vw, 150px);
    --rail-edge: 12px;
    --rail-gap: 16px;
    --rail-space: calc(var(--rail-width) + var(--rail-edge) + var(--rail-gap));
}

@media (max-width: 1099.98px) {
    :root {
        --rail-width: clamp(44px, 11vw, 112px);
        --rail-edge: 4px;
        --rail-gap: 8px;
    }
}

@media (min-width: 300px) {
    body:has(> .sponsor-rail) {
        padding-left: var(--rail-space);
        padding-right: var(--rail-space);
    }

    body:has(> .sponsor-rail) > header,
    body:has(> .sponsor-rail) > footer {
        margin-left: calc(-1 * var(--rail-space));
        margin-right: calc(-1 * var(--rail-space));
    }

    body:has(> .sponsor-rail) > footer {
        margin-top: calc(4rem + var(--rail-clearance, 0px));
    }

    .sponsor-rail.is-railed {
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        /*
            Absolute, against the document rather than the window: the rails
            are part of the page and scroll away with it rather than following
            the reader down every article. They start under the header -
            sponsors.js writes where that ends as `--rail-top`, and 13rem is
            the fallback, larger than any of the headers so never an overlap.
            The squares stack from the top at their own size, so a square is
            in the same place whatever the length of the page.
        */
        position: absolute;
        top: var(--rail-top, 13rem);
        width: var(--rail-width);
        /* Over the page, under the header and any modal. */
        z-index: 5;
    }

    .sponsor-rail-left.is-railed {
        left: var(--rail-edge);
    }

    .sponsor-rail-right.is-railed {
        right: var(--rail-edge);
    }
}

/*
    When the measuring says there is no margin to put a rail in - a narrow
    window, or a page whose content runs the full width of it - a moderator
    still has to be able to put a logo in one, and being told "sign in on a
    bigger screen" is not an answer.

    So for staff only, and only while the margins are not being drawn, the side
    spots fold into two labelled groups in the flow of the page. They are the
    same slots doing the same thing: pressing one opens the same picker and the
    same upload form. `:has` is what keeps this staff-only - the class it looks
    for is the one the overlay adds when somebody signs in - so a visitor on a
    laptop still sees nothing of it.

    Kept small deliberately. This is a way in to the side spots, not a copy of
    all forty-eight of them: sponsors.js drops the empty ones behind the first
    free spot (see `is-spare` below) and, while the rails are not being drawn,
    sends what is already placed into the bands in the page instead - so an
    advertiser's logo is in the page where people read it rather than in a pile
    at the foot of it.
*/
.sponsor-rail.is-stacked:has(.sponsor-slot.is-admin) {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    max-width: 1200px;
    /* Air above as well as below: sponsors.js lifts this block to just under
       the header while the margins are not being drawn, and pressed against
       that blue bar it would read as part of the navigation. */
    margin: 1.5rem auto;
    padding: 0 2rem;
}

.sponsor-rail.is-stacked:has(.sponsor-slot.is-admin)::before {
    flex: 1 0 100%;
    color: rgba(29, 78, 216, 0.8);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-align: center;
}

.sponsor-rail-left.is-stacked:has(.sponsor-slot.is-admin)::before {
    content: "Left side spots \2014 in the margin on a wide screen, in the page on this one";
}

.sponsor-rail-right.is-stacked:has(.sponsor-slot.is-admin)::before {
    content: "Right side spots \2014 in the margin on a wide screen, in the page on this one";
}

/* Side by side at the size they are in a rail, rather than stretched across
   the page: these stand in for a square in the margin, so they should look
   like one. */
.sponsor-rail.is-stacked:has(.sponsor-slot.is-admin) .sponsor-rail-slot {
    flex: 0 0 auto;
    width: 150px;
}

/*
    A page whose only sponsor spots are its margins, on a window with no margins
    to draw - the obituaries page on a laptop.

    There is no band on such a page to move a logo into, so the stacked block is
    the only place it can be drawn, and a sponsor is owed more than being drawn
    for staff alone. So a stacked rail with something actually in it is shown to
    everybody. Only the logos: the empty squares stay hidden as they do on every
    page, and the labelled heading above them is still `is-admin` only, so a
    visitor sees a row of sponsors under the header rather than editing
    furniture.
*/
.sponsor-rail.is-stacked:has(.sponsor-slot[data-sponsor-filled]) {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    max-width: 1200px;
    margin: 1.5rem auto;
    padding: 0 2rem;
}

.sponsor-rail.is-stacked:has(.sponsor-slot[data-sponsor-filled]) .sponsor-rail-slot {
    flex: 0 0 auto;
    width: 150px;
}

/*
    An empty side spot with another empty one ahead of it in the queue.

    Twenty-four squares a side is a wall of dashed boxes, in a margin or folded
    into the page, and all but the first empty one say the same thing.
    sponsors.js marks the ones behind the first free spot and they come out, so
    what is left here is whatever has been placed plus the next spot to fill.
*/
.sponsor-rail .sponsor-rail-slot.is-spare {
    /* Important because the admin empty-square rule below shows every empty
       square, and a spare one is exactly an empty square to leave out. */
    display: none !important;
}


/*
    One rail spot. These are `section` elements like every other slot, so they
    arrive with the site's 1200px section width and its 2rem of section padding;
    in a 172px rail that would be all padding and no logo, so both go.
*/
.sponsor-rail-slot {
    max-width: none;
    margin: 0;
    padding: 0;
}

.sponsor-rail-slot .sponsor-board-title {
    margin-bottom: 0.4rem;
    font-size: 0.62rem;
    letter-spacing: 0.1em;
}

/* A column of squares, not a row sharing a width between tiles. */
.sponsor-rail-slot .sponsor-list {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0.6rem;
}

.sponsor-rail-slot .sponsor-item {
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
}

.sponsor-rail-slot .sponsor-tile {
    /* The square, in place of the shape the artwork would otherwise impose.
       The logo still scales to fit inside it, so nothing is cropped by this. */
    aspect-ratio: 1 / 1;
    min-height: 0;
    max-height: none;
    /* Thin rails, so the tile gives its room to the logo rather than to air. */
    padding: 0.4rem;
    /* White rather than the page's grey: a rail sits on the page background
       itself, so its tiles need their own edge to read as cards. */
    background: #ffffff;
    box-shadow: 0 6px 18px rgba(22, 32, 58, 0.08);
}

/* A cropped logo fills its tile, and the padding above would leave it stopping
   short of the border it was cropped to. Restated here because the rule that
   drops the padding for a crop is less specific than the rail's own. */
.sponsor-rail-slot .sponsor-tile.sponsor-tile-cover {
    padding: 0;
}

/*
    The admin furniture is laid out for a full-width strip, so in a rail it runs
    down the column instead and is let off the widths that would otherwise push
    a rail wider than its gutter.
*/
.sponsor-rail .sponsor-slot-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 0.35rem;
}

/*
    An empty rail spot - the thing a moderator or an admin actually clicks.

    A dashed square exactly where the logo would land, with the whole square as
    the button, because "click the square to put an ad in it" is the entire
    instruction this has to carry. The generic empty-slot box is unpicked here
    so the square itself is the only frame.
*/
/* Square, whatever height the rail has been given to spread them over. */
.sponsor-rail.is-railed .sponsor-rail-slot {
    flex: 0 0 auto;
}

.sponsor-rail .sponsor-rail-slot.is-admin.is-empty {
    display: flex;
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 0;
    background: none;
}

/*
    The weather band: directly under Our News on the front page, the full width
    of the column and edged like the boxes around it.

    Before the frame reports its height the band shows the plain link it was
    built around, which is also what a visitor with no JavaScript gets and what
    is left if the frame never answers.
*/
.weather-band {
    position: relative;
    margin: 0 auto 3.5rem;
    padding: 1.25rem 1.5rem;
    min-height: 160px;
    overflow: hidden;
    border-radius: 22px;
    background: linear-gradient(135deg, #12307f 0%, #2a5be0 100%);
    color: white;
    box-shadow: 0 22px 50px rgba(10, 27, 68, 0.26);
}

.weather-band.is-loaded {
    min-height: 0;
}

/*
    Kept rendering rather than hidden while it loads: a frame that is display:
    none never lays out, so it would never measure itself and never report the
    height this band is sized by.
*/
.weather-band-frame {
    position: absolute;
    inset: 1.25rem 1.5rem;
    display: block;
    width: calc(100% - 3rem);
    height: 120px;
    border: 0;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.weather-band.is-loaded .weather-band-frame {
    position: static;
    width: 100%;
    opacity: 1;
}

.weather-band-link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    color: #e4edff;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
}

.weather-band-link:hover,
.weather-band-link:focus-visible {
    color: #ffffff;
    text-decoration: underline;
}

.weather-band.is-loaded .weather-band-link {
    display: none;
}

@media (max-width: 768px) {
    .weather-band {
        padding: 1rem 0.75rem;
        border-radius: 16px;
    }

    .weather-band-frame {
        inset: 1rem 0.75rem;
        width: calc(100% - 1.5rem);
    }
}

@media (prefers-reduced-motion: reduce) {
    .weather-band-frame {
        transition: none;
    }
}

.sponsor-rail .sponsor-rail-slot.is-admin.is-empty .sponsor-slot-bar {
    flex: 1 1 auto;
    margin: 0;
}

.sponsor-slot-add.sponsor-slot-add-square {
    flex: 1 1 auto;
    flex-direction: column;
    justify-content: center;
    gap: 0.2rem;
    padding: 0.35rem;
    border: 1px dashed rgba(29, 78, 216, 0.55);
    border-radius: 12px;
    /* Quiet until it is pointed at. These are visible to staff only, but they
       are still sitting beside the page's own content. */
    background: rgba(255, 255, 255, 0.92);
    color: #1d4ed8;
    font-size: 0.6rem;
    line-height: 1.25;
    text-align: center;
    white-space: normal;
}

.sponsor-slot-add.sponsor-slot-add-square .sponsor-slot-add-plus {
    font-size: 1.6rem;
    line-height: 1;
}

.sponsor-slot-add.sponsor-slot-add-square:hover,
.sponsor-slot-add.sponsor-slot-add-square:focus-visible {
    /* A square that lifts would leave the column; it brightens instead. */
    transform: none;
    border-style: solid;
    background: rgba(29, 78, 216, 0.08);
    box-shadow: 0 6px 18px rgba(29, 78, 216, 0.18);
}

/* A rail spot that already has a logo in it still offers the + , but as a pill
   across the bottom of the square rather than a second square. */
.sponsor-slot-add.sponsor-slot-add-compact {
    justify-content: center;
    padding: 0.25rem 0.5rem;
    font-size: 0.68rem;
}

/*
    The picker is a panel with a list of logos in it, and in a 172px rail it
    would be a column of single letters. So in a rail it is taken out of the flow
    and opened sideways, towards the middle of the page where there is room.

    It is anchored to the rail rather than to the square that opened it - the
    rail is already centred in the window, so a panel pinned to its top cannot
    end up off-screen above or below whichever square was clicked. That is what
    the `position: static` is for: the slot is relative while an admin is signed
    in, and would otherwise be the thing the panel measures from.

    The rail scrolls its own overflow, which would clip a panel hanging outside
    it, so it stops doing that while a picker is open. `is-open` is not needed:
    `:has` asks the same question of the markup that is already there.
*/
.sponsor-rail .sponsor-rail-slot.is-admin {
    position: static;
}

.sponsor-rail .sponsor-slot-picker {
    position: absolute;
    top: 0;
    /* Opened sideways into the page, where there is room: a 320px panel does
       not fit in a 100px rail, and the rail is thinner than the panel at every
       width. */
    width: min(320px, 46vw);
    max-width: none;
    max-height: 82vh;
    margin: 0;
    overflow-y: auto;
}

.sponsor-rail-left .sponsor-slot-picker {
    left: calc(100% + 0.75rem);
}

.sponsor-rail-right .sponsor-slot-picker {
    right: calc(100% + 0.75rem);
}

/*
    The rails on a phone or tablet.

    The same squares in the same order, only slimmer, so the furniture around
    each logo gives way first: the "Sponsored" label and most of the tile's
    padding go, the admin buttons shrink to their "+", and the weather card -
    unreadable in a column this thin - is left out below 900px. The page
    between the rails loses some of its own side padding in return, so the
    narrowed column still has room for its text.
*/
@media (max-width: 1099.98px) {
    .sponsor-rail.is-railed {
        gap: 0.5rem;
    }

    .sponsor-rail.is-railed .sponsor-rail-slot .sponsor-board-title {
        display: none;
    }

    .sponsor-rail.is-railed .sponsor-rail-slot .sponsor-tile {
        padding: 0.2rem;
        border-radius: 8px;
    }

    .sponsor-rail.is-railed .sponsor-rail-slot .sponsor-tile.sponsor-tile-cover {
        padding: 0;
    }
}

@media (max-width: 768px) {
    body:has(> .sponsor-rail) section:not(.sponsor-board) {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    .sponsor-rail.is-railed .sponsor-slot-add.sponsor-slot-add-square {
        padding: 0;
        border-radius: 8px;
    }

    .sponsor-rail.is-railed .sponsor-slot-add-square .sponsor-slot-add-where {
        display: none;
    }

    .sponsor-rail.is-railed .sponsor-slot-add.sponsor-slot-add-compact {
        padding: 0.15rem;
        /* Only the "+": "Add here" does not fit a 44px column. */
        font-size: 0;
    }

    .sponsor-rail.is-railed .sponsor-slot-add.sponsor-slot-add-compact span {
        font-size: 0.9rem;
    }
}

.sponsor-board-title {
    margin: 0 0 1.5rem;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #1d4ed8;
}

.sponsor-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.sponsor-item {
    display: flex;
    /*
        Grows to share the row evenly, but never past a width that would
        stretch two sponsors across the whole page.

        Both numbers come through custom properties so the places that give a
        strip smaller tiles - the band above the hero, an inline divider, a
        phone - set only the two widths and inherit the rest of this. They are
        then multiplied by the logo's own size setting, so a sponsor set larger
        takes more of the row and the ones beside it give way.
    */
    flex: 0 1 calc(var(--sponsor-basis, 160px) * var(--logo-scale, 1));
    max-width: calc(var(--sponsor-basis-max, 200px) * var(--logo-scale, 1));
    /*
        Tiles in a row are no longer all one height, so they hang from a common
        middle instead of being stretched to match the tallest. Without this the
        list's own stretch would override the shape worked out below.
    */
    align-items: center;
}

.sponsor-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    /*
        The tile takes the shape of the artwork in it rather than forcing every
        logo into the same letterbox. --logo-aspect is the uploaded image's own
        width and height, written inline by whatever draws the tile, so a square
        badge gets a square tile and the section below it moves down to make
        room. The fallback is the 16/9 this strip has always been, so a logo
        whose dimensions were never recorded looks exactly as it did.

        The two bounds stop that running away: a very tall image cannot push a
        whole section off the screen, and a very wide one still has a box to sit
        in. Both are worked out from the height this strip would have used
        anyway, and both scale with the logo's size setting, so raising the size
        raises the ceiling with it rather than hitting it sooner.
    */
    height: auto;
    aspect-ratio: var(--logo-aspect, 16 / 9);
    min-height: calc(var(--sponsor-height, 90px) * 0.7 * var(--logo-scale, 1));
    max-height: calc(var(--sponsor-height, 90px) * 2.2 * var(--logo-scale, 1));
    padding: 0.75rem 1rem;
    box-sizing: border-box;
    /* The frame a crop is cropped to: a zoomed logo is clipped by this box
       rather than spilling over its neighbours in the strip. */
    overflow: hidden;
    background: #f5f7fb;
    border: 1px solid rgba(29, 78, 216, 0.25);
    border-radius: 6px;
    text-decoration: none;
    /* Full strength at rest: a muted logo reads as blurry, and a sponsor's
       mark should be as clear as the page around it. */
    opacity: 1;
    transition: opacity 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

a.sponsor-tile:hover,
a.sponsor-tile:focus-visible {
    opacity: 1;
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(16, 26, 56, 0.35);
}

a.sponsor-tile:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

/* The width and height attributes on the image are there to reserve the row
   before the bitmap arrives; these override them so every logo is scaled into
   the same tile whatever its own proportions. */
/*
    The framing set in the crop editor, read from custom properties the tile
    builders write inline. Defaults here are "no crop", so a logo saved before
    the editor existed - or one an admin never reframed - draws exactly as it
    always did.

    Zoom scales about the focus point rather than the centre, which is what makes
    dragging the preview feel like moving the artwork under a fixed window.
*/
.sponsor-logo {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    object-position: var(--logo-focus-x, 50%) var(--logo-focus-y, 50%);
    transform: scale(var(--logo-zoom, 1));
    transform-origin: var(--logo-focus-x, 50%) var(--logo-focus-y, 50%);
}

/*
    "Cover" is what cropping means for artwork that is not a wordmark: fill the
    tile and let the edges go. It needs a real box to fill, so the intrinsic
    sizing above is dropped, and the tile's padding goes with it - a crop that
    stopped short of the border would not have filled anything.
*/
.sponsor-tile-cover {
    padding: 0;
}

.sponsor-logo-cover {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    object-fit: cover;
}

@media (max-width: 768px) {
    .sponsor-board {
        padding: 2rem 1.25rem;
    }

    .sponsor-item {
        --sponsor-basis: 130px;
        --sponsor-basis-max: 160px;
    }

    .sponsor-tile {
        --sponsor-height: 72px;
    }

    .sponsor-board-top {
        padding: 1rem 1.25rem 0.9rem;
    }

    .sponsor-board-top .sponsor-item {
        /* Two to a row on a phone. Six single-file logos above the hero would
           be a screen of advertising before the site said anything. */
        flex: 1 1 40%;
        max-width: none;
    }

    .sponsor-board-top .sponsor-tile {
        --sponsor-height: 58px;
    }
}

/* ============================================================
   Sponsor slots — the positions a logo can be placed in, and the
   editing furniture an admin sees over them.

   A slot is invisible to a visitor unless it has a logo in it. The
   outlined box, the label and the + button only exist while an
   admin is signed in, and they are drawn deliberately unlike
   content: a dashed gold outline and a small caps label, so nothing
   here could be mistaken for part of the page.
   ============================================================ */

/* A strip between two sections rather than at the top of the page. Lighter
   again than the top band: no heavy background, a hairline above and below so
   it reads as a divider that happens to carry logos, and small tiles. Between
   two cards on the inner pages the same treatment reads as a gap with logos in
   it, which is the intent in both places. */
.sponsor-board-inline {
    padding: 1.1rem 1.25rem;
    border-top: 1px solid rgba(29, 78, 216, 0.14);
    border-bottom: 1px solid rgba(29, 78, 216, 0.14);
}

/*
    A band between two blocks of an inner page, drawn the way the front page
    draws its own: a row straight across the page, hairline to hairline, with
    the logos centred in it.

    The front page's bands are sections of the page itself, so they run the full
    width of it. The inner pages carry their own column - 900px on the calendar
    and the listings, 980 on the jobs page, 960 on obituaries - and a band left
    inside one of those was drawn the width of the column, which read as another
    panel of the page rather than the strip the front page has in the same
    place. So the bands sit outside the column now, as children of the page's
    own `main`, and this is the air around them that the column's grid gap used
    to provide.
*/
main > .sponsor-board-inline {
    margin: 1.6rem 0;
}

.sponsor-board-inline .sponsor-board-title {
    margin-bottom: 0.75rem;
    font-size: 0.72rem;
    color: rgba(29, 78, 216, 0.75);
}

.sponsor-board-inline .sponsor-item {
    --sponsor-basis: 120px;
    --sponsor-basis-max: 150px;
}

.sponsor-board-inline .sponsor-tile {
    --sponsor-height: 60px;
}

/* --- Only from here down is admin-only furniture. --- */

.sponsor-slot.is-admin {
    position: relative;
}

/* An empty slot has nothing in it to give it a size, so the outline is what
   makes the position visible at all. Dashed rather than solid because it marks
   a space that is not yet anything. */
.sponsor-slot.is-admin.is-empty {
    padding: 0.75rem 1rem;
    border: 1px dashed rgba(29, 78, 216, 0.55);
    border-radius: 14px;
    background: rgba(29, 78, 216, 0.04);
}

.sponsor-slot-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem 0.75rem;
    margin-top: 0.6rem;
}

.sponsor-slot.is-empty .sponsor-slot-bar {
    /* Nothing above it in an empty slot, so the gap would be a stray indent. */
    margin-top: 0;
}

.sponsor-slot-name {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(29, 78, 216, 0.8);
}

/* The same gold gradient, black text and lift as every other button on the
   site, at the size a control sitting inside a layout can be. */
.sponsor-slot-add {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.85rem;
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    border: none;
    border-radius: 999px;
    color: #ffffff;
    font-family: 'Poppins', sans-serif;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
}

.sponsor-slot-add span {
    font-size: 1rem;
    line-height: 1;
}

.sponsor-slot-add:hover,
.sponsor-slot-add:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.4);
}

.sponsor-slot-add:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

/* The × on a placed logo. Kept off the tile itself and small, because it is a
   destructive control sitting on top of content an admin is looking at. */
.sponsor-item {
    position: relative;
}

.sponsor-item-remove {
    position: absolute;
    top: -0.45rem;
    right: -0.45rem;
    width: 1.35rem;
    height: 1.35rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.6);
    border-radius: 50%;
    color: #0f2a6e;
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
}

.sponsor-item-remove:hover,
.sponsor-item-remove:focus-visible {
    background: #ff6b6b;
    border-color: #ff6b6b;
    color: #16203a;
}

/* --- Picking a logo up and moving it. ---
   The handle mirrors the × on the other corner, and is deliberately the same
   size and shape: two small controls on one tile, one to move it and one to
   take it away. */
.sponsor-item-grab {
    position: absolute;
    top: -0.45rem;
    left: -0.45rem;
    width: 1.35rem;
    height: 1.35rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.6);
    border-radius: 50%;
    color: #0f2a6e;
    font-size: 0.7rem;
    line-height: 1;
    letter-spacing: -0.08em;
    cursor: grab;
    /* Without this a drag that starts on the handle scrolls the page on a touch
       screen instead of moving the logo. */
    touch-action: none;
}

.sponsor-item-grab:hover,
.sponsor-item-grab:focus-visible {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    border-color: #1d4ed8;
    color: #ffffff;
}

.sponsor-item-grab:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

/* The pencil that opens a placed logo's editor, on the corner below the ×, in
   the same small circle as the other two so the three read as one set. */
.sponsor-item-edit {
    position: absolute;
    bottom: -0.45rem;
    right: -0.45rem;
    width: 1.35rem;
    height: 1.35rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.6);
    border-radius: 50%;
    color: #0f2a6e;
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
}

.sponsor-item-edit:hover,
.sponsor-item-edit:focus-visible {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    border-color: #1d4ed8;
    color: #ffffff;
}

.sponsor-item-edit:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

/* --- Making a placed logo bigger or smaller. ---
   The pair sits under the tile rather than on it. The size being chosen is the
   size of the tile, so a control laid over the artwork would be covering the
   one thing the choice is being judged by. A pill rather than two loose
   circles, because the reading between them belongs to both. */
.sponsor-item-size {
    position: absolute;
    bottom: -0.6rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 0.1rem;
    padding: 0.1rem 0.2rem;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.6);
    border-radius: 999px;
    line-height: 1;
    white-space: nowrap;
}

.sponsor-item-size button {
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-radius: 50%;
    color: #0f2a6e;
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
}

.sponsor-item-size button:hover:not([disabled]),
.sponsor-item-size button:focus-visible {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
}

.sponsor-item-size button:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 1px;
}

/* At either end of the range, rather than hidden: a control that vanished
   would look like the logo had lost the ability to be resized. */
.sponsor-item-size button[disabled] {
    opacity: 0.35;
    cursor: default;
}

.sponsor-item-size-value {
    min-width: 2.3rem;
    text-align: center;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    color: #44506b;
}

/* The tile stays in the row while it is being dragged, faded, so the row does
   not collapse and re-lay-out under the pointer mid-move. */
.sponsor-item.is-dragging {
    opacity: 0.3;
}

/* The logo under the pointer. Fixed to the viewport and out of the way of
   hit-testing, so the slot underneath is what gets found. */
.sponsor-drag-ghost {
    position: fixed;
    z-index: 4000;
    pointer-events: none;
    transform: translate(-50%, -50%);
    filter: drop-shadow(0 12px 22px rgba(16, 26, 56, 0.55));
}

.sponsor-drag-ghost .sponsor-tile {
    width: 130px;
    /* Held to one width and one range of heights whatever the logo's own size
       is, because this one is held under a pointer: what matters is that it
       looks like the logo and stays small enough to see past. */
    height: auto;
    aspect-ratio: var(--logo-aspect, 130 / 64);
    min-height: 44px;
    max-height: 150px;
    opacity: 1;
    border-color: #1d4ed8;
}

/* Where it would land: a gap of exactly its size opens in the row, which
   answers the question the drag is asking without needing a legend. */
.sponsor-drop-slot {
    flex: 0 1 120px;
    max-width: 150px;
    min-height: 60px;
    border: 1px dashed #1d4ed8;
    border-radius: 6px;
    background: rgba(29, 78, 216, 0.14);
    list-style: none;
}

/* The slot being aimed at. An inset shadow rather than a border so nothing
   moves by a pixel as the target changes under the pointer. */
.sponsor-slot.is-admin.is-drop-target {
    background: rgba(29, 78, 216, 0.09);
    box-shadow: inset 0 0 0 1px rgba(29, 78, 216, 0.35);
    border-radius: 14px;
}

body.sponsor-dragging {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}

/* A logo is a link to a sponsor's site; dragging one across the page should not
   be able to end in a visit to it. */
body.sponsor-dragging a.sponsor-tile {
    pointer-events: none;
}

/* The list of logos to choose from, opened by the + inside the slot itself so
   the choice is made where its result will appear. */
.sponsor-slot-picker {
    max-width: 520px;
    margin: 0.75rem auto 0;
    padding: 1rem;
    /* The gradient, gold hairline, radius and shadow every panel on the site
       is built from, so a list that appears inside the page reads as part of
       it rather than as a browser dialog that happened to open there. */
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.94));
    border: 1px solid rgba(29, 78, 216, 0.7);
    border-radius: 14px;
    box-shadow: 0 14px 30px rgba(16, 26, 56, 0.42);
    text-align: left;
}

.sponsor-slot-picker-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid rgba(29, 78, 216, 0.2);
    color: #44506b;
    font-size: 0.9rem;
}

.sponsor-slot-picker-head strong {
    color: #1d4ed8;
    font-weight: 600;
}

.sponsor-slot-close {
    flex: 0 0 auto;
    padding: 0 0.35rem;
    background: none;
    border: none;
    color: #44506b;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.sponsor-slot-close:hover,
.sponsor-slot-close:focus-visible {
    color: #0f2a6e;
}

.sponsor-slot-note {
    margin: 0;
    color: #44506b;
    font-size: 0.82rem;
}

.sponsor-pick-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.4rem;
    max-height: 15rem;
    overflow-y: auto;
}

.sponsor-pick-btn {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.45rem;
    background: rgba(29, 78, 216, 0.05);
    border: 1px solid rgba(29, 78, 216, 0.18);
    border-radius: 10px;
    color: #44506b;
    font-family: 'Poppins', sans-serif;
    font-size: 0.82rem;
    text-align: left;
    cursor: pointer;
    transition: all 0.2s ease;
}

.sponsor-pick-btn:hover:not([disabled]),
.sponsor-pick-btn:focus-visible {
    background: rgba(29, 78, 216, 0.12);
    border-color: rgba(29, 78, 216, 0.7);
    transform: translateY(-1px);
}

.sponsor-pick-btn:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.sponsor-pick-btn strong {
    color: #44506b;
    font-weight: 600;
}

.sponsor-pick-btn[disabled] {
    /* Already in this slot: shown rather than hidden, so it is clear the logo
       exists and where it went, instead of it seeming to be missing. */
    opacity: 0.55;
    cursor: default;
}

/* The one tile that keeps a fixed window: a row in a menu of logos to choose
   from, where every thumbnail has to be the same size for the list to be
   readable. So the shape and the size the real tiles take are switched back off
   here - without this the tile's own minimum height would win over the 42px. */
.sponsor-pick-thumb {
    flex: 0 0 auto;
    width: 80px;
    height: 42px;
    aspect-ratio: auto;
    min-height: 0;
    max-height: none;
    padding: 0.25rem 0.35rem;
    opacity: 1;
}

.sponsor-pick-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.sponsor-pick-where {
    color: #64708c;
    font-size: 0.75rem;
}

/* The upload form inside the picker.

   Deliberately below the list of logos already uploaded, and introduced by
   "...or": placing one that exists is the common case, and uploading a new one
   from here is the way out when it does not exist yet. */
.sponsor-slot-upload {
    display: grid;
    gap: 0.45rem;
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(29, 78, 216, 0.2);
    text-align: left;
}

/* The editor has no picker list above it, so it needs no divider either. */
.sponsor-slot-edit {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.sponsor-slot-edit .sponsor-slot-edit-thumb {
    justify-self: center;
    width: 140px;
    height: 72px;
}

.sponsor-slot-upload-head {
    color: #1d4ed8;
    font-size: 0.82rem;
    font-weight: 600;
}

.sponsor-slot-input {
    width: 100%;
    padding: 0.5rem 0.65rem;
    background: rgba(29, 78, 216, 0.06);
    border: 1px solid rgba(29, 78, 216, 0.25);
    border-radius: 8px;
    color: #44506b;
    font-family: 'Poppins', sans-serif;
    font-size: 0.82rem;
}

.sponsor-slot-upscale {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: #44506b;
}

.sponsor-slot-input::placeholder {
    color: #64708c;
}

.sponsor-slot-input:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.25);
}

.sponsor-slot-input[type="file"] {
    padding: 0.4rem 0.5rem;
    color: #44506b;
    font-size: 0.78rem;
}

.sponsor-slot-upload-btn {
    justify-self: start;
}

/* Empty until there is something to say, so the form does not open with a
   blank strip of text under the button. */
.sponsor-slot-upload-msg {
    display: none;
    margin: 0;
    color: #1d4ed8;
    font-size: 0.8rem;
}

.sponsor-slot-upload-msg:not(:empty) {
    display: block;
}

.sponsor-slot-upload-msg.is-error {
    color: #c62828;
}

@media (max-width: 768px) {
    .sponsor-board-inline {
        padding: 0.9rem 1rem;
    }

    .sponsor-board-inline .sponsor-item {
        flex: 1 1 40%;
        max-width: none;
    }

    .sponsor-pick-thumb {
        width: 62px;
        height: 36px;
        min-height: 0;
    }
}

/* --- The Advertisement Logos panel in the admin modal. --- */

/* The Sponsor Bank sits above the admin panel that opened it, so the panel
   stays visible behind rather than appearing to have been replaced. */
.sponsor-bank-modal {
    z-index: 1100;
}

/* The panel writes an explicit display on nothing here, but the site's habit is
   to say so per element rather than trust the attribute. */
#adminSponsorBank[hidden] {
    display: none !important;
}

/* --- The staff Sales Panel: which salesman looks after which account. --- */

/* Above the admin panel and the Content Editor that open it, so the panel behind
   stays visible rather than appearing to have been replaced. The same 1100 the
   Sponsor Bank uses: only one of the two is ever open at a time. */
.sales-assign-modal {
    z-index: 1100;
}

/* The buttons are in the markup for everyone, so sales-assign.js hides them from
   anyone who is not signed in as staff. */
#adminSalesPanelBtn[hidden],
#modSalesPanelBtn[hidden] {
    display: none !important;
}

/* Taller than the documents list it borrows its row styling from: this one is
   read as a grouped list rather than scanned for a single file. */
.sales-assign-list {
    max-height: 46vh;
    gap: 1rem;
}

.sales-assign-group h4 {
    color: #0f2a6e;
    margin: 0 0 0.15rem;
    font-size: 0.98rem;
}

.sales-assign-group > .admin-document-meta {
    display: block;
    margin-bottom: 0.5rem;
}

.sales-assign-group .sales-assign-row {
    margin-bottom: 0.5rem;
}

.sales-assign-row-main {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.sales-assign-row-main strong {
    color: #0f2a6e;
}

.sales-assign-row-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
}

.sales-assign-footnote {
    display: block;
    margin: 0;
    padding-top: 0.2rem;
    border-top: 1px solid rgba(29, 78, 216, 0.15);
}

/* Editing a name or a website: two fields and a save, folded away until asked
   for so the list stays a list. */
.admin-sponsor-edit {
    flex: 1 1 100%;
    display: grid;
    gap: 0.5rem;
    margin-top: 0.6rem;
    padding: 0.7rem 0.8rem;
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.94));
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 12px;
}

.admin-sponsor-edit[hidden] {
    display: none;
}

.admin-sponsor-edit-field {
    display: grid;
    gap: 0.25rem;
}

.admin-sponsor-edit-field input {
    width: 100%;
    padding: 0.5rem 0.65rem;
    background: rgba(29, 78, 216, 0.06);
    border: 1px solid rgba(29, 78, 216, 0.25);
    border-radius: 8px;
    color: #44506b;
    font-family: 'Poppins', sans-serif;
    font-size: 0.85rem;
}

.admin-sponsor-edit-field input:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.25);
}

.admin-sponsor-edit .btn-update-prefs {
    justify-self: start;
}

/*
    The crop editor, opened from "Fit" on a sponsor row.

    Laid out as preview beside controls so the frame stays in view while the
    zoom is moved - the whole value of the panel is watching the framing change
    as it is adjusted.
*/
.admin-sponsor-fit {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: flex-start;
    margin-top: 0.6rem;
    padding: 0.8rem;
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.94));
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 12px;
}

.admin-sponsor-fit[hidden] {
    display: none;
}

.admin-fit-stage {
    flex: 0 1 auto;
    /* The preview inside can be asked to be two and a half times a slot wide;
       the panel is not allowed to grow with it past the point where the
       controls beside it would be pushed off. */
    max-width: 100%;
    display: grid;
    gap: 0.35rem;
}

/*
    The same shape and size as a real slot tile, so the preview is the thing
    itself rather than a picture of it. `grab` says the artwork can be moved
    before anybody tries.
*/
.admin-fit-frame {
    /*
        The preview grows and changes shape with the controls beside it, because
        the size being chosen is a size on the page and a number in a readout
        does not show that. Held to the width of the panel so a logo set to four
        times does not push the controls out of reach.
    */
    width: calc(200px * var(--logo-scale, 1));
    max-width: 100%;
    height: auto;
    aspect-ratio: var(--logo-aspect, 200 / 90);
    min-height: 56px;
    max-height: 280px;
    opacity: 1;
    cursor: grab;
    /* A drag that starts on the frame should move the logo, not scroll the
       panel or select the image on a phone. */
    touch-action: none;
    user-select: none;
}

.admin-fit-frame:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.admin-fit-frame.is-dragging {
    cursor: grabbing;
    border-color: #1d4ed8;
}

.admin-fit-frame img {
    pointer-events: none;
}

.admin-fit-controls {
    flex: 1 1 220px;
    min-width: 0;
    display: grid;
    gap: 0.6rem;
}

.admin-fit-modes {
    display: flex;
    gap: 0.4rem;
}

.admin-fit-mode {
    flex: 1 1 auto;
    padding: 0.4rem 0.6rem;
    background: rgba(29, 78, 216, 0.06);
    border: 1px solid rgba(29, 78, 216, 0.25);
    border-radius: 8px;
    color: #44506b;
    font-family: 'Poppins', sans-serif;
    font-size: 0.82rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.admin-fit-mode:hover {
    border-color: #1d4ed8;
    color: #0f2a6e;
}

/* The chosen mode, filled in rather than merely outlined: which of the two is
   active is the one thing that has to be readable at a glance. */
.admin-fit-mode.is-on {
    background: #1d4ed8;
    border-color: #1d4ed8;
    color: #ffffff;
}

.admin-fit-controls input[type="range"] {
    width: 100%;
    accent-color: #1d4ed8;
}

.admin-fit-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Upscaling in the crop editor: the choice and the button that applies it. */
.admin-fit-upscale {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
}

.admin-fit-upscale .admin-sponsor-edit-field {
    flex: 1 1 200px;
}

.admin-fit-upscale select,
#adminSponsorUpscale {
    width: 100%;
    padding: 0.45rem 0.6rem;
    border: 1px solid rgba(29, 78, 216, 0.25);
    border-radius: 8px;
    font-family: 'Poppins', sans-serif;
    font-size: 0.85rem;
}

@media (max-width: 600px) {
    .admin-fit-frame {
        width: 100%;
    }
}

.admin-sponsor-notice {
    margin: 0 0 0.6rem;
    padding: 0.6rem 0.8rem;
    background: rgba(29, 78, 216, 0.12);
    border-left: 3px solid #1d4ed8;
    border-radius: 4px;
    color: #0f2a6e;
    font-size: 0.85rem;
}

.admin-sponsor-row .admin-document-details {
    /* Takes the space the thumbnail and buttons leave, so long sponsor names
       wrap instead of pushing the buttons off the row. */
    flex: 1 1 180px;
    min-width: 0;
}

/*
    The list thumbnail follows the same shape and size as the real tile, so the
    list is where an admin sees at a glance that one sponsor is set much larger
    than the rest. It is bounded harder than a tile on a page is: a row in a
    list has to stay a row.
*/
.admin-sponsor-thumb {
    flex: 0 0 auto;
    width: calc(110px * var(--logo-scale, 1));
    max-width: 180px;
    height: auto;
    aspect-ratio: var(--logo-aspect, 110 / 56);
    min-height: 40px;
    max-height: 104px;
    padding: 0.4rem 0.5rem;
    opacity: 1;
}

.admin-sponsor-link {
    color: #1d4ed8;
    font-size: 0.8rem;
    word-break: break-all;
}

/* --- Choosing pages: the tick boxes in the panel. ---
   A browser's own checkbox is a small blue-grey square with a system tick in
   it, which on this page is the one control that looks like it came from
   somewhere else. So the box is drawn instead: a gold hairline square that
   fills with the same gold gradient as every button on the site, and the whole
   label is a pill that lights up with it. The input is still a real checkbox
   underneath - it is restyled, not replaced by something clickable - so it
   tabs, ticks with the space bar and reads correctly to a screen reader. */
.admin-sponsor-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.7rem;
    background: rgba(29, 78, 216, 0.05);
    border: 1px solid rgba(29, 78, 216, 0.18);
    border-radius: 999px;
    color: #44506b;
    font-size: 0.82rem;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.2s ease;
}

.admin-sponsor-toggle:hover {
    border-color: rgba(29, 78, 216, 0.55);
    color: #44506b;
}

.admin-sponsor-toggle:has(input:checked) {
    background: rgba(29, 78, 216, 0.12);
    border-color: rgba(29, 78, 216, 0.7);
    color: #44506b;
}

/* While "All pages" is ticked the individual pages are not the ones deciding.
   They go quiet rather than disappearing, so it stays clear what would happen
   if All were unticked. */
.admin-sponsor-toggle:has(input:disabled) {
    opacity: 0.5;
    cursor: default;
}

.admin-sponsor-toggle input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    margin: 0;
    background: rgba(29, 78, 216, 0.08);
    border: 1px solid rgba(29, 78, 216, 0.55);
    border-radius: 4px;
    cursor: inherit;
    transition: all 0.2s ease;
}

.admin-sponsor-toggle input[type="checkbox"]:checked {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    border-color: #1d4ed8;
}

.admin-sponsor-toggle input[type="checkbox"]:checked::after {
    content: '\2713';
    color: #16203a;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
}

.admin-sponsor-toggle input[type="checkbox"]:focus-visible {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.admin-sponsor-toggle-inline {
    margin: 0.2rem 0;
}

/* The page tick boxes, in the upload form and expanded inside a row. Its own
   full-width line in the row rather than squeezed beside the buttons, because
   seven labels wrapped through a button group is unreadable, and built from the
   same gradient and gold hairline as the panels it sits in. */
/* display:flex here beats the browser's own [hidden] rule, so the collapsed
   state has to be said out loud - without this the per-row checklist would sit
   open on every row and the Pages button would appear to do nothing. */
.admin-sponsor-pages[hidden] {
    display: none;
}

.admin-sponsor-pages {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    flex-basis: 100%;
    padding: 0.75rem;
    background: linear-gradient(140deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.94));
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 12px;
}

.admin-sponsor-pages[hidden] {
    display: none !important;
}

/* "All pages" leads the list and is the one that changes what the others do, so
   it is set apart from them rather than reading as a seventh page. */
.admin-sponsor-toggle-all {
    flex-basis: 100%;
    margin-bottom: 0.2rem;
    background: rgba(29, 78, 216, 0.08);
    border-color: rgba(29, 78, 216, 0.4);
    border-radius: 10px;
    color: #1d4ed8;
    font-weight: 600;
}

/* Same specificity as the generic checked pill and written after it, so ticking
   All keeps its gold rather than turning white like a page. */
.admin-sponsor-toggle-all:has(input:checked) {
    background: rgba(29, 78, 216, 0.16);
    border-color: rgba(29, 78, 216, 0.7);
    color: #0f2a6e;
}

.admin-sponsor-flag {
    font-weight: 600;
}

.admin-sponsor-flag.is-live {
    color: #2e7d32;
}

.admin-sponsor-flag.is-waiting {
    color: #b45309;
}

.admin-sponsor-flag.is-hidden {
    color: #64708c;
}

.admin-sponsor-preview {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    align-items: flex-start;
}

.admin-sponsor-preview .admin-sponsor-thumb {
    width: 180px;
    height: 90px;
    aspect-ratio: auto;
    max-height: none;
}

.btn-document-view[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
    box-shadow: none;
}

/* ============================================================
   Contracts and Billing - the account records page and the two
   buttons in the profile panel that open it.
   ============================================================ */

/* The Contracts and Billing buttons in the profile panel. */
.business-profile-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.business-profile-heading h3 {
    margin: 0;
}

.business-account-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    color: #2e7d32;
    background: rgba(33, 150, 83, 0.14);
    border: 1px solid rgba(78, 194, 117, 0.45);
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
}

.account-portal-buttons {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
    gap: 1rem;
}

.btn-account-portal {
    --badge-ring: #ffffff;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
    background:
        linear-gradient(150deg, rgba(29, 78, 216, 0.16) 0%, rgba(29, 78, 216, 0) 55%),
        linear-gradient(135deg, #ffffff 0%, #eaf0ff 100%);
    color: #0f2a6e;
    border: 2px solid rgba(29, 78, 216, 0.55);
    padding: 1.25rem 1.4rem;
    border-radius: 12px;
    font-family: 'Poppins', sans-serif;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    text-align: left;
    cursor: pointer;
    transition: box-shadow 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}

.btn-account-portal:hover,
.btn-account-portal:focus-visible {
    box-shadow: 0 12px 28px rgba(29, 78, 216, 0.28);
    border-color: #1d4ed8;
    transform: translateY(-3px);
}

.account-portal-hint {
    color: #64708c;
    font-size: 0.9rem;
    margin: 0.9rem 0 0;
}

.btn-account-portal-sub {
    color: rgba(68, 80, 107, 0.62);
    font-size: 0.82rem;
    font-weight: 500;
    letter-spacing: 0;
}

/* ------------------------------------------------ the badge counter ------ */

/**
 * The unopened counter, borrowed from a phone home screen: a red disc sitting
 * on the corner of the thing it belongs to, ringed in the colour behind it so
 * it reads as punched through rather than pasted on. Each host sets
 * --badge-ring to its own background; the fallback in var() supplies the rest,
 * since a value declared here would beat the inherited one.
 */
.portal-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.5rem;
    border-radius: 999px;
    background: linear-gradient(180deg, #ff6257 0%, #e1261b 100%);
    color: #ffffff;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0;
    box-shadow:
        0 0 0 3px var(--badge-ring, #ffffff),
        0 4px 12px rgba(16, 26, 56, 0.55);
    animation: portalBadgePop 0.5s cubic-bezier(0.2, 1.4, 0.4, 1) both;
}

.btn-account-portal .portal-badge {
    position: absolute;
    top: -0.75rem;
    right: -0.65rem;
}

@keyframes portalBadgePop {
    0% { transform: scale(0.2); opacity: 0; }
    70% { transform: scale(1.14); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

/* ============================================================
   account-documents.html
   ============================================================ */

.account-portal-body {
    /* One palette for the whole page, taken from the site's gold on charcoal. */
    --vault-ink: #f5f7fb;
    --vault-panel: #ffffff;
    --vault-raised: #eef1f7;
    --vault-gold: #1d4ed8;
    --vault-gold-bright: #0f2a6e;
    --vault-line: rgba(29, 78, 216, 0.28);
    --vault-text: #16203a;
    --vault-muted: #64708c;

    min-height: 100vh;
    color: var(--vault-text);
    font-size: 17px;
    background:
        radial-gradient(1100px 620px at 8% -12%, rgba(29, 78, 216, 0.17), transparent 62%),
        radial-gradient(900px 520px at 102% 4%, rgba(29, 78, 216, 0.09), transparent 58%),
        linear-gradient(180deg, #ffffff 0%, var(--vault-ink) 42%, #ffffff 100%);
    background-attachment: fixed;
}

/* Fixed and pointer-transparent, so nothing here is dragged along by scrolling. */
.portal-grain {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0.5;
    background-image: repeating-linear-gradient(
        118deg,
        rgba(29, 78, 216, 0.05) 0px,
        rgba(29, 78, 216, 0.05) 1px,
        transparent 1px,
        transparent 7px
    );
    mask-image: radial-gradient(120% 90% at 50% 0%, #000 20%, transparent 78%);
    -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 20%, transparent 78%);
}

/* --------------------------------------------------------- top bar ------- */

.portal-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 1rem clamp(1.2rem, 4vw, 3.5rem);
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    border-bottom: 3px solid var(--vault-gold);
    box-shadow: 0 6px 24px rgba(16, 26, 56, 0.45);
}

.portal-brand {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    text-decoration: none;
}

.portal-brand img {
    height: 44px;
    width: auto;
}

.portal-brand-text {
    color: var(--vault-gold);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
}

.portal-topbar-side {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.account-portal-back {
    color: var(--vault-muted);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: color 0.2s ease, border-color 0.2s ease;
}

.account-portal-back:hover {
    color: var(--vault-gold-bright);
    border-bottom-color: var(--vault-gold);
}

.account-portal-badge {
    border: 1px solid var(--vault-line);
    border-radius: 999px;
    padding: 0.3rem 1rem;
    color: var(--vault-gold);
    background: rgba(29, 78, 216, 0.08);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

/* --------------------------------------------------------- layout ------- */

.account-portal {
    position: relative;
    z-index: 1;
    width: min(1680px, 100%);
    margin: 0 auto;
    /* Enough to push the last panel to the bottom of a short page, so the two
       tabs and their contents own the whole window rather than a column of it. */
    min-height: calc(100vh - 92px);
    display: flex;
    flex-direction: column;
    gap: clamp(1.4rem, 2.6vw, 2.4rem);
    padding: clamp(1.8rem, 4vw, 3.4rem) clamp(1.2rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4rem);
}

.portal-masthead {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
    flex-wrap: wrap;
    padding-bottom: clamp(1rem, 2vw, 1.8rem);
    border-bottom: 1px solid var(--vault-line);
}

.portal-eyebrow {
    margin: 0;
    color: var(--vault-gold);
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.32em;
}

.portal-masthead-text {
    min-width: 0;
}

#portalHeading {
    margin: 0.35rem 0 0.7rem;
    font-size: clamp(2.8rem, 6.5vw, 5rem);
    font-weight: 800;
    line-height: 0.98;
    letter-spacing: -0.02em;
    color: var(--vault-gold-bright);
    text-shadow: 0 8px 30px rgba(29, 78, 216, 0.22);
}

.account-portal-account {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-wrap: wrap;
    margin: 0;
    color: var(--vault-text);
    font-size: 1.05rem;
}

.portal-account-label {
    color: var(--vault-muted);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.18em;
}

/* A quiet piece of furniture in the corner, to stop the masthead from being
   one lonely block of text on a wide screen. */
.portal-masthead-mark {
    position: relative;
    display: grid;
    place-items: center;
    width: 128px;
    height: 128px;
    flex: 0 0 auto;
}

.portal-mark-ring {
    position: absolute;
    inset: 0;
    border: 1px solid var(--vault-line);
    border-radius: 50%;
}

.portal-mark-ring::after {
    content: '';
    position: absolute;
    inset: 14px;
    border: 1px dashed rgba(29, 78, 216, 0.35);
    border-radius: 50%;
    animation: portalMarkSpin 46s linear infinite;
}

.portal-mark-core {
    color: var(--vault-gold);
    font-size: 1.15rem;
    font-weight: 800;
    letter-spacing: 0.22em;
}

@keyframes portalMarkSpin {
    to { transform: rotate(360deg); }
}

/* ----------------------------------------------------------- tabs ------- */

.account-portal-tabs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: clamp(0.9rem, 1.8vw, 1.5rem);
}

.account-portal-tab {
    --badge-ring: #ffffff;
    position: relative;
    display: flex;
    align-items: center;
    gap: 1.2rem;
    padding: clamp(1.3rem, 2.4vw, 1.9rem) clamp(1.4rem, 2.4vw, 2rem);
    border: 2px solid rgba(29, 78, 216, 0.3);
    border-radius: 16px;
    background:
        linear-gradient(160deg, rgba(29, 78, 216, 0.07) 0%, rgba(29, 78, 216, 0) 60%),
        #ffffff;
    color: var(--vault-gold);
    text-decoration: none;
    overflow: hidden;
    transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.account-portal-tab::before {
    /* A gold edge that fills in when the tab is the one you are on. */
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 5px;
    background: linear-gradient(180deg, var(--vault-gold-bright), var(--vault-gold));
    transform: scaleY(0);
    transform-origin: top;
    transition: transform 0.35s ease;
}

.account-portal-tab:hover {
    transform: translateY(-4px);
    border-color: rgba(29, 78, 216, 0.6);
    box-shadow: 0 16px 34px rgba(16, 26, 56, 0.5);
}

.account-portal-tab.active {
    --badge-ring: #ffffff;
    border-color: var(--vault-gold);
    background:
        linear-gradient(160deg, rgba(59, 111, 242, 0.16) 0%, rgba(29, 78, 216, 0.02) 65%),
        #ffffff;
    box-shadow: 0 18px 40px rgba(29, 78, 216, 0.16);
}

.account-portal-tab.active::before {
    transform: scaleY(1);
}

.portal-tab-icon {
    display: grid;
    place-items: center;
    width: 3.6rem;
    height: 3.6rem;
    flex: 0 0 auto;
    border-radius: 12px;
    border: 1px solid var(--vault-line);
    background: rgba(29, 78, 216, 0.06);
}

.portal-tab-icon svg {
    width: 1.9rem;
    height: 1.9rem;
}

.account-portal-tab.active .portal-tab-icon {
    color: var(--vault-gold-bright);
    border-color: rgba(29, 78, 216, 0.6);
}

.portal-tab-text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.portal-tab-name {
    font-size: clamp(1.4rem, 2.4vw, 1.8rem);
    font-weight: 700;
    line-height: 1.1;
}

.account-portal-tab.active .portal-tab-name {
    color: var(--vault-gold-bright);
}

.portal-tab-sub {
    color: var(--vault-muted);
    font-size: 0.9rem;
    font-weight: 500;
}

.account-portal-tab .portal-badge {
    margin-left: auto;
}

/* ---------------------------------------------------------- panels ------ */

.account-portal-card {
    position: relative;
    border: 1px solid var(--vault-line);
    border-radius: 16px;
    padding: clamp(1.4rem, 2.6vw, 2.4rem);
    background:
        linear-gradient(180deg, rgba(29, 78, 216, 0.05) 0%, rgba(29, 78, 216, 0) 180px),
        var(--vault-panel);
    box-shadow: 0 20px 50px rgba(16, 26, 56, 0.35);
}

/* The documents panel takes whatever height is left over. */
.portal-card-docs {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
}

.portal-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.4rem;
}

.account-portal-card h2 {
    margin: 0;
    color: var(--vault-gold-bright);
    font-size: clamp(1.3rem, 2.2vw, 1.7rem);
    font-weight: 700;
    letter-spacing: -0.01em;
}

.portal-count {
    color: var(--vault-muted);
    font-size: 0.9rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.account-portal-summary {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.account-portal-summary-row {
    display: flex;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 0.65rem 0;
    border-bottom: 1px solid rgba(29, 78, 216, 0.12);
    color: var(--vault-text);
    font-size: 1.02rem;
}

.account-portal-summary-row:last-child {
    border-bottom: none;
}

.account-portal-label {
    color: var(--vault-muted);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

/* ------------------------------------------------- the card on file ----- */

.portal-plastic {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    width: min(430px, 100%);
    margin-bottom: 1.2rem;
    padding: 1.5rem 1.6rem;
    border-radius: 14px;
    border: 1px solid rgba(29, 78, 216, 0.45);
    background:
        linear-gradient(115deg, rgba(59, 111, 242, 0.14) 0%, rgba(29, 78, 216, 0.02) 45%, rgba(29, 78, 216, 0.04) 100%),
        linear-gradient(160deg, #ffffff 0%, #ffffff 100%);
    box-shadow: 0 18px 38px rgba(16, 26, 56, 0.5);
    overflow: hidden;
}

.portal-plastic::after {
    /* A slow band of light across the face of the card. */
    content: '';
    position: absolute;
    top: -60%;
    left: -30%;
    width: 40%;
    height: 220%;
    background: linear-gradient(90deg, transparent, rgba(59, 111, 242, 0.12), transparent);
    transform: rotate(18deg);
    animation: portalPlasticSheen 7s ease-in-out infinite;
}

@keyframes portalPlasticSheen {
    0%, 65% { transform: translateX(0) rotate(18deg); }
    100% { transform: translateX(360%) rotate(18deg); }
}

.portal-plastic-brand {
    color: var(--vault-gold-bright);
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.portal-plastic-chip {
    width: 46px;
    height: 34px;
    border-radius: 6px;
    border: 1px solid rgba(29, 78, 216, 0.5);
    background:
        repeating-linear-gradient(0deg, rgba(29, 78, 216, 0.35) 0 1px, transparent 1px 9px),
        linear-gradient(150deg, #1d4ed8 0%, #1d4ed8 100%);
}

.portal-plastic-number {
    color: var(--vault-text);
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: 0.12em;
}

.portal-plastic-dots {
    color: var(--vault-muted);
    margin-right: 0.4rem;
}

.portal-plastic-foot {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    color: var(--vault-muted);
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

.portal-plastic-name {
    color: var(--vault-text);
}

.portal-plastic-exp {
    white-space: nowrap;
}

/* ------------------------------------------- admin forms, folded away --- */

.account-portal-editor {
    margin: 0 0 1.6rem;
    border: 1px dashed rgba(29, 78, 216, 0.3);
    border-radius: 12px;
    background: rgba(29, 78, 216, 0.04);
}

.account-portal-editor > summary {
    padding: 0.95rem 1.2rem;
    color: var(--vault-gold);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    cursor: pointer;
    list-style: none;
}

.account-portal-editor > summary::marker,
.account-portal-editor > summary::-webkit-details-marker {
    display: none;
}

.account-portal-editor > summary::before {
    content: '+';
    display: inline-block;
    width: 1.3rem;
    color: var(--vault-gold-bright);
    font-weight: 700;
}

.account-portal-editor[open] > summary::before {
    content: '\2212';
}

.account-portal-form {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    padding: 0 1.2rem 1.3rem;
}

.account-portal-form input[type="text"],
.account-portal-form input[type="file"],
.account-portal-form select,
.portal-picker select {
    padding: 0.85rem 0.95rem;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.35);
    color: #44506b;
    border-radius: 8px;
    font-size: 1rem;
    font-family: 'Poppins', sans-serif;
}

.account-portal-form input[type="text"]:focus,
.account-portal-form input[type="file"]:focus,
.account-portal-form select:focus,
.portal-picker select:focus {
    outline: none;
    border-color: var(--vault-gold-bright);
    box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.18);
}

.account-portal-form-row {
    display: flex;
    gap: 0.8rem;
    flex-wrap: wrap;
}

.account-portal-form-row input {
    flex: 1 1 160px;
}

/* Whose paperwork the page is showing. Staff only; a member never sees it. */
.portal-picker {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    padding: 0 1.2rem 1.3rem;
}

.portal-picker-label {
    color: var(--vault-muted);
    font-size: 0.82rem;
    font-weight: 600;
}

.portal-picker select {
    width: 100%;
    max-width: 32rem;
}

.account-portal-note {
    color: var(--vault-muted);
    font-size: 0.82rem;
    margin: 0;
}

/* ------------------------------------------------- the document grid ---- */

.account-portal-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(285px, 100%), 1fr));
    gap: clamp(1rem, 2vw, 1.6rem);
    align-content: start;
}

.portal-doc {
    position: relative;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--vault-line);
    border-radius: 14px;
    background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
    overflow: hidden;
    transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
    /* backwards, not both: a filled-forwards transform would outrank the hover
       lift below and the card would never move. */
    animation: portalDocIn 0.5s ease backwards;
}

@keyframes portalDocIn {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: translateY(0); }
}

.portal-doc:hover {
    transform: translateY(-5px);
    border-color: rgba(29, 78, 216, 0.55);
    box-shadow: 0 18px 38px rgba(16, 26, 56, 0.5);
}

.portal-doc.is-unread {
    border-color: rgba(29, 78, 216, 0.5);
    box-shadow: 0 0 0 1px rgba(29, 78, 216, 0.12), 0 14px 34px rgba(16, 26, 56, 0.45);
}

/* The page thumbnail. Drawn rather than rendered from the file: it stands in
   for the document until it is opened, which is the whole point of it being
   blurred in the first place.

   A button rather than a link, because opening the PDF is a fetch that carries
   the session token in a header — so the browser's own button chrome has to be
   reset back to the plain surface this was as an anchor. */
.portal-doc-preview {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    margin: 0;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
    border: none;
    border-bottom: 1px solid var(--vault-line);
    border-radius: 0;
    font: inherit;
    color: inherit;
    text-align: inherit;
    text-decoration: none;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}

.portal-doc-page {
    position: absolute;
    inset: 12% 14% -18%;
    display: flex;
    flex-direction: column;
    /* Fixed rather than proportional: a percentage gap here would eat the whole
       page at narrow card widths and squash the lines to nothing. Anything that
       runs past the bottom is clipped, which is what a page does anyway. */
    gap: 9px;
    padding: 1.1rem 1rem;
    border-radius: 4px 4px 0 0;
    background: linear-gradient(180deg, #f5f7fb 0%, #eef1f7 100%);
    box-shadow: 0 -6px 24px rgba(16, 26, 56, 0.4);
    transform-origin: center top;
    transition: filter 0.55s ease, transform 0.55s ease;
}

.portal-doc-page > * {
    flex: 0 0 auto;
}

.portal-doc-page-head {
    height: 12px;
    width: 46%;
    border-radius: 2px;
    background: #1d4ed8;
}

.portal-doc-rule {
    height: 6px;
    border-radius: 2px;
    background: rgba(29, 78, 216, 0.08);
}

.portal-doc-page-sign {
    height: 11px;
    width: 38%;
    margin-top: 6px;
    border-radius: 2px;
    background: repeating-linear-gradient(
        68deg,
        rgba(14, 25, 55, 0.39) 0 2px,
        transparent 2px 5px
    );
}

.portal-doc.is-unread .portal-doc-page {
    filter: blur(7px) saturate(0.7) brightness(0.86);
    transform: scale(1.03);
}

.portal-doc-seal {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background: linear-gradient(180deg, rgba(29, 78, 216, 0.55) 0%, rgba(15, 42, 110, 0.85) 100%);
    opacity: 0;
    transition: opacity 0.35s ease;
}

.portal-doc.is-unread .portal-doc-seal,
.portal-doc:hover .portal-doc-seal {
    opacity: 1;
}

.portal-doc-seal-mark {
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.82);
    background: rgba(15, 42, 110, 0.55);
    color: #ffffff;
    font-size: 0.82rem;
    font-weight: 800;
    letter-spacing: 0.06em;
}

.portal-doc-seal-text {
    color: #ffffff;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.16em;
}

/* The per-card marker. The number lives on the tab; a card only needs to say
   that it is one of them. */
.portal-doc-flag {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.75rem 0.3rem 0.6rem;
    border-radius: 999px;
    background: linear-gradient(180deg, #ff6257 0%, #e1261b 100%);
    color: #ffffff;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    box-shadow: 0 4px 14px rgba(16, 26, 56, 0.5);
}

.portal-doc-flag::before {
    content: '';
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: #ffffff;
    animation: portalFlagPulse 2.2s ease-in-out infinite;
}

@keyframes portalFlagPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.45; transform: scale(0.8); }
}

.portal-doc-body {
    flex: 1 1 auto;
    padding: 1.1rem 1.2rem 0.6rem;
}

.portal-doc-title {
    margin: 0 0 0.4rem;
    color: var(--vault-gold-bright);
    font-size: 1.12rem;
    font-weight: 700;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.portal-doc-meta {
    margin: 0;
    color: var(--vault-muted);
    font-size: 0.86rem;
}

.portal-doc-actions {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    padding: 0.9rem 1.2rem 1.2rem;
}

.portal-doc-actions .btn-document-view {
    flex: 1 1 auto;
    text-align: center;
    padding: 0.65rem 1rem;
    font-size: 0.95rem;
    border-radius: 8px;
}

.portal-doc-actions .btn-delete-document {
    padding: 0.65rem 1rem;
    font-size: 0.9rem;
    border-radius: 8px;
}

/* ------------------------------------------------ loading and empty ----- */

.portal-doc-skeleton {
    position: relative;
    aspect-ratio: 4 / 5;
    border: 1px solid rgba(29, 78, 216, 0.16);
    border-radius: 14px;
    background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
    overflow: hidden;
}

.portal-doc-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 20%, rgba(29, 78, 216, 0.1) 50%, transparent 80%);
    transform: translateX(-100%);
    animation: portalShimmer 1.6s ease-in-out infinite;
}

@keyframes portalShimmer {
    to { transform: translateX(100%); }
}

.portal-empty {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.7rem;
    padding: clamp(2.5rem, 6vw, 5rem) 1.5rem;
    border: 1px dashed rgba(29, 78, 216, 0.28);
    border-radius: 14px;
    text-align: center;
}

.portal-empty-mark {
    width: 62px;
    height: 78px;
    border: 2px solid rgba(29, 78, 216, 0.45);
    border-radius: 4px;
    background: repeating-linear-gradient(
        180deg,
        transparent 0 14px,
        rgba(29, 78, 216, 0.2) 14px 16px
    );
}

.portal-empty-title {
    margin: 0.5rem 0 0;
    color: var(--vault-gold-bright);
    font-size: 1.2rem;
    font-weight: 700;
}

.account-portal-empty {
    color: var(--vault-muted);
    margin: 0;
    font-size: 0.98rem;
    max-width: 46ch;
}

/* A message standing in for the whole list should span it, not sit in one cell. */
.account-portal-list > .account-portal-empty {
    grid-column: 1 / -1;
}

/* ------------------------------------------------------- narrow screens - */

@media (max-width: 640px) {
    .portal-masthead-mark {
        display: none;
    }

    .account-portal-list {
        grid-template-columns: 1fr;
    }

    .portal-brand-text {
        font-size: 0.85rem;
        letter-spacing: 0.14em;
    }
}

@media (prefers-reduced-motion: reduce) {
    .portal-doc,
    .portal-badge,
    .portal-doc-flag::before,
    .portal-mark-ring::after,
    .portal-plastic::after,
    .portal-doc-skeleton::after {
        animation: none;
    }

    .portal-doc:hover,
    .account-portal-tab:hover,
    .btn-account-portal:hover {
        transform: none;
    }
}

.admin-package-editor {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(29, 78, 216, 0.3);
}

.admin-package-title {
    color: #0f2a6e;
    margin-bottom: 0.7rem;
}

.admin-package-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 1rem;
}

.admin-package-card {
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 8px;
    background: rgba(29, 78, 216, 0.05);
    padding: 1rem;
}

.admin-package-card h4 {
    margin: 0 0 0.75rem;
    color: #0f2a6e;
}

.admin-package-select-row {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0.8rem;
}

.admin-package-select-row label {
    color: #0f2a6e;
    font-size: 0.85rem;
}

.admin-plan-select,
.admin-plan-form input,
.admin-plan-form textarea {
    width: 100%;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.4);
    border-radius: 6px;
    color: #44506b;
    padding: 0.6rem 0.7rem;
    font-family: 'Poppins', sans-serif;
    font-size: 0.9rem;
}

.admin-plan-form {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.admin-plan-form textarea {
    resize: vertical;
}

.admin-plan-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.admin-plan-actions .btn-update-prefs {
    margin-top: 0;
}

.admin-reset-btn {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    color: #0f2a6e;
    border: 1px solid rgba(29, 78, 216, 0.5);
}

.admin-reset-btn:hover {
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.25);
}

/* Moderator Dashboard Styles */
.sales-panel-modal-content {
    max-width: 880px;
    background: #f8f4ea;
}

.sales-panel-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.2rem 0 1.2rem;
    border-bottom: 1px solid rgba(138, 75, 8, 0.2);
}

.sales-panel-heading h2 { margin: 0; color: #29364a; }
.sales-panel-kicker { margin: 0 0 0.25rem; color: #8a4b08; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; }
.sales-panel-welcome { margin: 0.35rem 0 0; color: #667085; }
.sales-panel-readonly { flex: 0 0 auto; padding: 0.3rem 0.65rem; color: #8a4b08; background: rgba(217, 139, 32, 0.14); border: 1px solid rgba(138, 75, 8, 0.28); border-radius: 999px; font-size: 0.72rem; font-weight: 800; text-transform: uppercase; }
.sales-panel-note { margin: 1rem 0; color: #5b6473; line-height: 1.6; }
.sales-customers-summary { margin-bottom: 0.75rem; color: #29364a; font-size: 0.84rem; font-weight: 800; }
.sales-customers-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem; }
.sales-customer-card { padding: 1.15rem; background: #ffffff; border: 1px solid rgba(41, 54, 74, 0.14); border-top: 3px solid #b87922; border-radius: 5px 14px 14px 14px; box-shadow: 0 10px 24px rgba(41, 54, 74, 0.07); }
.sales-customer-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.sales-customer-card h3 { margin: 0; color: #29364a; font-size: 1.08rem; }
.sales-customer-company { margin: 0 0 0.25rem; color: #8a4b08; font-size: 0.73rem; font-weight: 700; text-transform: uppercase; }
.sales-customer-status { padding: 0.18rem 0.5rem; color: #2e6b3e; background: #e9f5ec; border-radius: 999px; font-size: 0.68rem; font-weight: 800; }
.sales-customer-details { margin: 1rem 0 0; display: grid; gap: 0.65rem; }
.sales-customer-details div { display: grid; grid-template-columns: 4rem minmax(0, 1fr); gap: 0.5rem; }
.sales-customer-details dt { color: #7a8290; font-size: 0.75rem; font-weight: 700; }
.sales-customer-details dd { margin: 0; color: #364152; font-size: 0.84rem; overflow-wrap: anywhere; }
.sales-customer-details a { color: #1d4ed8; text-decoration: none; }
.sales-customer-details a:hover, .sales-customer-details a:focus-visible { text-decoration: underline; }
.sales-customers-empty { grid-column: 1 / -1; padding: 2rem; text-align: center; background: rgba(255, 255, 255, 0.64); border: 1px dashed rgba(138, 75, 8, 0.35); border-radius: 12px; }
.sales-customers-empty h3 { margin: 0 0 0.4rem; color: #29364a; }
.sales-customers-empty p { margin: 0; color: #667085; }
.sales-customer-skeleton { min-height: 190px; border-radius: 12px; background: linear-gradient(100deg, #ebe7df 25%, #f8f6f0 45%, #ebe7df 65%); background-size: 200% 100%; animation: sales-panel-loading 1.2s ease-in-out infinite; }
@keyframes sales-panel-loading { to { background-position: -200% 0; } }

@media (max-width: 680px) {
    .sales-customers-list { grid-template-columns: 1fr; }
    .sales-panel-heading { align-items: center; }
}

.moderator-section {
    border: 1px solid rgba(29, 78, 216, 0.3);
    border-radius: 8px;
    padding: 1.2rem;
    margin-bottom: 1.2rem;
    background: rgba(29, 78, 216, 0.04);
}

.moderator-section h3 {
    color: #0f2a6e;
    margin-bottom: 1rem;
    font-size: 1.1rem;
}

/*
    The access map at the top of the moderator panel. Tinted apart from the
    editing sections below it so it reads as a summary and a set of shortcuts
    rather than one more form to fill in.
*/
.moderator-access-section {
    border-color: rgba(15, 42, 110, 0.5);
    background: linear-gradient(145deg, rgba(29, 78, 216, 0.09), rgba(255, 255, 255, 0.96));
}

.moderator-access-links {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.moderator-stations-section {
    border-color: rgba(184, 121, 34, 0.48);
    background: linear-gradient(145deg, rgba(255, 250, 239, 0.96), rgba(29, 78, 216, 0.035));
}

.moderator-page-text-section {
    border-color: rgba(15, 42, 110, 0.42);
    background: linear-gradient(145deg, rgba(238, 244, 255, 0.94), rgba(255, 255, 255, 0.96));
}

.moderator-page-text-section .mod-form label {
    color: #44506b;
    font-size: 0.78rem;
    font-weight: 700;
}

.moderator-stations-section .mod-form label {
    color: #44506b;
    font-size: 0.78rem;
    font-weight: 700;
}

.mod-form {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 1rem;
    background: rgba(29, 78, 216, 0.05);
    padding: 1rem;
    border-radius: 6px;
}

.mod-form input,
.mod-form textarea {
    padding: 0.6rem;
    background: #ffffff;
    border: 1px solid rgba(29, 78, 216, 0.4);
    color: #44506b;
    border-radius: 4px;
    font-family: 'Poppins', sans-serif;
    font-size: 0.9rem;
}

.mod-form input:focus,
.mod-form textarea:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 6px rgba(29, 78, 216, 0.3);
}

.mod-form button {
    background: #1d4ed8;
    color: #ffffff;
    padding: 0.6rem 1rem;
    border: none;
    border-radius: 4px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s ease;
}

.mod-form-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.mod-form-actions .btn-cancel {
    background: #eef1f7;
    color: #44506b;
}

.mod-form-actions .btn-cancel:hover,
.mod-form-actions .btn-cancel:focus-visible {
    background: #dde3ee;
}

.mod-form button:hover {
    background: #3b6ff2;
}

.mod-items-list {
    max-height: 35vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.mod-item {
    background: rgba(29, 78, 216, 0.04);
    padding: 0.8rem;
    border-left: 3px solid #1d4ed8;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.mod-item strong {
    color: #0f2a6e;
    font-size: 0.95rem;
}

.mod-item p {
    color: #44506b;
    font-size: 0.85rem;
    margin: 0;
}

.mod-item a {
    color: #0f2a6e;
    text-decoration: none;
    word-break: break-all;
    font-size: 0.85rem;
}

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

.mod-item button {
    align-self: flex-start;
    background: #ff6b6b;
    color: white;
    padding: 0.4rem 0.8rem;
    border: none;
    border-radius: 4px;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s ease;
}

.mod-item button:hover {
    background: #ff5252;
}

/* Footer */
footer {
    background-color: #1a3fb0;
    color: #ffffff;
    padding: 2rem;
    text-align: center;
    margin-top: 4rem;
    border-top: 3px solid #0f2a6e;
}

footer p {
    margin: 0.5rem 0;
    color: #cfe0ff;
}

footer .copyright {
    font-size: 0.9rem;
    color: #cfe0ff;
    margin-top: 1rem;
}

/*
    The station's social accounts, as a row of tappable marks.

    Sized in rem rather than px and given a 2.6rem target, because the row sits
    at the bottom of a page most people reach on a phone and a 24px glyph is not
    something a thumb can hit. The circle is drawn in the footer's own palette so
    the row reads as part of the footer rather than as four pasted brand badges,
    and the same rule covers hover and keyboard focus - a visitor tabbing through
    the footer can see where they are.
*/
.footer-social {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin: 1.1rem 0 0;
}

.footer-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    color: #cfe0ff;
    background: rgba(255, 255, 255, 0.08);
    transition: background-color 180ms ease, color 180ms ease, transform 180ms ease;
}

.footer-social-icon {
    width: 1.35rem;
    height: 1.35rem;
    display: block;
}

.footer-social-link:hover,
.footer-social-link:focus-visible {
    color: #0f2a6e;
    background: #ffffff;
    transform: translateY(-2px);
}

.footer-social-link:focus-visible {
    outline: 2px solid #cfe0ff;
    outline-offset: 3px;
}

/* The lift is decoration; the colour change carries the same information. */
@media (prefers-reduced-motion: reduce) {
    .footer-social-link {
        transition: none;
    }

    .footer-social-link:hover,
    .footer-social-link:focus-visible {
        transform: none;
    }
}

/*
    Footer links - the EEO report and FCC public file page above all, which a
    visitor and a regulator both expect to find in the footer rather than in the
    menu. A nav with a flex gap instead of a paragraph of separators, so a second
    link sits beside the first without any punctuation being typed into markup.
*/
.footer-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.35rem 1.25rem;
    margin: 1.25rem 0 0;
}

.footer-links a {
    color: #cfe0ff;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
}

.footer-links a:hover,
.footer-links a:focus-visible {
    color: #ffffff;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.footer-links a:focus-visible {
    outline: 2px solid #cfe0ff;
    outline-offset: 3px;
}

/* On the page itself the link stays, and says so. */
.footer-links a[aria-current="page"] {
    color: #ffffff;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Subscription Selection in Subscribe Form */
.subscription-selection {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 1rem 0;
    text-align: left;
}

.subscription-selection label {
    color: #1d4ed8;
    font-weight: 600;
    font-size: 0.95rem;
}

.plan-optional {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.12rem 0.45rem;
    border-radius: 999px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: rgba(29, 78, 216, 0.15);
    color: #0f2a6e;
}

.subscription-selection select {
    -webkit-appearance: none;
    appearance: none;
    padding: 0.9rem 2.7rem 0.9rem 0.95rem;
    border: 1px solid rgba(29, 78, 216, 0.55);
    background:
        linear-gradient(180deg, rgba(245, 247, 251, 0.98), rgba(255, 255, 255, 0.98)),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='10' viewBox='0 0 14 10'%3E%3Cpath d='M1 1l6 7 6-7' fill='none' stroke='%231d4ed8' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat, no-repeat;
    background-position: 0 0, calc(100% - 0.95rem) center;
    background-size: auto, 14px 10px;
    color: #44506b;
    border-radius: 12px;
    font-family: 'Poppins', sans-serif;
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
}

.subscription-selection select:focus {
    outline: none;
    border-color: #1d4ed8;
    box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.22);
    transform: translateY(-1px);
}

.subscription-selection select option {
    background-color: #ffffff;
    color: #44506b;
}

/* Subscription Info Card in Profile */
.subscription-info-card {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.3);
}

.sub-status {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.status-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem;
    border-bottom: 1px solid rgba(29, 78, 216, 0.15);
}

.status-row:last-child {
    border-bottom: none;
}

.status-label {
    color: #1d4ed8;
    font-weight: 600;
    font-size: 0.95rem;
}

.status-value {
    color: #44506b;
    font-size: 0.95rem;
    text-align: right;
}

.status-active {
    color: #4caf50;
    font-weight: 600;
}

/* Payment Card */
.payment-card {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.3);
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.payment-display {
    padding: 1rem;
    border-radius: 5px;
    background-color: rgba(29, 78, 216, 0.05);
    min-height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.payment-display.has-method {
    background-color: rgba(76, 175, 80, 0.1);
}

.payment-display .payment-info-text {
    color: #1d4ed8;
    font-weight: 600;
}

.btn-edit-payment {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
    border: none;
    padding: 0.8rem 1.5rem;
    font-size: 0.95rem;
    font-weight: 600;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s;
    font-family: 'Poppins', sans-serif;
}

.btn-edit-payment:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.4);
}

/* Payment Modal */
.payment-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(14, 25, 55, 0.55);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 2000;
}

.payment-modal.active {
    display: flex;
}

.payment-modal-content {
    background-color: #ffffff;
    padding: 2rem;
    border-radius: 10px;
    border: 2px solid #1d4ed8;
    max-width: 400px;
    width: 90%;
    box-shadow: 0 10px 40px rgba(29, 78, 216, 0.3);
}

.payment-modal-content h4 {
    color: #0f2a6e;
    margin: 0 0 1.5rem 0;
    font-size: 1.3rem;
}

#paymentForm {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

#paymentForm input {
    padding: 0.75rem;
    border: 2px solid #1d4ed8;
    background-color: #ffffff;
    color: #44506b;
    border-radius: 5px;
    font-family: 'Poppins', sans-serif;
}

#paymentForm input:focus {
    outline: none;
    background-color: #ffffff;
    box-shadow: 0 0 10px rgba(29, 78, 216, 0.3);
}

.payment-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

.payment-buttons {
    display: flex;
    gap: 1rem;
}

.btn-save-payment,
.btn-cancel-payment {
    flex: 1;
    padding: 0.8rem;
    border: none;
    border-radius: 5px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
    font-family: 'Poppins', sans-serif;
}

.btn-save-payment {
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
}

.btn-save-payment:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.4);
}

.btn-cancel-payment {
    background-color: #f5f7fb;
    color: #44506b;
}

.btn-cancel-payment:hover {
    background-color: #f5f7fb;
}

/* Subscriptions Grid in Modal */
.subscriptions-grid-modal {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: 2rem;
    margin-top: 2rem;
}

#subscriptionsModal .subscribe-modal-content {
    width: min(1120px, 95vw);
    max-width: 1120px;
}

#subscriptionsModal .subscriptions-grid-modal {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.25rem;
}

.subscription-card {
    background: linear-gradient(135deg, #ffffff 0%, #ffffff 100%);
    border: 2px solid #1d4ed8;
    border-radius: 12px;
    padding: 2.5rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
    text-align: center;
}

.subscription-card:hover {
    transform: translateY(-10px);
    box-shadow: 0 15px 40px rgba(29, 78, 216, 0.4);
    border-color: #1d4ed8;
}

.subscription-card.featured {
    border-color: #1d4ed8;
    box-shadow: 0 10px 30px rgba(29, 78, 216, 0.25);
}

.featured-badge {
    position: absolute;
    top: -15px;
    left: 50%;
    transform: translateX(-50%);
    background: linear-gradient(135deg, #1d4ed8 0%, #3b6ff2 100%);
    color: #ffffff;
    padding: 0.6rem 1.8rem;
    border-radius: 25px;
    font-weight: 700;
    font-size: 0.8rem;
    letter-spacing: 0.5px;
}

.subscription-card h3 {
    color: #0f2a6e;
    font-size: 1.6rem;
    margin: 0;
    font-weight: 700;
}

.sub-price {
    color: #44506b;
    font-size: 2.2rem;
    font-weight: 700;
    margin: 0;
}

.sub-price span {
    font-size: 0.9rem;
    color: #64708c;
    display: block;
    font-weight: 400;
    margin-top: 0.3rem;
}

.sub-features {
    list-style: none;
    padding: 0;
    margin: 0;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.sub-features li {
    color: #44506b;
    padding: 0.6rem 0.8rem;
    border-radius: 6px;
    font-size: 0.9rem;
    background-color: rgba(29, 78, 216, 0.08);
}

.sub-features li:nth-child(odd) {
    background-color: rgba(29, 78, 216, 0.12);
}

@media (max-width: 1024px) {
    #subscriptionsModal .subscriptions-grid-modal {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Responsive Design */
@media (max-width: 768px) {
    /* The bar stays on one line. A 150px-tall logo used to push the toggle and the
       LIVE NOW button onto a second row, which made the sticky header around 260px
       tall on a phone and ate most of the screen. */
    header {
        flex-wrap: nowrap;
        gap: 0.6rem;
        padding: 0.55rem 0.85rem;
    }

    header .logo {
        flex: 0 1 auto;
        min-width: 0;
    }

    header .logo img {
        height: 72px;
        max-width: 100%;
    }

    /* The panel hangs off the bottom edge of the header itself rather than from a
       fixed 88px offset. The old offset was shorter than the header, so the menu
       opened part-way down the bar: a strip of the header showed above it and the
       rest of the bar, including the toggle, sat underneath it. calc(100% + 3px)
       clears the header's gold bottom border, so the panel is flush at any height. */
    header .menu {
        display: none;
        position: absolute;
        top: calc(100% + 3px);
        left: 0;
        right: 0;
        flex-direction: column;
        background-color: #1a3fb0;
        box-shadow: 0 5px 15px rgba(16, 26, 56, 0.25);
        gap: 0;
        padding: 0.85rem 1rem 1rem;
        border-radius: 0 0 10px 10px;
        border-bottom: 3px solid #0f2a6e;
        z-index: 99;
        /* A full menu is taller than a phone screen, and the overflow used to run off
           the bottom of the page with no way to reach the last few links. The height
           variable is published by mobile-nav.js; the fallback covers the compact bar. */
        max-height: calc(100vh - var(--mst-header-height, 96px));
        max-height: calc(100dvh - var(--mst-header-height, 96px));
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }

    header .menu.active {
        display: flex;
    }

    header .menu-toggle {
        display: block;
        position: static;
        flex: 0 0 auto;
        font-size: 2.1rem;
        line-height: 1;
        padding: 0.5rem 0.7rem;
        min-width: 52px;
        min-height: 52px;
        border: 1px solid rgba(255, 255, 255, 0.45);
        border-radius: 8px;
        background: rgba(255, 255, 255, 0.12);
        color: #ffffff;
        /* Stops the double-tap zoom delay and the blue flash on tap. */
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
        -webkit-user-select: none;
        user-select: none;
    }

    header .menu-toggle:hover,
    header .menu-toggle:focus-visible {
        background: rgba(255, 255, 255, 0.2);
        border-color: #ffffff;
    }

    header .menu-toggle:active {
        background: rgba(255, 255, 255, 0.28);
    }

    header .menu li {
        width: 100%;
    }

    #signUpMenuItem,
    #signInMenuItem {
        margin: 0 0 0.55rem !important;
    }

    #signInMenuItem {
        margin-bottom: 0.8rem !important;
        padding-bottom: 0.35rem;
        border-bottom: 1px solid rgba(255, 255, 255, 0.3);
    }

    .nav-sign-in-btn,
    .nav-sign-up-btn {
        display: block;
        width: 100%;
        text-align: center;
        padding: 0.85rem 0.75rem;
        font-size: 1rem;
    }

    header .menu a {
        display: block;
        width: 100%;
        padding: 0.9rem 0.55rem;
        font-size: 1.05rem;
        font-weight: 600;
        border-bottom: 1px solid rgba(255, 255, 255, 0.22);
    }

    header .menu li:last-child a {
        border-bottom: none;
    }

    header .live-btn {
        font-size: 0.95rem;
        padding: 0.8rem 1rem;
        margin-left: auto;
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* Nothing on a phone should force a sideways scroll. */
    img,
    iframe,
    video {
        max-width: 100%;
    }

    /* iOS zooms the whole page in when a field under 16px takes focus, and it does
       not zoom back out afterwards. */
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="password"],
    input[type="search"],
    input[type="number"],
    input[type="url"],
    input[type="date"],
    select,
    textarea {
        font-size: 16px;
    }

    /* A radius only reads as a box if there is page showing beside it, so on a
       narrow screen the royal boxes come off the viewport edges rather than
       running corner-to-corner. The Our News box sets the same inset in its own
       block near the end of this file. */
    .hero {
        margin: 0 1rem 2.25rem;
        padding: 2.75rem 1.5rem;
        min-height: 0;
    }

    .hero h1 {
        font-size: 2rem;
    }

    section h2 {
        font-size: 1.8rem;
    }

    .station-grid, .news-grid, .event-grid, .live-now-grid, .local-listings-grid {
        grid-template-columns: 1fr;
    }

    #subscriptionsModal .subscribe-modal-content {
        width: 92vw;
        max-width: 92vw;
    }

    #subscriptionsModal .subscriptions-grid-modal {
        grid-template-columns: 1fr;
    }
}

/* Narrow phones. The three header items still have to share one line, so the logo
   and the LIVE NOW button give up a little more room. */
@media (max-width: 480px) {
    header {
        gap: 0.45rem;
        padding: 0.5rem 0.65rem;
    }

    header .logo img {
        height: 58px;
    }

    header .menu-toggle {
        font-size: 1.85rem;
        min-width: 48px;
        min-height: 48px;
        padding: 0.4rem 0.55rem;
    }

    header .live-btn {
        font-size: 0.82rem;
        padding: 0.7rem 0.75rem;
        letter-spacing: 0;
    }

    header .menu {
        padding: 0.7rem 0.8rem 0.85rem;
    }
}

/* News Modal */
.news-modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(14, 25, 55, 0.55);
    animation: fadeIn 0.3s;
}

.news-modal.active {
    display: flex;
    align-items: center;
    justify-content: center;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.news-modal-content {
    background-color: #ffffff;
    padding: 2rem;
    border-radius: 10px;
    border: 3px solid #1d4ed8;
    max-width: 800px;
    max-height: 80vh;
    overflow-y: auto;
    position: relative;
    box-shadow: 0 10px 40px rgba(29, 78, 216, 0.3);
}

.news-modal-content h2 {
    color: #1d4ed8;
    margin-bottom: 2rem;
    font-size: 2rem;
}

.close-btn,
.close-btn-events {
    color: #1d4ed8;
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    font-size: 3rem;
    font-weight: bold;
    cursor: pointer;
    transition: color 0.3s, transform 0.2s;
    line-height: 1;
    padding: 1rem;
    border-radius: 5px;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.close-btn:hover,
.close-btn-events:hover {
    color: #0f2a6e;
    transform: scale(1.15);
    background-color: rgba(29, 78, 216, 0.15);
}

.close-btn-local {
    color: #1d4ed8;
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    font-size: 3rem;
    font-weight: bold;
    cursor: pointer;
    transition: color 0.3s, transform 0.2s;
    line-height: 1;
    padding: 1rem;
    border-radius: 5px;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.close-btn-local:hover {
    color: #0f2a6e;
    transform: scale(1.15);
    background-color: rgba(29, 78, 216, 0.15);
}

.local-listings-modal-note {
    color: #44506b;
    margin: 0.2rem 0 0;
}

.local-listings-modal-actions {
    margin-top: 1rem;
}

.close-btn-advertise {
    color: #1d4ed8;
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    font-size: 3rem;
    font-weight: bold;
    cursor: pointer;
    transition: color 0.3s, transform 0.2s;
    line-height: 1;
    padding: 1rem;
    border-radius: 5px;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.close-btn-advertise:hover {
    color: #0f2a6e;
    transform: scale(1.15);
    background-color: rgba(29, 78, 216, 0.15);
}

.close-btn-subscribe {
    color: #1d4ed8;
    position: absolute;
    right: 0.5rem;
    top: 0.5rem;
    font-size: 2rem;
    font-weight: bold;
    cursor: pointer;
    transition: color 0.3s, transform 0.2s;
    line-height: 1;
    padding: 0.5rem;
    border-radius: 5px;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.close-btn-subscribe:hover {
    color: #0f2a6e;
    transform: scale(1.15);
    background-color: rgba(29, 78, 216, 0.15);
}

.modal-articles {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

.article {
    background-color: #ffffff;
    padding: 1.5rem;
    border-left: 4px solid #1d4ed8;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s;
}

.article:hover {
    background-color: #f5f7fb;
    border-left-color: #1d4ed8;
    box-shadow: 0 5px 15px rgba(29, 78, 216, 0.3);
    transform: translateX(5px);
}

.article a {
    text-decoration: none;
    color: inherit;
}

.article-link {
    text-decoration: none;
    display: block;
}

.article h3 {
    color: #1d4ed8;
    margin-bottom: 0.5rem;
    font-size: 1.3rem;
}

.article-thumb {
    width: 100%;
    max-height: 220px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.45);
    margin-bottom: 0.9rem;
    display: block;
}

.article .article-date {
    color: #64708c;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}

.article p {
    color: #44506b;
    line-height: 1.8;
    margin-bottom: 1rem;
}

.article p:last-child {
    margin-bottom: 0;
}

.article-source-link {
    margin-top: 0.75rem;
    font-size: 0.78rem;
    color: #0f2a6e;
    word-break: break-word;
}

.popup-article-admin-actions {
    margin-top: 0.8rem;
}

.popup-article-admin-actions .btn-update-prefs {
    margin-top: 0;
    padding: 0.45rem 0.75rem;
    font-size: 0.82rem;
}

.edit-article-actions {
    display: flex;
    gap: 0.65rem;
    flex-wrap: wrap;
    align-items: center;
}

.edit-article-actions .btn-submit {
    margin-top: 0;
}

.edit-article-cancel-btn {
    margin-top: 0;
    background: linear-gradient(135deg, #f5f7fb 0%, #ffffff 100%);
    color: #44506b;
    border: 1px solid rgba(29, 78, 216, 0.45);
}

.edit-article-image-upload {
    background: rgba(29, 78, 216, 0.08);
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 8px;
    padding: 0.7rem 0.8rem;
}

.edit-article-image-upload label {
    display: block;
    color: #0f2a6e;
    font-weight: 600;
    margin-bottom: 0.4rem;
}

.edit-article-image-upload input[type="file"] {
    width: 100%;
    color: #44506b;
}

.edit-article-image-note {
    margin: 0.45rem 0 0;
    color: #44506b;
    font-size: 0.82rem;
}

.edit-article-image-preview {
    margin-top: 0.7rem;
    max-width: 100%;
    max-height: 220px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid rgba(29, 78, 216, 0.5);
}

.event-detail {
    background-color: #ffffff;
    padding: 1.5rem;
    border-left: 4px solid #1d4ed8;
    border-radius: 5px;
    margin-bottom: 1.5rem;
}

.event-detail h3 {
    color: #1d4ed8;
    margin-bottom: 1.5rem;
    font-size: 1.5rem;
}

.event-meta {
    background-color: #f5f7fb;
    padding: 1.5rem;
    border-radius: 5px;
    margin-bottom: 1.5rem;
}

.event-meta p {
    color: #44506b;
    margin-bottom: 0.8rem;
    font-size: 1rem;
}

.event-meta p strong {
    color: #1d4ed8;
}

.event-description {
    color: #44506b;
    line-height: 1.9;
}

.event-description p {
    margin-bottom: 1.5rem;
}

.plan-detail {
    background-color: #ffffff;
    padding: 1.5rem;
    border-radius: 5px;
}

.plan-detail h3 {
    color: #1d4ed8;
    margin-bottom: 1rem;
    font-size: 1.8rem;
}

.plan-tagline {
    color: #64708c;
    font-size: 1.05rem;
    margin-bottom: 2rem;
}

.plan-features {
    background-color: #f5f7fb;
    padding: 1.5rem;
    border-radius: 5px;
    margin-bottom: 1.5rem;
}

.plan-features h4 {
    color: #1d4ed8;
    margin-bottom: 1rem;
}

.plan-features ul {
    list-style: none;
    padding: 0;
}

.plan-features li {
    color: #44506b;
    padding: 0.6rem 0;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid #dde3ee;
}

.plan-features li:last-child {
    border-bottom: none;
}

.plan-description {
    color: #44506b;
    line-height: 1.8;
    margin-bottom: 1.5rem;
}

.plan-description p {
    margin-bottom: 1.5rem;
}

.plan-cta {
    text-align: center;
    padding-top: 1.5rem;
    border-top: 2px solid #dde3ee;
}

.plan-cta .btn {
    background-color: #1d4ed8;
    color: #ffffff;
    padding: 0.9rem 2rem;
    border-radius: 5px;
    text-decoration: none;
    font-weight: 600;
    transition: all 0.3s;
    display: inline-block;
}

/* ---------------------------------------------------------------------------
   Moderator notifications — the bell in the header and the panel under it.

   The bell only exists for staff, so it is hidden by attribute rather than by a
   class: the markup ships with `hidden` and notifications.js removes it once the
   session looks like a moderator's. The !important matches the pattern the song
   request cards use, because `header .menu li` carries layout rules that would
   otherwise win against the browser's own [hidden] rule.
   --------------------------------------------------------------------------- */
.notif-menu-item {
    position: relative;
    display: flex;
    align-items: center;
}

.notif-menu-item[hidden] {
    display: none !important;
}

.notif-bell {
    position: relative;
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.55);
    border-radius: 50%;
    width: 2.6rem;
    height: 2.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    /* The bell is drawn as a stroked SVG, so the icon colour rides on `color`
       and picks up the same white the rest of the header uses. */
    color: #ffffff;
    transition: border-color 0.3s, background-color 0.3s, color 0.3s, transform 0.3s;
}

.notif-bell:hover,
.notif-bell:focus-visible {
    border-color: #ffffff;
    background-color: rgba(255, 255, 255, 0.18);
    color: #ffffff;
    transform: scale(1.05);
}

/* Something unread is worth noticing across the header, so the ring fills. */
.notif-bell.has-unread {
    border-color: #ffffff;
    background-color: rgba(255, 255, 255, 0.24);
    color: #ffffff;
}

.notif-bell-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.notif-bell-icon svg {
    width: 1.35rem;
    height: 1.35rem;
    display: block;
}

.notif-badge {
    position: absolute;
    top: -0.35rem;
    right: -0.35rem;
    min-width: 1.2rem;
    height: 1.2rem;
    padding: 0 0.28rem;
    border-radius: 999px;
    background-color: #d32f2f;
    color: #ffffff;
    font-family: 'Poppins', sans-serif;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.2rem;
    text-align: center;
    box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.18);
    animation: notifBadgePulse 2.4s ease-in-out infinite;
}

.notif-badge[hidden] {
    display: none;
}

@keyframes notifBadgePulse {
    0%, 100% { box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.18), 0 0 0 0 rgba(211, 47, 47, 0.55); }
    50% { box-shadow: 0 0 0 2px rgba(16, 26, 56, 0.18), 0 0 0 6px rgba(211, 47, 47, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .notif-badge {
        animation: none;
    }
}

.notif-panel {
    position: absolute;
    top: calc(100% + 0.75rem);
    right: 0;
    width: 23rem;
    max-width: calc(100vw - 2rem);
    background-color: #ffffff;
    border: 2px solid rgba(29, 78, 216, 0.55);
    border-radius: 10px;
    box-shadow: 0 12px 30px rgba(16, 26, 56, 0.55);
    z-index: 120;
    overflow: hidden;
    text-align: left;
}

.notif-panel[hidden] {
    display: none;
}

.notif-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 1rem;
    border-bottom: 1px solid rgba(29, 78, 216, 0.3);
}

.notif-panel-head h3 {
    color: #1d4ed8;
    font-size: 1.05rem;
    margin: 0;
}

.notif-link {
    background: none;
    border: none;
    color: #1d4ed8;
    font-family: 'Poppins', sans-serif;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0;
    transition: color 0.3s;
}

.notif-link:hover,
.notif-link:focus-visible {
    color: #0f2a6e;
    text-decoration: underline;
}

.notif-list {
    display: flex;
    flex-direction: column;
    max-height: 22rem;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.notif-empty {
    color: #64708c;
    font-size: 0.85rem;
    margin: 0;
    padding: 1.1rem 1rem;
}

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    padding: 0.2rem 0.5rem 0.2rem 0;
    border-bottom: 1px solid rgba(29, 78, 216, 0.16);
}

.notif-item:last-child {
    border-bottom: none;
}

/* An unread row carries the gold edge; a read one is left plain, so the panel
   reads as a list of work outstanding rather than a wall of history. The edge is
   an inset shadow rather than a border because marking a row read happens under
   the moderator's cursor: a real border would take its 3px back and shift the
   text sideways as they read it. */
.notif-item.is-unread {
    background-color: rgba(29, 78, 216, 0.08);
    box-shadow: inset 3px 0 0 rgba(29, 78, 216, 0.35);
}

.notif-item-main {
    flex: 1;
    /* Lets the button shrink inside the row so a long song title or a long
       address wraps instead of pushing the dismiss button off the panel. */
    min-width: 0;
    overflow-wrap: anywhere;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    padding: 0.75rem 0.5rem 0.75rem 0.85rem;
    font-family: 'Poppins', sans-serif;
}

.notif-item-main:hover .notif-item-title,
.notif-item-main:focus-visible .notif-item-title {
    color: #0f2a6e;
}

.notif-item-title {
    color: #1d4ed8;
    font-size: 0.9rem;
    font-weight: 600;
    transition: color 0.3s;
}

.notif-item-body {
    color: #44506b;
    font-size: 0.82rem;
    line-height: 1.45;
}

.notif-item-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #64708c;
    font-size: 0.72rem;
}

/* Said only to the moderator whose mailbox it was: with no mail delivered, this
   panel is the only warning they are getting. */
.notif-email-note {
    color: #c62828;
    font-size: 0.7rem;
}

.notif-item-dismiss {
    background: none;
    border: none;
    color: #64708c;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.7rem 0.4rem;
    transition: color 0.3s;
}

.notif-item-dismiss:hover,
.notif-item-dismiss:focus-visible {
    color: #c62828;
}

.notif-panel-foot {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 0.85rem 1rem;
    border-top: 1px solid rgba(29, 78, 216, 0.3);
    background-color: #ffffff;
}

.notif-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #44506b;
    font-size: 0.82rem;
    cursor: pointer;
}

.notif-toggle input {
    accent-color: #1d4ed8;
    width: 1rem;
    height: 1rem;
    cursor: pointer;
}

.notif-hint {
    color: #64708c;
    font-size: 0.72rem;
    line-height: 1.4;
    margin: 0;
}

.notif-hint[hidden] {
    display: none;
}

.notif-panel-foot .notif-link {
    align-self: flex-start;
}

/* On a phone the menu is already a scrolling dropdown, so the panel joins the
   column in flow instead of hanging off a row inside it. */
@media (max-width: 768px) {
    .notif-menu-item {
        flex-direction: column;
        align-items: stretch;
        gap: 0.6rem;
        padding-bottom: 0.6rem;
        border-bottom: 1px solid rgba(29, 78, 216, 0.2);
    }

    .notif-bell {
        width: 100%;
        border-radius: 25px;
        height: 2.8rem;
        gap: 0.5rem;
    }

    .notif-bell::after {
        content: 'Notifications';
        color: #ffffff;
        font-family: 'Poppins', sans-serif;
        font-size: 1rem;
        font-weight: 600;
    }

    /* The phone menu scrolls, so a badge hanging off the pill's corner would be
       clipped by that scroll box. Tuck it inside the pill instead. */
    .notif-badge {
        top: 50%;
        right: 0.85rem;
        transform: translateY(-50%);
    }

    .notif-panel {
        position: static;
        width: auto;
        max-width: none;
        box-shadow: none;
    }

    .notif-list {
        max-height: 16rem;
    }
}

/* ---------------------------------------------------------------------------
   The staff hot bar — a dock of shortcuts an admin or moderator builds out of
   the site's own buttons by pressing and holding them.

   It sits against the right edge, vertically centred, because the two other
   floating things on this site are already spoken for: the mini player holds
   the bottom-left and the toast holds the bottom-right. The dock is capped at
   eight shortcuts so it can never grow taller than a short viewport, which is
   also why it needs no scroll box — a scroll box would clip the labels that
   fly out to the left of each button.
   --------------------------------------------------------------------------- */
.hot-bar {
    position: fixed;
    top: 50%;
    right: 0.85rem;
    transform: translateY(-50%);
    /* Above the page and its header (100), below every modal (1000 and up), the
       mini player (2000) and the toast (2100). A dock of shortcuts is furniture:
       it must never cover a dialog, or a message about the dock itself. */
    z-index: 900;
    font-family: 'Poppins', sans-serif;
}

.hot-bar[hidden] {
    display: none;
}

/* The phone menu opens as a full-height panel over the page, and the dock sits
   right where it lands. Stand the dock down until the menu is closed again. */
body:has(header .menu.active) .hot-bar {
    display: none;
}

.hot-bar-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.45rem;
    border-radius: 999px;
    border: 1px solid rgba(29, 78, 216, 0.5);
    background: linear-gradient(160deg, rgba(255, 255, 255, 0.96), rgba(245, 247, 251, 0.93));
    box-shadow: 0 14px 30px rgba(16, 26, 56, 0.45);
    backdrop-filter: blur(5px);
    transition: gap 0.24s ease, padding 0.24s ease;
}

/* Collapsed, the dock is just its own handle — a moderator reading an article
   should not have to work around a column of shortcuts. */
.hot-bar.is-collapsed .hot-bar-items,
.hot-bar.is-collapsed .hot-bar-done {
    display: none;
}

.hot-bar-collapse {
    position: relative;
    width: 1.7rem;
    height: 1.7rem;
    flex: none;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: rgba(29, 78, 216, 0.16);
    color: #1d4ed8;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.24s ease, color 0.24s ease;
}

/* One bar is the "hide" affordance; the crossing bar appears when the dock is
   collapsed, turning it into a plus that reads as "there is more here". */
.hot-bar-collapse::before,
.hot-bar-collapse::after {
    content: '';
    position: absolute;
    width: 0.85rem;
    height: 0.18rem;
    border-radius: 999px;
    background: currentColor;
}

.hot-bar-collapse::after {
    transform: rotate(90deg);
    opacity: 0;
    transition: opacity 0.24s ease;
}

.hot-bar.is-collapsed .hot-bar-collapse {
    width: 2rem;
    height: 2rem;
}

.hot-bar.is-collapsed .hot-bar-collapse::after {
    opacity: 1;
}

.hot-bar-collapse:hover,
.hot-bar-collapse:focus-visible {
    background: rgba(29, 78, 216, 0.3);
    color: #0f2a6e;
}

.hot-bar-items {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
}

.hot-bar-slot {
    position: relative;
    display: flex;
    /* The shake animates `transform`, so the slot owns transform and the button
       inside owns the hover scale. Nesting them keeps the two off each other. */
    align-items: center;
    justify-content: center;
}

.hot-bar-btn {
    position: relative;
    width: 2.9rem;
    height: 2.9rem;
    padding: 0;
    border: 2px solid rgba(29, 78, 216, 0.55);
    border-radius: 50%;
    background: linear-gradient(150deg, rgba(245, 247, 251, 0.96), rgba(255, 255, 255, 0.96));
    color: #1d4ed8;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.24s ease, color 0.24s ease, transform 0.24s ease, background-color 0.24s ease;
}

.hot-bar-btn:hover,
.hot-bar-btn:focus-visible {
    border-color: #1d4ed8;
    color: #0f2a6e;
    transform: scale(1.08);
}

.hot-bar-btn-ghost {
    border-style: dashed;
    border-color: rgba(29, 78, 216, 0.4);
    color: rgba(29, 78, 216, 0.75);
    background: transparent;
}

.hot-bar-icon {
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1;
    pointer-events: none;
}

.hot-bar-btn-ghost .hot-bar-icon {
    font-size: 1.3rem;
    font-weight: 400;
}

/* The label flies out to the left on hover rather than living in the dock, so
   eight shortcuts stay a narrow column instead of a second menu. */
.hot-bar-label {
    position: absolute;
    right: calc(100% + 0.6rem);
    top: 50%;
    padding: 0.32rem 0.6rem;
    border-radius: 7px;
    border: 1px solid rgba(29, 78, 216, 0.5);
    background: rgba(255, 255, 255, 0.97);
    color: #44506b;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transform: translateY(-50%) translateX(6px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.hot-bar-btn:hover .hot-bar-label,
.hot-bar-btn:focus-visible .hot-bar-label {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}

/* A label under a shaking button is unreadable, and in edit mode the badge is
   the thing to look at anyway. */
.hot-bar.is-editing .hot-bar-label {
    display: none;
}

.hot-bar-remove {
    position: absolute;
    top: -0.15rem;
    left: -0.15rem;
    width: 1.3rem;
    height: 1.3rem;
    padding: 0;
    border: 2px solid #dde3ee;
    border-radius: 50%;
    background-color: #d32f2f;
    color: #ffffff;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 2;
}

.hot-bar.is-editing .hot-bar-remove {
    display: flex;
}

.hot-bar-remove:hover,
.hot-bar-remove:focus-visible {
    background-color: #f44336;
    transform: scale(1.1);
}

.hot-bar-done {
    display: none;
    padding: 0.3rem 0.7rem;
    border: 1px solid rgba(29, 78, 216, 0.55);
    border-radius: 999px;
    background: rgba(29, 78, 216, 0.16);
    color: #0f2a6e;
    font-family: 'Poppins', sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
}

.hot-bar.is-editing .hot-bar-done {
    display: block;
}

/* The shake. Staggered by position so the dock wobbles the way a home screen
   does rather than marching in step. */
@keyframes hotBarJiggle {
    0%, 100% { transform: rotate(-2.4deg) translateY(-0.6px); }
    50% { transform: rotate(2.4deg) translateY(0.6px); }
}

.hot-bar.is-editing .hot-bar-slot {
    animation: hotBarJiggle 0.25s ease-in-out infinite;
}

.hot-bar.is-editing .hot-bar-slot:nth-child(even) {
    animation-delay: -0.12s;
    animation-duration: 0.27s;
}

.hot-bar.is-editing .hot-bar-slot:nth-child(3n) {
    animation-duration: 0.23s;
}

/* A newly pinned shortcut announces itself once. */
@keyframes hotBarPop {
    0% { transform: scale(0.55); opacity: 0.2; }
    60% { transform: scale(1.16); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}

.hot-bar-slot.just-added {
    animation: hotBarPop 0.42s ease-out;
}

/* The "charging" cue while a button is being held. It is deliberately on every
   pinnable control, not just the dock, so a hold reads as doing something from
   the first moment — and it suppresses the touch callout that a long press on a
   phone would otherwise raise over the top of it. */
.hot-bar-pressing {
    -webkit-touch-callout: none;
    user-select: none;
    -webkit-user-select: none;
    animation: hotBarCharge 0.5s ease-out forwards;
}

@keyframes hotBarCharge {
    0% { box-shadow: 0 0 0 0 rgba(29, 78, 216, 0); }
    100% { box-shadow: 0 0 0 4px rgba(29, 78, 216, 0.45); }
}

@media (prefers-reduced-motion: reduce) {
    .hot-bar.is-editing .hot-bar-slot,
    .hot-bar-slot.just-added,
    .hot-bar-pressing {
        animation: none;
    }

    /* Without the shake, edit mode still has to be obvious. */
    .hot-bar.is-editing .hot-bar-btn {
        border-style: dashed;
        border-color: #1d4ed8;
    }

    .hot-bar-pressing {
        outline: 3px solid rgba(29, 78, 216, 0.6);
    }
}

@media (max-width: 768px) {
    .hot-bar {
        right: 0.5rem;
    }

    .hot-bar-btn {
        width: 2.6rem;
        height: 2.6rem;
    }

    .hot-bar-icon {
        font-size: 0.85rem;
    }
}
/* ===========================================================================
   Our News - the station's own reporting desk
   ===========================================================================

   The first thing on the page, above the sponsor strip and the hero, and it
   borrows the hero's royal band so the two read as one piece of chrome at the
   top of the site rather than two competing panels.

   The shape is a video spot with the story folded underneath it. The clip is
   always mounted - this segment exists for the clip - while the script hides
   behind a button, because a full script printed here would push the hero off
   the screen and nobody reads a script they did not ask for.

   Everything news-desk.js draws is in here. Nothing is styled by element, so
   the script's markup can grow without this block guessing at it.
   ------------------------------------------------------------------------- */

/* The generic `section` rule caps every box at 1200px and gives it no vertical
   margin at all, so boxes touch and rely on their own padding to keep apart.
   That works while they are light panels on a light page - and fails here,
   because this box carries the hero's royal gradient and would butt straight
   into the hero, the two reading as one slab of blue.

   So this one holds its own air and its own edges: space above it to clear the
   sticky header, more below so the sponsor strip and the hero start well clear
   of it, and a radius and a shadow that lift it off the page as a box in its
   own right rather than a band bleeding into the next. */
.ournews {
    margin: 2.25rem auto 3.5rem;
    padding: 3.25rem 2.5rem 3rem;
    border-radius: 22px;
    background: linear-gradient(135deg, #12307f 0%, #2a5be0 100%);
    color: white;
    box-shadow: 0 22px 50px rgba(10, 27, 68, 0.26);
}

.ournews[hidden] {
    /* Written out because an explicit display would otherwise beat the
       attribute, which is how the sponsor boards behave too. */
    display: none;
}

.ournews-inner {
    max-width: 1080px;
    margin: 0 auto;
}

/* ------------------------------------------------------------------ head --- */

.ournews-head {
    text-align: center;
    margin-bottom: 2.25rem;
}

.ournews-kicker {
    margin: 0 0 0.6rem;
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: #cfe0ff;
}

.ournews-head h2 {
    margin: 0 0 0.75rem;
    font-size: 2.6rem;
    line-height: 1.1;
    font-weight: 800;
    color: white;
}

.ournews-head h2 span {
    color: #cfe0ff;
}

.ournews-lede {
    max-width: 640px;
    margin: 0 auto;
    font-size: 1.1rem;
    line-height: 1.6;
    color: #cfe0ff;
}

.ournews-primary {
    margin-top: 1.5rem;
    padding: 0.8rem 1.9rem;
    border: 0;
    border-radius: 999px;
    background: white;
    color: #12307f;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
    box-shadow: 0 10px 24px rgba(8, 24, 64, 0.28);
}

.ournews-primary:hover:not([disabled]) {
    transform: translateY(-2px);
    box-shadow: 0 14px 30px rgba(8, 24, 64, 0.34);
}

.ournews-primary[disabled] {
    opacity: 0.6;
    cursor: default;
}

/* ---------------------------------------------------------------- notice --- */

.ournews-notice {
    max-width: 640px;
    margin: 0 auto 1.75rem;
    padding: 0.85rem 1.1rem;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    background: rgba(255, 255, 255, 0.14);
    color: white;
    font-size: 0.95rem;
    text-align: center;
}

.ournews-notice-error {
    border-color: rgba(255, 196, 196, 0.6);
    background: rgba(120, 18, 18, 0.35);
}

.ournews-notice-ok {
    border-color: rgba(198, 255, 214, 0.55);
    background: rgba(12, 88, 46, 0.32);
}

/* --------------------------------------------------------------- feature --- */

/*
    The segment before its stories arrive.

    It stands in the same box the real story occupies - the same panel, the same
    16:9 hole, three lines where the headline and summary go - so the story
    replaces it in space that was already reserved and nothing below moves. That
    is the whole point of it: the section used to be absent until its fetch
    landed, which is what made it look like it arrived after the rest of the
    page.
*/
.ournews-skeleton {
    background: rgba(6, 20, 56, 0.34);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 24px 60px rgba(6, 18, 48, 0.4);
}

.ournews-skeleton-video {
    aspect-ratio: 16 / 9;
    background: #0a1b44;
}

.ournews-skeleton-lines {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding: 1.75rem 1.9rem 1.6rem;
}

.ournews-skeleton-lines span {
    display: block;
    height: 0.85rem;
    border-radius: 999px;
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.08) 0%,
        rgba(255, 255, 255, 0.16) 50%,
        rgba(255, 255, 255, 0.08) 100%
    );
    background-size: 220% 100%;
    animation: ournews-shimmer 1.4s ease-in-out infinite;
}

/* Headline, then two shorter lines of summary. */
.ournews-skeleton-lines span:nth-child(1) {
    height: 1.4rem;
    width: 72%;
}

.ournews-skeleton-lines span:nth-child(2) {
    width: 100%;
}

.ournews-skeleton-lines span:nth-child(3) {
    width: 84%;
}

@keyframes ournews-shimmer {
    from { background-position: 120% 0; }
    to { background-position: -120% 0; }
}

/* Said once, for a screen reader, without a line of text appearing under the
   placeholder for everyone else. */
.ournews-skeleton-status {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .ournews-skeleton-lines span {
        animation: none;
    }
}

.ournews-feature {
    background: rgba(6, 20, 56, 0.34);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 24px 60px rgba(6, 18, 48, 0.4);
}

/* The spot keeps a 16:9 hole whether or not the clip has loaded, so the page
   does not jump when the first frame arrives. */
.ournews-spot {
    position: relative;
    aspect-ratio: 16 / 9;
    background: #0a1b44;
}

.ournews-video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #0a1b44;
}

/*
    A YouTube story fills the same hole the uploaded player does. The iframe is
    given no border of its own and stretched to the spot, so the two sources are
    indistinguishable in the layout - only the controls inside differ.
*/
.ournews-embed {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
    background: #0a1b44;
}

/*
    A story filed as something other than a clip.

    The 16:9 hole above exists so the page does not jump while a video loads. A
    photograph, a recording and a download have no such loading step and no
    reason to be letterboxed into a video's shape, so those kinds release the
    ratio and take the height their own content needs.
*/
.ournews-spot-image,
.ournews-spot-audio,
.ournews-spot-file {
    aspect-ratio: auto;
}

/*
    The shuffle: every picture stacked in one frame, one of them at full
    opacity. Stacking rather than swapping a src means the fade has both
    pictures to work with and no blank frame in between, and it is why the
    slides are absolutely positioned over a sized box rather than laid out.

    The box keeps 16:9 even though a photograph story otherwise releases it:
    stills of different shapes are about to take turns in this space, and
    without a fixed hole the page would jump on every advance.
*/
.ournews-spot-gallery {
    aspect-ratio: 16 / 9;
}

.ournews-gallery {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
}

.ournews-slides {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: #0a1b44;
}

.ournews-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 900ms ease;
    pointer-events: none;
}

/* The picture itself, whole: nothing of a photograph is cropped away to make
   it fit the frame, because the bit cropped off a news photograph is as likely
   as not to be the bit that matters. */
.ournews-shot {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* What fills the frame around it. The same picture, cropped to cover, blown up
   past the edges so the blur has something to smear, and pushed back with a
   dimmer so it reads as a background rather than a second photograph. */
.ournews-fill {
    position: absolute;
    inset: -8%;
    width: 116%;
    height: 116%;
    object-fit: cover;
    filter: blur(28px) saturate(1.15) brightness(0.62);
    transform: scale(1.06);
}

.ournews-slide.is-current {
    opacity: 1;
}

/* Over the picture rather than under it, so the frame stays the frame. */
.ournews-gallery-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 3.1rem;
    margin: 0;
    padding: 0.55rem 1rem;
    font-size: 0.86rem;
    line-height: 1.35;
    color: #f2f6ff;
    text-align: center;
    text-shadow: 0 1px 3px rgba(4, 12, 32, 0.9);
    background: linear-gradient(to top, rgba(4, 12, 32, 0.72), rgba(4, 12, 32, 0));
    pointer-events: none;
}

.ournews-gallery-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    background: linear-gradient(to top, rgba(4, 12, 32, 0.8), rgba(4, 12, 32, 0));
}

.ournews-gallery-arrow,
.ournews-gallery-pause {
    border: 1px solid rgba(233, 240, 255, 0.35);
    border-radius: 999px;
    background: rgba(6, 18, 48, 0.6);
    color: #f2f6ff;
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.ournews-gallery-arrow {
    width: 2rem;
    height: 2rem;
    font-size: 1.25rem;
}

.ournews-gallery-pause {
    padding: 0.35rem 0.7rem;
    font-size: 0.78rem;
}

.ournews-gallery-arrow:hover,
.ournews-gallery-pause:hover,
.ournews-gallery-arrow:focus-visible,
.ournews-gallery-pause:focus-visible {
    background: rgba(12, 34, 86, 0.9);
}

.ournews-dots {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.ournews-dot {
    width: 0.62rem;
    height: 0.62rem;
    padding: 0;
    border: 1px solid rgba(233, 240, 255, 0.7);
    border-radius: 50%;
    background: rgba(6, 18, 48, 0.55);
    cursor: pointer;
}

.ournews-dot.is-current {
    background: #f2f6ff;
}

/* Nothing fades for a visitor who asked for less movement; the shuffle stops
   in the script as well, so the picture on screen simply stays. */
@media (prefers-reduced-motion: reduce) {
    .ournews-slide {
        transition: none;
    }
}

/* Says what is chosen and still waiting to be sent. Empty most of the time,
   so it takes no room until it has something to say. */
.ournews-photo-ready:not(:empty) {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    opacity: 0.85;
    overflow-wrap: anywhere;
}

/* The desk's list of a story's pictures, inside the story form. */
.ournews-photo-admin {
    margin: 0.4rem 0 0.2rem;
}

.ournews-photo-title {
    margin: 0 0 0.5rem;
    font-size: 0.92rem;
}

.ournews-photo-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.ournews-photo-row {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-wrap: wrap;
}

.ournews-photo-thumb {
    width: 4.2rem;
    height: 3rem;
    object-fit: cover;
    border-radius: 6px;
    background: #0a1b44;
}

.ournews-photo-main {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1 1 12rem;
    min-width: 10rem;
}

.ournews-photo-count {
    font-size: 0.75rem;
    opacity: 0.75;
}

.ournews-photo-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}

.ournews-still-wrap {
    display: block;
}

.ournews-still {
    display: block;
    width: 100%;
    height: auto;
    max-height: 70vh;
    object-fit: contain;
    background: #0a1b44;
}

/* A recording has nothing to look at, so the tile is the label and the bar. */
.ournews-audio {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.85rem;
    padding: 2.2rem 1.6rem;
    background: #0a1b44;
}

/* The speaker, drawn in borders rather than loading an icon font for it. */
.ournews-audio-mark {
    width: 0;
    height: 0;
    border-top: 0.9rem solid transparent;
    border-bottom: 0.9rem solid transparent;
    border-right: 1.3rem solid rgba(207, 224, 255, 0.92);
}

.ournews-audio-label {
    margin: 0;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #cfe0ff;
}

.ournews-audio-player {
    width: 100%;
    max-width: 30rem;
}

/* A document: what it is, what it is called, how big, and a way to get it. */
.ournews-file {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    padding: 2.2rem 1.6rem;
    text-align: center;
    background: #0a1b44;
}

.ournews-file-badge {
    padding: 0.4rem 0.9rem;
    border-radius: 9px;
    background: #cfe0ff;
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    color: #0a1b44;
}

.ournews-file-name {
    margin: 0;
    overflow-wrap: anywhere;
    font-weight: 700;
    color: white;
}

.ournews-file-size {
    margin: 0;
    font-size: 0.82rem;
    color: #cfe0ff;
}

.ournews-file-link {
    margin-top: 0.4rem;
    padding: 0.6rem 1.3rem;
    border-radius: 999px;
    background: #cfe0ff;
    font-weight: 800;
    color: #0a1b44;
    text-decoration: none;
}

.ournews-file-link:hover,
.ournews-file-link:focus-visible {
    background: white;
}

.ournews-feature-text {
    padding: 1.75rem 1.9rem 1.6rem;
}

.ournews-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.85rem;
}

.ournews-beat {
    padding: 0.3rem 0.8rem;
    border-radius: 999px;
    background: #cfe0ff;
    color: #12307f;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.ournews-where {
    font-size: 0.85rem;
    color: #cfe0ff;
}

/* The beat class news-desk.js hangs on the article tints its chip. Police and
   fire are the two a reader scans for, so those are the ones that leave the
   house palette; the rest stay the pale blue the band is built from. */
.ournews-beat-police .ournews-beat {
    background: #d8e4ff;
    color: #0f2a6e;
}

.ournews-beat-fire .ournews-beat {
    background: #ffd9c9;
    color: #7a2a08;
}

.ournews-beat-weather .ournews-beat {
    background: #d4f0f7;
    color: #0b4a58;
}

.ournews-headline {
    margin: 0 0 0.7rem;
    font-size: 1.7rem;
    line-height: 1.25;
    font-weight: 800;
    color: white;
}

.ournews-summary {
    margin: 0;
    font-size: 1.02rem;
    line-height: 1.65;
    color: #dbe7ff;
}

/* ------------------------------------------------------------- the fold --- */

.ournews-more {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1.4rem;
    padding: 0.75rem 1.4rem;
    border: 1px solid rgba(255, 255, 255, 0.45);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    font-family: inherit;
    font-size: 0.92rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.18s ease, border-color 0.18s ease;
}

.ournews-more:hover {
    background: rgba(255, 255, 255, 0.2);
    border-color: white;
}

.ournews-caret {
    width: 0;
    height: 0;
    border-left: 0.32rem solid transparent;
    border-right: 0.32rem solid transparent;
    border-top: 0.4rem solid currentColor;
    transition: transform 0.22s ease;
}

.ournews-more.is-open .ournews-caret {
    transform: rotate(180deg);
}

.ournews-drop[hidden] {
    display: none;
}

.ournews-drop {
    margin-top: 1.3rem;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
}

/* Animated rather than snapped open, because the segment is the top of the
   page and a jump here shoves the whole document. */
.ournews-drop.is-open .ournews-drop-inner {
    animation: ournews-unfold 0.26s ease-out both;
}

@keyframes ournews-unfold {
    from {
        opacity: 0;
        transform: translateY(-0.5rem);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.ournews-drop-inner {
    padding-top: 1.3rem;
}

.ournews-script-title {
    margin: 0 0 0.75rem;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: #cfe0ff;
}

/* The script is what a presenter reads on air, so it gets a measured column and
   real line height rather than the tighter body setting. */
.ournews-script {
    max-width: 62ch;
    color: white;
    font-size: 1.05rem;
    line-height: 1.85;
}

.ournews-script p {
    margin: 0 0 1.1rem;
}

.ournews-script p:last-child {
    margin-bottom: 0;
}

.ournews-script-empty {
    color: #cfe0ff;
    font-style: italic;
}

/* --------------------------------------------------------------- picker --- */

.ournews-picker {
    margin-top: 2rem;
}

.ournews-picker-title {
    margin: 0 0 1rem;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: #cfe0ff;
}

.ournews-picker-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ournews-pick {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    width: 100%;
    padding: 0.7rem;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 14px;
    background: rgba(6, 20, 56, 0.3);
    color: white;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease,
        transform 0.18s ease;
}

.ournews-pick:hover {
    border-color: white;
    background: rgba(6, 20, 56, 0.45);
    transform: translateY(-2px);
}

.ournews-pick.is-current {
    border-color: white;
    background: rgba(255, 255, 255, 0.16);
    cursor: default;
    transform: none;
}

.ournews-thumb {
    position: relative;
    flex: 0 0 auto;
    display: block;
    width: 96px;
    aspect-ratio: 16 / 9;
    border-radius: 9px;
    overflow: hidden;
    background: #0a1b44;
}

.ournews-thumb-small {
    width: 96px;
}

.ournews-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ournews-thumb-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    color: #cfe0ff;
}

/* A triangle drawn in borders, so a still with no poster still reads as a
   clip and no icon font has to load for it. */
.ournews-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 0;
    height: 0;
    border-top: 0.42rem solid transparent;
    border-bottom: 0.42rem solid transparent;
    border-left: 0.66rem solid rgba(255, 255, 255, 0.92);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}

.ournews-length {
    position: absolute;
    right: 0.25rem;
    bottom: 0.25rem;
    padding: 0.1rem 0.32rem;
    border-radius: 5px;
    background: rgba(6, 18, 48, 0.82);
    font-size: 0.66rem;
    font-weight: 700;
    color: white;
}

.ournews-pick-text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.ournews-pick-beat {
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #cfe0ff;
}

.ournews-pick-title {
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.35;
    color: white;
}

/* ---------------------------------------------------------------- admin --- */

.ournews-admin-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1.5rem;
    padding-top: 1.2rem;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.ournews-admin-space {
    flex: 1 1 auto;
}

.ournews-state {
    padding: 0.28rem 0.7rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.ournews-state-live {
    background: #cfe0ff;
    color: #12307f;
}

.ournews-state-off {
    background: rgba(255, 255, 255, 0.18);
    color: white;
}

.ournews-state-wait {
    background: rgba(255, 214, 140, 0.9);
    color: #4a2c00;
}

/* Published, but past the front page's ten: readers find it under Local News. */
.ournews-state-archive {
    background: rgba(255, 255, 255, 0.9);
    color: #44506b;
}

.ournews-mini {
    padding: 0.42rem 0.85rem;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 8px;
    background: transparent;
    color: white;
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.16s ease, border-color 0.16s ease;
}

.ournews-mini:hover:not([disabled]) {
    background: rgba(255, 255, 255, 0.18);
    border-color: white;
}

.ournews-mini[disabled] {
    opacity: 0.45;
    cursor: default;
}

.ournews-mini-danger:hover:not([disabled]) {
    background: rgba(146, 22, 22, 0.6);
    border-color: #ffc4c4;
}

/* ----------------------------------------------------------------- form --- */

/* The upload form is the one white surface in the band: it is a working panel
   with real inputs, and white-on-royal fields would fight the site's forms
   everywhere else. */
.ournews-form {
    max-width: 760px;
    margin: 0 auto 2rem;
    padding: 1.75rem;
    border-radius: 18px;
    background: white;
    color: #16203a;
    text-align: left;
    box-shadow: 0 22px 50px rgba(6, 18, 48, 0.36);
}

.ournews-form-title {
    margin: 0 0 1.4rem;
    font-size: 1.25rem;
    font-weight: 800;
    color: #12307f;
}

.ournews-field {
    display: block;
    margin-bottom: 1.1rem;
}

.ournews-field > span {
    display: block;
    margin-bottom: 0.4rem;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #44506b;
}

.ournews-field input[type="text"],
.ournews-field select,
.ournews-field textarea {
    width: 100%;
    padding: 0.7rem 0.85rem;
    border: 1px solid #dde3ee;
    border-radius: 10px;
    background: #f5f7fb;
    color: #16203a;
    font-family: inherit;
    font-size: 0.95rem;
}

.ournews-field textarea {
    min-height: 200px;
    line-height: 1.7;
    resize: vertical;
}

.ournews-field input:focus,
.ournews-field select:focus,
.ournews-field textarea:focus {
    outline: 2px solid #3b6ff2;
    outline-offset: 1px;
    background: white;
}

.ournews-field input[type="file"] {
    width: 100%;
    font-family: inherit;
    font-size: 0.9rem;
    color: #44506b;
}

.ournews-hint {
    display: block;
    margin: 0.4rem 0 0;
    font-size: 0.82rem;
    line-height: 1.5;
    color: #64708c;
}

/* Headline beside beat, where beside filed-by: the pairs belong together and
   the narrow half is the one that only ever holds a short value. */
.ournews-field-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.1rem;
}

@media (min-width: 620px) {
    .ournews-field-row {
        grid-template-columns: 2fr 1fr;
    }

    .ournews-field-row:not(:has(.ournews-field-small)) {
        grid-template-columns: 1fr 1fr;
    }
}

.ournews-progress {
    margin: 0 0 1rem;
    padding: 0.7rem 0.9rem;
    border-radius: 10px;
    background: #eef1f7;
    font-size: 0.88rem;
    font-weight: 600;
    color: #12307f;
}

.ournews-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* Inside the white panel the primary button flips to royal-on-white: the
   white pill it is in the band would disappear here. */
.ournews-form .ournews-primary {
    margin-top: 0;
    padding: 0.75rem 1.7rem;
    background: #1d4ed8;
    color: white;
    box-shadow: none;
}

.ournews-form .ournews-primary:hover:not([disabled]) {
    background: #12307f;
    transform: none;
    box-shadow: none;
}

.ournews-secondary {
    padding: 0.75rem 1.5rem;
    border: 1px solid #dde3ee;
    border-radius: 999px;
    background: white;
    color: #44506b;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}

.ournews-secondary:hover:not([disabled]) {
    border-color: #1d4ed8;
    color: #1d4ed8;
}

.ournews-secondary[disabled] {
    opacity: 0.6;
    cursor: default;
}

/* ---------------------------------------------------------------- empty --- */

.ournews-empty {
    max-width: 560px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem;
    border: 1px dashed rgba(255, 255, 255, 0.4);
    border-radius: 16px;
    text-align: center;
    font-size: 1rem;
    color: #cfe0ff;
}

/* ----------------------------------------------------------- responsive --- */

@media (max-width: 768px) {
    .ournews {
        margin: 1.25rem 1rem 2.25rem;
        padding: 2.25rem 1.25rem 2rem;
        border-radius: 16px;
    }

    .ournews-head h2 {
        font-size: 2rem;
    }

    .ournews-lede {
        font-size: 1rem;
    }

    .ournews-feature-text {
        padding: 1.35rem 1.25rem 1.25rem;
    }

    .ournews-headline {
        font-size: 1.35rem;
    }

    .ournews-more {
        width: 100%;
        justify-content: center;
    }

    .ournews-picker-list {
        grid-template-columns: 1fr;
    }

    .ournews-form {
        padding: 1.35rem;
    }

    .ournews-form-actions > button {
        flex: 1 1 auto;
    }
}

@media (max-width: 480px) {
    .ournews-head h2 {
        font-size: 1.7rem;
    }

    .ournews-thumb,
    .ournews-thumb-small {
        width: 78px;
    }
}

/* Swapping the spot and unfolding the script are both view transitions; with
   motion turned down they become plain redraws. */
@media (prefers-reduced-motion: reduce) {

    .ournews-primary,
    .ournews-pick,
    .ournews-caret {
        transition: none;
    }

    .ournews-primary:hover:not([disabled]),
    .ournews-pick:hover {
        transform: none;
    }

    .ournews-drop.is-open .ournews-drop-inner {
        animation: none;
    }
}

/* ============================================================
   Fitting the window — the last word in the stylesheet, so it is
   the safety net under everything above rather than a rule any of
   it has to work around.

   Two ideas only:

     - Nothing is allowed to be wider than the window. A picture, a
       table, a code block or a link long enough to be its own line
       will otherwise push the page out sideways, and a page that
       scrolls sideways on a phone is the one thing a reader cannot
       fix by turning the device.

     - The page's own rules win. Every selector here is wrapped in
       `:where()`, which has no specificity at all, so a class
       anywhere above this block overrides it without needing
       `!important` - the sponsor tiles, for one, deliberately let a
       logo fill its box and still do.
   ============================================================ */

html {
    /* A phone turned from landscape back to portrait inflates text to fill the
       narrower column unless it is told not to, which is how one paragraph ends
       up a size larger than the one above it. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

:where(img, svg, video, canvas, iframe, embed, object) {
    max-width: 100%;
}

:where(img, video) {
    /* So a picture narrowed by the line above keeps its shape rather than
       being squashed into the width it was given in the markup. */
    height: auto;
}

:where(table) {
    max-width: 100%;
}

:where(pre) {
    max-width: 100%;
    overflow-x: auto;
}

/* A link to a funeral home's listings page, an email address in a job advert, a
   sponsor's name run together - each is one unbreakable word wider than a phone,
   and each was enough on its own to make the whole page scroll sideways. */
:where(p, li, dd, dt, td, th, blockquote, figcaption, label, h1, h2, h3, h4, h5, h6, a) {
    overflow-wrap: break-word;
}

/*
    A two-column card whose first column is a fixed width has a screen below
    which it cannot hold both: the label column keeps its 180px and the content
    beside it is squeezed into whatever is left. Below that width the two stack,
    which is the same card with the columns read one after the other.
*/
@media (max-width: 520px) {
    .player-card {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0.7rem;
    }
}

/*
    Sponsor bands on a phone. The band above the hero already goes two logos to
    a row there; a band between two blocks of the page does the same, and gives
    up some of its air, so a strip of advertising is never taller than the block
    it sits between.
*/
@media (max-width: 600px) {
    .sponsor-board-inline {
        padding: 0.9rem 1rem;
    }

    .sponsor-board-inline .sponsor-item {
        flex: 1 1 40%;
        max-width: none;
    }

    .sponsor-board-inline .sponsor-tile {
        --sponsor-height: 54px;
    }
}

/* ---------------------------------------------------------------------------
   News Archive — the Our News stories that rolled off the front page, listed
   under the Local News popup. Plain cards in the popup's own palette: this is
   somewhere to look a story up, not to watch it.
   --------------------------------------------------------------------------- */

.newsbank {
    margin-top: 0.5rem;
    padding-top: 1.5rem;
    border-top: 2px solid rgba(29, 78, 216, 0.18);
}

.newsbank-heading {
    color: #0f2a6e;
    font-size: 1.35rem;
    margin-bottom: 0.25rem;
}

.newsbank-lede,
.newsbank-count,
.newsbank-status {
    color: #64708c;
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

.newsbank-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.newsbank-item {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 1rem;
    background: #ffffff;
    padding: 1rem;
    border-left: 4px solid #1d4ed8;
    border-radius: 5px;
}

.newsbank-thumb {
    width: 140px;
    height: 90px;
    object-fit: cover;
    border-radius: 6px;
    background: #e8eefb;
    display: block;
}

.newsbank-thumb-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #1d4ed8;
    font-weight: 800;
    letter-spacing: 0.1em;
}

.newsbank-text {
    min-width: 0;
}

.newsbank-meta {
    color: #64708c;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 0.3rem;
}

.newsbank-title {
    color: #1d4ed8;
    font-size: 1.1rem;
    margin-bottom: 0.35rem;
}

.newsbank-summary {
    color: #44506b;
    line-height: 1.6;
    margin-bottom: 0.35rem;
}

.newsbank-byline {
    color: #64708c;
    font-size: 0.82rem;
    margin-bottom: 0.5rem;
}

.newsbank-script summary {
    cursor: pointer;
    color: #0f2a6e;
    font-weight: 700;
    font-size: 0.9rem;
}

.newsbank-script-body {
    margin-top: 0.6rem;
    color: #44506b;
    line-height: 1.7;
}

.newsbank-script-body p {
    margin-bottom: 0.75rem;
}

.newsbank-media {
    display: inline-block;
    margin-top: 0.5rem;
    color: #1d4ed8;
    font-weight: 700;
    font-size: 0.9rem;
}

.newsbank-more {
    margin-top: 1rem;
    padding: 0.6rem 1.2rem;
    border: 1px solid rgba(29, 78, 216, 0.45);
    border-radius: 8px;
    background: #ffffff;
    color: #1d4ed8;
    font-weight: 700;
    cursor: pointer;
}

.newsbank-more:disabled {
    opacity: 0.6;
    cursor: default;
}

@media (max-width: 560px) {
    .newsbank-item {
        grid-template-columns: 1fr;
    }

    .newsbank-thumb {
        width: 100%;
        height: 160px;
    }
}

/* ---------------------------------------------------------------------------
   Website Updates — the change log signed-in accounts can read, and the form
   admins use to write up exactly what was changed.
--------------------------------------------------------------------------- */

#siteUpdatesMenuItem[hidden] {
    display: none;
}

body.site-updates-open {
    overflow: hidden;
}

.news-modal-content.site-updates-modal {
    width: min(760px, calc(100vw - 2rem));
    max-height: 86vh;
    padding: 2rem 2rem 1.5rem;
}

.site-updates-modal h2 {
    margin-bottom: 0.35rem;
}

.site-updates-close {
    position: absolute;
    top: 0.6rem;
    right: 0.8rem;
    background: none;
    border: none;
    color: #1d4ed8;
    font-size: 2.4rem;
    line-height: 1;
    cursor: pointer;
}

.site-updates-close:hover,
.site-updates-close:focus-visible {
    color: #0f2a6e;
}

.site-updates-intro {
    margin: 0 0 1.25rem;
    color: #4b5675;
}

.site-updates-btn {
    background: #eef3ff;
    color: #0f2a6e;
    border: 1px solid rgba(29, 78, 216, 0.35);
    border-radius: 999px;
    padding: 0.45rem 1rem;
    font: 600 0.85rem 'Poppins', sans-serif;
    cursor: pointer;
    transition: background 0.2s, box-shadow 0.2s;
}

.site-updates-btn:hover,
.site-updates-btn:focus-visible {
    background: #dbe6ff;
}

.site-updates-btn:disabled {
    opacity: 0.6;
    cursor: wait;
}

.site-updates-btn-primary {
    background: #1d4ed8;
    border-color: #1d4ed8;
    color: #ffffff;
}

.site-updates-btn-primary:hover,
.site-updates-btn-primary:focus-visible {
    background: #0f2a6e;
}

.site-updates-btn-danger {
    color: #b42318;
    border-color: rgba(180, 35, 24, 0.35);
    background: #fff4f2;
}

.site-updates-btn-danger:hover,
.site-updates-btn-danger:focus-visible {
    background: #ffe2dd;
}

/* Composer ---------------------------------------------------------------- */

.site-updates-composer {
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid #dfe6f5;
}

.site-updates-composer[hidden],
.site-updates-form[hidden] {
    display: none;
}

.site-updates-form {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    padding: 1.1rem;
    border: 1px solid #cfdaf3;
    border-radius: 10px;
    background: #f7f9ff;
}

.site-updates-form h3 {
    margin: 0;
    color: #0f2a6e;
    font-size: 1.15rem;
}

.site-updates-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-weight: 600;
    color: #1f2a44;
    font-size: 0.9rem;
}

.site-updates-field em,
.site-updates-changes legend em {
    color: #b42318;
    font-style: normal;
}

.site-updates-form input,
.site-updates-form textarea,
.site-updates-form select {
    width: 100%;
    box-sizing: border-box;
    padding: 0.55rem 0.7rem;
    border: 1px solid #c3cee6;
    border-radius: 7px;
    font: 400 0.92rem 'Poppins', sans-serif;
    color: #1f2a44;
    background: #ffffff;
}

.site-updates-form textarea {
    resize: vertical;
}

.site-updates-form input:focus,
.site-updates-form textarea:focus,
.site-updates-form select:focus {
    outline: 2px solid rgba(29, 78, 216, 0.45);
    outline-offset: 1px;
    border-color: #1d4ed8;
}

.site-updates-changes {
    border: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.site-updates-changes legend {
    font-weight: 600;
    color: #1f2a44;
    font-size: 0.9rem;
    margin-bottom: 0.2rem;
}

.site-updates-help {
    margin: 0;
    font-size: 0.82rem;
    color: #4b5675;
}

#siteUpdatesChangeRows {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.site-updates-change-row {
    display: grid;
    grid-template-columns: 8.5rem 1fr 2rem;
    grid-template-areas:
        "kind area remove"
        "detail detail detail";
    gap: 0.45rem;
    padding: 0.65rem;
    border: 1px solid #dbe3f4;
    border-radius: 8px;
    background: #ffffff;
}

.site-updates-change-kind { grid-area: kind; }
.site-updates-change-area { grid-area: area; }
.site-updates-change-detail { grid-area: detail; }

.site-updates-change-remove {
    grid-area: remove;
    background: none;
    border: none;
    color: #8a94ad;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.site-updates-change-remove:hover,
.site-updates-change-remove:focus-visible {
    color: #b42318;
}

#siteUpdatesAddChangeBtn {
    align-self: flex-start;
}

.site-updates-error {
    margin: 0;
    color: #b42318;
    font-size: 0.88rem;
    font-weight: 600;
}

.site-updates-error[hidden] {
    display: none;
}

.site-updates-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

/* Log --------------------------------------------------------------------- */

.site-updates-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.site-updates-empty {
    margin: 0;
    color: #4b5675;
    text-align: center;
    padding: 1.5rem 0;
}

.site-update {
    padding: 1.1rem 1.2rem;
    border: 1px solid #dfe6f5;
    border-left: 4px solid #1d4ed8;
    border-radius: 8px;
    background: #ffffff;
    scroll-margin-top: 1rem;
}

.site-update.is-new {
    background: #f3f7ff;
}

.site-update.is-focused {
    box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.25);
}

.site-update-head h3 {
    margin: 0;
    color: #0f2a6e;
    font-size: 1.1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.site-update-new {
    background: #1d4ed8;
    color: #ffffff;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
}

.site-update-meta {
    margin: 0.25rem 0 0;
    font-size: 0.8rem;
    color: #6a7390;
}

.site-update-summary {
    margin: 0.7rem 0 0;
    color: #1f2a44;
}

.site-update-changes {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.site-update-change {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    color: #1f2a44;
    font-size: 0.92rem;
    line-height: 1.45;
}

.site-update-kind {
    flex: 0 0 auto;
    min-width: 4.9rem;
    text-align: center;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.2rem 0.45rem;
    border-radius: 5px;
    margin-top: 0.1rem;
}

.site-update-kind-new { background: #dcfce7; color: #166534; }
.site-update-kind-improved { background: #dbeafe; color: #1e40af; }
.site-update-kind-fixed { background: #fef3c7; color: #92400e; }
.site-update-kind-removed { background: #fee2e2; color: #991b1b; }

.site-update-detail {
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.site-update-area {
    color: #0f2a6e;
}

.site-update-tools {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.85rem;
}

@media (max-width: 600px) {
    .news-modal-content.site-updates-modal {
        padding: 1.5rem 1rem 1rem;
        max-height: 92vh;
    }

    .site-updates-change-row {
        grid-template-columns: 1fr 2rem;
        grid-template-areas:
            "kind remove"
            "area area"
            "detail detail";
    }

    .site-update-change {
        flex-direction: column;
        gap: 0.25rem;
    }
}

/* The listener's place in line, on each request still waiting for the studio. */
.song-request-queue-position {
    display: inline-block;
    align-self: flex-start;
    margin-top: 0.2rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: #dbeafe;
    color: #1e40af;
    font-size: 0.78rem;
    font-weight: 700;
}

/* Mobile viewport refinement
   Keep the page expansive on small screens without pinning content to the
   glass. Fluid gutters respond continuously between compact and large phones. */
@media (max-width: 768px) {
    html {
        font-size: clamp(15px, 3.9vw, 16px);
        overflow-x: hidden;
    }

    body {
        width: 100%;
        min-width: 0;
        overflow-x: hidden;
    }

    header {
        padding-inline: max(0.9rem, env(safe-area-inset-left));
        padding-right: max(0.9rem, env(safe-area-inset-right));
    }

    section,
    .subscribe {
        width: 100%;
        max-width: none;
        padding: clamp(2.5rem, 8vw, 3.5rem) clamp(1rem, 4.5vw, 1.5rem);
    }

    section h2,
    .subscribe h2 {
        font-size: clamp(1.75rem, 7vw, 2.25rem);
        line-height: 1.15;
        margin-bottom: clamp(1.75rem, 6vw, 2.5rem);
    }

    .hero {
        width: calc(100% - clamp(2rem, 9vw, 3rem));
        min-height: clamp(430px, 72svh, 590px);
        margin: 0 auto clamp(2.5rem, 9vw, 3.5rem);
        padding: clamp(3rem, 10vw, 4.5rem) clamp(1.25rem, 6vw, 2rem);
        border-radius: clamp(16px, 5vw, 22px);
    }

    .hero h1 {
        font-size: clamp(2rem, 9vw, 2.75rem);
        line-height: 1.12;
    }

    .hero p {
        font-size: clamp(1rem, 4.25vw, 1.15rem);
    }

    .station-grid,
    .news-grid,
    .event-grid,
    .live-now-grid,
    .local-listings-grid,
    .sports-grid {
        gap: clamp(1.1rem, 4vw, 1.5rem);
    }

    .station-card,
    .news-card,
    .event-card,
    .local-listing-card {
        padding: clamp(1.25rem, 5vw, 1.75rem);
    }

    .player-card {
        width: 100%;
        max-width: 100%;
    }
}

@media (max-width: 380px) {
    section,
    .subscribe {
        padding-inline: 0.9rem;
    }

    .hero {
        width: calc(100% - 1.8rem);
    }
}
