/* =========================================================
   1. VARIABLES & RESET
   ========================================================= */
:root {
    --bg: #f0f2f5;
    --surface: #ffffff;
    --text: #0f172a;
    --text-muted: #475569;
    --border: #e2e8f0;
    --border-hover: #cbd5e1;
    --gold: #eaab00;
    /* Darker gold for text-only uses (logo dot, timestamps).
       --gold stays as the decorative/accent color for borders, soft tints,
       hover states, etc. — see WCAG contrast notes in style.css history. */
    --gold-text: #946000;
    --gold-soft: rgba(234, 171, 0, 0.12);
    --navy: #1e3a8a;
    --navy-soft: rgba(30, 58, 138, 0.08);
    --green: #047857;
    --green-soft: rgba(4, 120, 87, 0.1);
    --red-soft: #fef2f2;
    --red: #dc2626;
    --radius: 14px;
    --radius-sm: 8px;
    --radius-pill: 50px;
    --shadow: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
    --shadow-hover: 0 8px 25px rgba(0,0,0,0.08);
    --transition: 0.2s ease;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Disable browser "text auto-inflation" / "font boosting" (Chrome Android,
   iOS Safari). Without this, wide blocks of text get auto-enlarged for
   readability — which means a tag pill like "CENTER FOR HEALTH EDUCATION
   AND PROMOTION" that spans most of the screen width renders LARGER than
   short pills on the same card, producing inconsistent pill heights.
   Declaring 100% makes the browser honor author font-size exactly. */
html { overflow-y: scroll; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, sans-serif;
    background: var(--bg); color: var(--text); line-height: 1.5;
    -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; padding-bottom: 60px;
}

/* =========================================================
   2. HEADER
   ========================================================= */
header { background: var(--surface); position: sticky; top: 0; z-index: 100; border-bottom: 1px solid var(--border); }
/* Height of the main sticky header — used by .sticky-nav-bar and scroll-margin
   calculations below. These values are SAFE FALLBACKS only: JS measures the
   actual rendered header height at runtime and overrides this variable (see
   updateHeaderHeightVar in app.js). Fallback values are intentionally
   conservative so nothing gets clipped before JS runs:
     Desktop: 38px gear button + 10px padding×2 + 1px border = ~59px (→ 60px)
     Mobile:  28px hamburger  + 10px padding×2 + 1px border = ~49px (→ 50px)
   If JS fails entirely (no-JS users), these fallbacks still produce a usable
   layout with no clipping. */
:root { --header-h: 60px; }
@media (max-width: 1000px) { :root { --header-h: 50px; } }
.header-container { max-width: 1100px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; }
.logo-block h1 { font-size: 1.35rem; font-weight: 800; letter-spacing: -0.5px; color: var(--text); line-height: 1; user-select: none; display: flex; align-items: baseline; }
.logo-link { cursor: pointer; }
.logo-dot { color: var(--gold-text); }
.header-page-title { font-size: 1.15rem; font-weight: 600; color: var(--text-muted); margin-left: 2px; pointer-events: none; cursor: default; }
@media (max-width: 400px) { .header-page-title { display: none; } }

/* =========================================================
   3. NAVIGATION
   ========================================================= */
.main-nav { display: flex; gap: 4px; align-items: center; }
.nav-link { background: none; border: none; font-size: 0.85rem; font-weight: 600; color: var(--text-muted); padding: 6px 10px; border-radius: var(--radius-sm); cursor: pointer; transition: var(--transition); white-space: nowrap; text-decoration: none; }
.nav-link:hover { background: var(--bg); color: var(--text); }
.nav-link.active { background: var(--gold-soft); color: var(--text); }
.nav-external { color: var(--text-muted); text-decoration: none; display: flex; align-items: center; }
/* Search nav item: text label in the mobile overlay; icon-only on desktop (see min-width:1001px block) */
.nav-search-icon { display: none; }
.hamburger-menu { display: flex; background: none; border: none; cursor: pointer; padding: 4px; border-radius: var(--radius-sm); }
.close-menu { display: none; background: none; border: none; font-size: 1.4rem; cursor: pointer; align-self: flex-end; margin-bottom: 16px; color: var(--text); }
.menu-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 99; opacity: 0; transition: opacity 0.3s; pointer-events: none; backdrop-filter: blur(2px); }

@media (max-width: 1000px) {
    .main-nav { display: none; }
    .menu-overlay.open { display: block; opacity: 1; pointer-events: auto; }
    .main-nav.open { display: flex; position: fixed; top: 0; right: 0; width: 260px; height: 100vh; background: var(--surface); flex-direction: column; padding: 20px; box-shadow: -4px 0 20px rgba(0,0,0,0.1); z-index: 100; align-items: flex-start; border-left: 1px solid var(--border); }
    .close-menu { display: block; }
    .nav-link { width: 100%; text-align: left; padding: 14px 8px; font-size: 1rem; border-radius: 0; border-bottom: 1px solid var(--border); }
    .nav-link.active { background: var(--gold-soft); border-radius: var(--radius-sm); }
}
@media (min-width: 1001px) { .hamburger-menu { display: none !important; } }

/* =========================================================
   4. LAYOUT & VIEWS
   ========================================================= */
.container { max-width: 1100px; margin: 0 auto; padding: 16px; }
.app-view { display: none; animation: fadeUp 0.35s ease-out; }
.app-view.active { display: block; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.section-title { font-size: 1.5rem; font-weight: 800; margin-bottom: 16px; letter-spacing: -0.3px; }
.view-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }
.view-header .section-title { margin-bottom: 0; }

/* Toolbar row: title on left, clear button on right — always */
.toolbar-row {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 12px;
    position: relative;
    min-height: 32px;
}
.toolbar-row .clear-btn { position: absolute; right: 0; }
.toolbar-row .date-label { text-align: center; width: 100%; pointer-events: none; }

/* Sticky wrapper that holds toolbar + filters together so filters stay visible when expanded while scrolled.
   The negative margin + extra top padding pushes the background up to cover the container's padding-top gap
   so there's no sliver of page content visible between the header and the sticky bar. */
.sticky-nav-bar {
    position: sticky;
    /* Sit flush below the main sticky header. Previously hardcoded to 44px,
       which was ~10px too short on desktop (header is ~54px with nav buttons),
       causing the top edge of the bar — including the "Today" label — to be
       obscured by the header's higher z-index. The --header-h variable tracks
       the real height and keeps mobile/desktop in sync automatically. */
    top: var(--header-h);
    z-index: 50;
    background: var(--bg);
    /* Negative margin pulls the bar up into the container's 16px top-padding so it sits
       flush with the header from the page's initial render (no scroll gap). */
    margin: -16px -16px 4px;
    /* Bottom padding gives breathing room below the chip row so content scrolling underneath
       (like day-group-header "Today" labels) isn't clipped by the bar's lower boundary.
       Tightened from 12px to 8px to reclaim dead space on mobile. */
    padding: 16px 16px 8px;
    border-bottom: 1px solid var(--border);
}

/* Compact toolbar: date nav + action buttons */
.toolbar-compact {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 36px;
    padding-bottom: 0;
}
.toolbar-center { display: flex; align-items: center; gap: 0; }
.toolbar-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; margin-left: auto; }
.date-label-inline { font-size: 0.95rem; font-weight: 700; color: var(--text); white-space: nowrap; min-width: 140px; text-align: center; }

/* Three-item toolbar: left label, center date, right clear */
.toolbar-three { justify-content: center; }
.toolbar-three .game-label { position: absolute; left: 0; }
.game-label {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
    white-space: nowrap;
}
.toolbar-row .section-title { margin-bottom: 0; }

/* =========================================================
   5. CARD GRID
   ========================================================= */
.card-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .card-grid { grid-template-columns: repeat(3, 1fr); } }
.feed-pinned-header { grid-column: 1 / -1; padding: 8px 0 4px; font-size: 0.85rem; font-weight: 700; color: var(--gold); border-bottom: 2px solid var(--gold); margin-bottom: 4px; }
.feed-divider { grid-column: 1 / -1; padding: 12px 0 4px; font-size: 0.8rem; font-weight: 600; color: var(--text-muted); border-top: 1px solid var(--border); margin-top: 8px; }
.feed-setup-hint { grid-column: 1 / -1; font-size: 0.82rem; color: var(--text-muted); padding: 8px 12px; background: var(--gold-soft); border-radius: var(--radius-sm); margin: 0; }
.feed-setup-hint a { color: var(--navy); font-weight: 700; }
.feed-group-dimmed { opacity: 0.55; }
.feed-group-dimmed label:hover { opacity: 0.85; }
.feed-group-dim-note { font-size: 0.7rem; color: var(--text-muted); font-weight: 400; margin-left: 6px; }

/* Heading-style group label (Penn Manor / Millersville University / Other).
   The whole row is a clickable master checkbox. Visual treatment: uppercase
   navy text with bottom border so it reads as a section divider, while
   remaining obviously interactive (cursor:pointer, hover background). */
.feed-heading-label {
    transition: background 0.15s;
}
.feed-heading-label:hover { background: var(--bg); }
.feed-heading-text {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--navy);
    font-weight: 800;
}

/* Subgroup (collapsible nested section, e.g. Club Sports / Greek Life under
   MU GetInvolved). The header row is clickable to expand/collapse; chevron
   rotates 90deg when open. Children render below in a wrapped chip layout. */
.feed-subgroup-header {
    transition: background 0.15s;
}
.feed-subgroup-header:hover { filter: brightness(0.97); }
.feed-subgroup-header.is-active { background: var(--gold-soft); }
.feed-subgroup-chevron {
    transition: transform 0.18s ease;
    user-select: none;
}

/* Favorited event/game card — gold accent. Favorites are no longer pinned at the top of
   Events/Sports pages; they live in their chronological day group with this visual badge
   so users can spot them at a glance while scrolling. A soft gold-tinted background makes
   the favorite easier to pick out in a long list — the border alone was too subtle against
   the off-white surface. */
.app-card.card-fav {
    border: 2px solid var(--gold);
    background: linear-gradient(0deg, rgba(216, 163, 46, 0.06), rgba(216, 163, 46, 0.06)), var(--surface);
    box-shadow: 0 2px 12px rgba(216, 163, 46, 0.18);
}

/* Card-level favorite toggle — NEW inline layout. Sits left of the title on the
   same baseline so the star is visually attached to the event name rather than
   floating in the corner. Replaces the older position:absolute approach which
   required ad-hoc padding to prevent overlap with tags/title/score-corner.
   The older .card-fav-btn selector below is kept for search results and any
   other surfaces that still use the absolute-positioned star; main event/sports
   cards use .card-fav-inline now. */
.card-heading {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}
.card-heading .card-title {
    margin: 0;
    flex: 1;
    min-width: 0;
}
.card-fav-inline {
    flex-shrink: 0;
    /* Visible button: 30×30 — slightly larger than before for better legibility
       but still compact enough not to dominate the title row. Touch target
       expanded to 44×44 via ::before pseudo-element below to meet WCAG/iOS
       guidelines without shifting layout. */
    width: 30px;
    height: 30px;
    position: relative;
    padding: 0;
    background: transparent;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    font-size: 1.05rem;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
    font-family: inherit;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s, color 0.15s, border-color 0.15s, background 0.15s;
}
/* Invisible hit-target expander: an absolutely positioned ::before overlay
   that adds 7px of clickable space on every side without affecting layout
   geometry. Final tap area = 44×44 (ideal for thumbs); visible button stays
   30×30 so it doesn't visually overpower the title. */
.card-fav-inline::before {
    content: '';
    position: absolute;
    inset: -7px;
    border-radius: 50%;
}
.card-fav-inline:hover { transform: scale(1.1); color: var(--gold); border-color: var(--gold); }
.card-fav-inline.active { color: var(--gold); border-color: var(--gold); background: var(--surface); }

/* Legacy absolute-positioned fav button — kept for search results etc. */
.card-fav-btn {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 30px;
    height: 30px;
    padding: 0;
    background: rgba(255, 255, 255, 0.85);
    border: 1px solid var(--border);
    border-radius: 50%;
    font-size: 1rem;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
    font-family: inherit;
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    transition: transform 0.15s, color 0.15s, background 0.15s;
    z-index: 2;
}
.card-fav-btn:hover { transform: scale(1.1); color: var(--gold); border-color: var(--gold); }
.card-fav-btn.active { color: var(--gold); border-color: var(--gold); background: white; }
/* If a card uses the legacy absolute star, keep the old padding workarounds
   for tags/title. New inline-star cards (main event/sports views) don't need
   these because the star is part of the flex heading. */
.app-card:has(.card-fav-btn) .card-body > .card-tags { padding-left: 34px; min-height: 30px; }
.app-card:has(.card-fav-btn) .card-body > .card-title { padding-left: 34px; }
/* Score corner still overlaps the top-right of the card regardless of star
   placement — title needs right-padding whenever a score badge is present. */
.app-card:has(.score-corner) .card-heading { padding-right: 80px; }
.app-card:has(.score-corner) .card-body > .card-title { padding-right: 80px; }
.app-card:has(.score-corner) .card-body > .card-tags { padding-right: 80px; }

/* Secondary tags (rendered below title+meta in new card layout) are visually
   de-emphasized vs the primary source/category tag pills. Slightly smaller,
   thinner top margin — they're metadata, not headline content anymore. */
.card-tags-secondary { margin-top: 8px; margin-bottom: 0; }

/* Gold pulse animation applied to .card-tags when a star is toggled on.
   Visual cue showing the user which category bucket they just favorited. */
@keyframes tags-flash-pulse {
    0%, 100% { background: transparent; box-shadow: none; }
    50% { background: var(--gold-soft); box-shadow: 0 0 0 3px var(--gold); }
}
.card-tags.tags-flash {
    animation: tags-flash-pulse 0.7s ease-in-out 2;
    border-radius: var(--radius-sm);
    padding: 2px 4px;
    margin: 6px -4px 0 -4px;
}

/* Community board post footer badges. Age badge is quiet gray (informational);
   expiry badges are progressively louder as the deadline approaches — amber
   for 2-3 days out, red for "tomorrow" or "today". Uses a single base class
   so sizing and padding stay consistent across the three states. */
.board-meta-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; align-items: center; }
.board-badge { font-size: 0.7rem; padding: 3px 8px; border-radius: var(--radius-sm); font-weight: 600; line-height: 1.3; display: inline-flex; align-items: center; }
.board-badge-age { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.board-badge-expiring-soon { background: #fef3c7; color: #92400e; border: 1px solid #fcd34d; }
.board-badge-expiring-now { background: #fee2e2; color: #991b1b; border: 1px solid #fca5a5; }

/* Small 📅 add-to-calendar button in the card action row. Matches height of the
   Details button (28px) but square so it reads as an icon-only action. On tap it
   downloads a minimal .ics file; most mobile OSes auto-prompt "Add to Calendar". */
.btn-cal, .btn-share {
    width: 30px;
    height: 28px;
    padding: 0;
    background: var(--surface);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.85rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.btn-cal:hover, .btn-share:hover { border-color: var(--navy); background: var(--bg); }

/* Last-updated line at the bottom of the home view. Small, muted — informational not
   alarming in the normal case. When stale (>3hr), gains an amber tint to signal the
   data may be old without being visually scary. */
.home-last-updated {
    text-align: center;
    font-size: 0.72rem;
    color: var(--text-muted);
    padding: 12px 8px 6px;
    letter-spacing: 0.01em;
}
.home-last-updated.stale { color: #b8860b; }

/* Toolbar ⭐ Favs button — a variant of .family-toggle that shows a label next to the star.
   Matches .family-toggle size so it lines up with other toolbar toggles. */
.family-toggle.fav-toggle {
    width: auto;
    padding: 0 10px;
    gap: 4px;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--navy);
    border-color: var(--gold);
}
.family-toggle.fav-toggle.active { background: var(--gold); color: var(--navy); border-color: var(--gold); }
.family-toggle.fav-toggle:not(.active):hover { background: var(--gold-soft); }
.fav-toggle-label { font-size: 0.78rem; }

/* Past toggle on Sports — same shape as fav-toggle but different color accent (navy) since
   it represents a mode switch rather than a favorites overlay. */
.family-toggle.past-toggle {
    width: auto;
    padding: 0 10px;
    gap: 4px;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--navy);
    border-color: var(--navy);
}
.family-toggle.past-toggle.active { background: var(--navy); color: white; border-color: var(--navy); }
.family-toggle.past-toggle:not(.active):hover { background: var(--bg); }
.past-toggle-label { font-size: 0.78rem; }

/* Labeled family toggles (Family / Free Food / Free Stuff) — same auto-width
   layout as the Favs/Past toggles so the text label fits on desktop, keeping the
   green family-toggle accent. Label hides on mobile (icon-only), like Favs/Past. */
.family-toggle.has-label { width: auto; padding: 0 10px; gap: 4px; font-size: 0.78rem; font-weight: 700; }
.family-toggle-label { font-size: 0.78rem; }

/* MBA member lens toggle — navy accent matching the "✓ MBA Member" badge. The
   short "MBA" label stays visible even on mobile (a bare ✓ would be unclear). */
.family-toggle.mba-toggle {
    width: auto;
    padding: 0 10px;
    gap: 4px;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--navy);
    border-color: var(--navy);
}
.family-toggle.mba-toggle.active { background: var(--navy); color: white; border-color: var(--navy); }
.family-toggle.mba-toggle:not(.active):hover { background: var(--bg); }
.mba-toggle-label { font-size: 0.78rem; }

/* Marauder Gold toggle now shows the MU coin image instead of an emoji. */
.mg-coin-img { width: 22px; height: 22px; display: block; object-fit: contain; }
.family-toggle.mg-toggle.active { background: var(--gold-soft, #fdf6e3); border-color: var(--gold); }

/* Subtle note shown below the toolbar when a lens filter (MBA / Marauder Gold)
   is active, telling the user what's being filtered. */
.filter-note {
    font-size: 0.78rem;
    color: var(--text-muted);
    background: var(--gold-soft, #fdf6e3);
    border-left: 3px solid var(--gold);
    padding: 6px 10px;
    border-radius: 4px;
    margin: 6px 0 0;
}
.filter-note:empty { display: none; }

/* Category filter dropdown menu — a floating vertical list under "Filter ▾".
   Right-aligned to sit under the button; scrolls if taller than the cap. */
.sticky-nav-bar { position: sticky; }   /* ensure stacking context for the menu */
.filter-menu {
    position: absolute;
    right: 16px;
    z-index: 50;
    margin-top: 2px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: 0 6px 20px rgba(0,0,0,0.15);
    padding: 6px;
    max-height: 60vh;
    overflow-y: auto;
    min-width: 190px;
}
.filter-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 9px 12px;
    font-size: 0.9rem;
    color: var(--text);
    border-radius: 5px;
    cursor: pointer;
    white-space: nowrap;
}
.filter-menu-item:hover { background: var(--bg); }
.filter-menu-item.active { background: var(--navy); color: #fff; font-weight: 700; }

/* Mobile: hide the text, keep just the star/icon. Desktop shows the full label. */
@media (max-width: 768px) {
    .fav-toggle-label, .past-toggle-label, .family-toggle-label { display: none; }
    .family-toggle.fav-toggle, .family-toggle.past-toggle, .family-toggle.has-label { padding: 0; width: 36px; gap: 0; }
}

/* Clear filters button — compact X-only so the toolbar has room for more items.
   The button ID is `ev-clear-btn` / `sp-clear-btn`; JS toggles its `visibility` between
   `hidden` (reserves space so other buttons don't shift) and `visible` (shown when
   filters are active). Tooltip ("Clear filters") explains the action. */
.clear-btn {
    padding: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 0.95rem;
    font-weight: 700;
    background: var(--surface);
    color: #dc2626;
    border: 1.5px solid #fecaca;
    cursor: pointer;
    font-family: inherit;
    line-height: 1;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    /* Hidden by default — JS flips visibility to 'visible' when filters active.
       Using visibility (not display) so the button reserves its slot and the other
       toolbar buttons don't shift horizontally when it appears/disappears. */
    visibility: hidden;
}
.clear-btn:hover { background: #fef2f2; border-color: #dc2626; }

/* ===== Infinite-scroll day grouping (Events + Sports) ===== */
/* Day group header — an in-list divider between days. Not sticky anymore since the
   toolbar's #ev-current-day-label / #sp-current-day-label shows the active date as
   you scroll. That avoids double stacking of sticky elements. */
.day-group-header {
    grid-column: 1 / -1;
    background: transparent;
    padding: 10px 4px 6px;
    /* Previously 20px top margin to insulate from the sticky toolbar during
       scroll. That insulation turned out to be redundant — the sticky bar
       has its own solid background + border-bottom, so scrolled content
       doesn't bleed through; and scroll-margin-top below handles hash-link
       and programmatic scroll clearance. 4px keeps a small breath from the
       preceding card or callout without the previous 40px+ dead zone.  */
    margin: 4px 0 0;
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    /* Keep day-group-header clear of both sticky elements when programmatically
       scrolled to (hash link, JS scrollIntoView). Sticky-nav-bar is typically
       ~130px tall (toolbar-compact + filter row + padding); combined with
       --header-h gives a safe offset. Previously hardcoded 180px; variable-
       based keeps mobile/desktop in sync with the header height. */
    scroll-margin-top: calc(var(--header-h) + 130px);
}
/* First day-group-header in a container historically got a margin-top override
   (4px instead of 20px) to avoid extra space at the top of lists. Now that the
   base rule is also 4px, the override is redundant. Intentional no-op kept as
   a comment marker in case we revisit differential spacing. */
.day-group-header.today { color: var(--navy); border-bottom-color: var(--gold); }
.day-group-header .day-count { font-size: 0.7rem; font-weight: 500; color: var(--text-muted); margin-left: 8px; text-transform: none; letter-spacing: 0; }
/* Dynamic date label in the sticky toolbar — updates as the user scrolls past day groups.
   Plain text, explicitly not interactive — just a quiet indicator of the current date. */
.current-day-label {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--navy);
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    white-space: nowrap;
    transition: color 0.15s;
    cursor: default;
    user-select: none;
    pointer-events: none;
}
/* Today/Load More buttons */
.today-btn { background: var(--gold); color: var(--navy); border: 1.5px solid var(--gold); padding: 6px 12px; border-radius: var(--radius-sm); font-weight: 700; font-size: 0.82rem; cursor: pointer; font-family: inherit; white-space: nowrap; }
.today-btn:hover { background: #f3c75c; }
.load-more-btn { grid-column: 1 / -1; display: block; width: 100%; padding: 14px; margin-top: 16px; background: var(--surface); color: var(--navy); border: 1.5px solid var(--border); border-radius: var(--radius-sm); font-weight: 600; font-size: 0.9rem; cursor: pointer; font-family: inherit; transition: var(--transition); }
.load-more-btn:hover { border-color: var(--gold); background: var(--gold-soft); }
.load-more-note { grid-column: 1 / -1; text-align: center; font-size: 0.8rem; color: var(--text-muted); padding: 16px 8px; }
/* Upcoming/Past tab switcher on Sports page */
/* (Upcoming/Past tab switcher removed — Sports now uses a single "Past" toggle button
   in the toolbar-right, styled via .family-toggle.past-toggle above.) */
.welcome-banner { background: linear-gradient(135deg, var(--gold-soft), #fff8e1); border: 1.5px solid var(--gold); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px; }
.welcome-banner strong { font-size: 0.95rem; color: var(--navy); }
.affiliation-btn { background: white; border: 1.5px solid var(--gold); color: var(--navy); padding: 8px 14px; border-radius: var(--radius-sm); font-weight: 600; font-size: 0.88rem; cursor: pointer; font-family: inherit; transition: var(--transition); white-space: nowrap; }
.affiliation-btn:hover { background: var(--gold); color: var(--navy); transform: translateY(-1px); }  /* navy-on-gold = 5.09:1 (was white-on-gold 2.03, failed AA) */
.aff-chip { background: white; border: 1px solid var(--border); color: var(--text); padding: 6px 12px; border-radius: var(--radius-sm); font-weight: 600; font-size: 0.82rem; cursor: pointer; font-family: inherit; transition: var(--transition); flex: 1; }
.aff-chip:hover { border-color: var(--gold); }
.aff-chip.active { background: var(--navy); color: white; border-color: var(--navy); }
.perk-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }

/* Card description — short summary below location. Long descriptions get a "more" link
   that expands in-place (toggles .expanded on the parent .card-desc). Keeping cards
   compact by default; users opt in to reading more. */
.card-desc { margin-top: 8px; }
.card-desc-text { font-size: 0.82rem; color: var(--text); line-height: 1.45; margin: 0; white-space: pre-wrap; }
.card-desc .card-desc-full { display: none; }
.card-desc.expanded .card-desc-preview { display: none; }
.card-desc.expanded .card-desc-full { display: block; }
.card-desc-more, .card-desc-less { color: var(--navy); font-weight: 600; text-decoration: underline; cursor: pointer; white-space: nowrap; }
.card-desc-more:hover, .card-desc-less:hover { color: #1e3a8a; }
.perk-badge { display: inline-flex; align-items: center; font-size: 0.72rem; font-weight: 700; padding: 2px 8px; border-radius: var(--radius-pill); white-space: nowrap; }
.perk-food { background: #fef3c7; color: #92400e; border: 1px solid #fbbf24; }
.perk-stuff { background: #dbeafe; color: #1e40af; border: 1px solid #60a5fa; }
.perk-credit { background: #d1fae5; color: #065f46; border: 1px solid #34d399; }
.perk-registration { background: #fef9c3; color: #854d0e; border: 1px solid #ca8a04; }
.tl-perk { font-size: 0.8rem; }

/* Modal-scoped perk row: Free Food / Free Stuff are often the primary draw
   for an event, so in the modal we give them their own strip directly below
   the location with larger, high-contrast pills. These selectors only apply
   inside the event details overlay — card-level .perk-badge usage elsewhere
   keeps the compact pill sizing. */
.modal-perks { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px; }
.event-details-overlay .perk-badge {
    font-size: 0.88rem;
    padding: 6px 12px;
    border-width: 2px;
    gap: 4px;
}

/* =========================================================
   6. CARDS
   ========================================================= */
.app-card { background: var(--surface); border-radius: var(--radius); padding: 16px; border: 1px solid var(--border); box-shadow: var(--shadow); display: flex; flex-direction: column; justify-content: space-between; transition: transform var(--transition), box-shadow var(--transition); overflow: hidden; }
.app-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.card-img-wrap { margin: -16px -16px 12px -16px; height: 160px; overflow: hidden; flex-shrink: 0; }
.card-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.app-card-compact { padding: 12px; }
.card-featured { border: 2px solid var(--gold); background: linear-gradient(135deg, #fffbeb 0%, var(--surface) 100%); }
.card-body { flex: 1; }
.card-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.card-tag { display: inline-flex; align-items: center; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; background: var(--bg); color: var(--text-muted); padding: 3px 8px 1px; border-radius: var(--radius-pill); border: 1px solid var(--border); white-space: nowrap; line-height: 1.4; }
/* Multi-day event marker. Visible across all days the event spans (e.g. "Day 2 of 3"). Navy on soft-blue = 8.49:1 contrast. */
.card-tag-multiday { background: #dbeafe; color: var(--navy); border-color: #93c5fd; }
.card-title { font-size: 1.08rem; font-weight: 700; margin: 4px 0 6px; line-height: 1.3; color: var(--text); }
.card-title-sm { font-size: 0.95rem; font-weight: 700; margin: 4px 0; line-height: 1.3; }
.card-meta { font-size: 0.8rem; color: var(--text-muted); line-height: 1.4; }
.card-heading { font-size: 1rem; font-weight: 700; margin-bottom: 8px; }
.card-footer { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.specials-section { background: var(--gold-soft); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 12px; border-left: 3px solid var(--gold); }
.badge-members-only { display: inline-flex; align-items: center; background: #dc2626; color: white; font-size: 0.65rem; font-weight: 700; padding: 3px 8px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; line-height: 1.4; }
.card-actions { display: flex; justify-content: flex-end; align-items: center; gap: 8px; width: 100%; }
.game-loc-badge { font-size: 0.7rem; font-weight: 700; padding: 2px 8px; border-radius: var(--radius-pill); margin-right: auto; }
.game-loc-home { background: #dcfce7; color: #166534; }
.game-loc-away { background: #f3f4f6; color: var(--text-muted); }
.tag-family { background: #fef3c7; color: #92400e; }

/* =========================================================
   7. BUTTONS & BADGES
   ========================================================= */
.btn { display: inline-flex; align-items: center; justify-content: center; font-weight: 700; border-radius: var(--radius-sm); text-decoration: none; cursor: pointer; transition: var(--transition); border: none; font-family: inherit; }
.btn-sm { font-size: 0.8rem; padding: 6px 12px; }
.btn-outline { background: var(--surface); border: 1px solid var(--border); color: var(--text); }
.btn-outline:hover { border-color: var(--border-hover); background: var(--bg); }
.btn-ticket { background: var(--green); color: white; }
.btn-ticket:hover { opacity: 0.9; }
.btn-gold { background: var(--gold); color: #000; padding: 10px 20px; font-size: 0.9rem; }
.btn-dark { background: var(--text); color: white; }
.badge { display: inline-flex; align-items: center; font-size: 0.75rem; font-weight: 700; padding: 4px 10px; border-radius: var(--radius-pill); }
.badge-free { background: var(--navy); color: var(--gold); }
.badge-door { background: var(--bg); border: 1px solid var(--border); color: var(--text); }
.badge-premium { background: var(--gold); color: #000; font-size: 0.65rem; text-transform: uppercase; margin-bottom: 8px; }
/* Verified MBA (Millersville Business Association) member — identical for both
   tiers. Navy pill with gold check; sits in the card-tag row, right-aligned. */
.badge-mba { display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; white-space: nowrap; }
.badge-mba-shield { width: 20px; height: 23px; display: block; flex-shrink: 0; }
.badge-mba-label { font-size: 0.6rem; font-weight: 800; color: var(--navy); text-transform: uppercase; letter-spacing: 0.4px; }
/* Enhanced Directory listing for Featured Spotlight buyers — prominent gold
   accent, logo header, marketing tagline. */
.card-spotlight { border: 1.5px solid var(--gold); box-shadow: 0 2px 10px rgba(184,134,11,0.12); }
.enhanced-logo { max-height: 48px; max-width: 60%; object-fit: contain; display: block; margin: 8px 0 2px; }
.enhanced-tagline { font-size: 0.82rem; font-style: italic; color: var(--navy); font-weight: 600; margin: 2px 0 6px; }
.home-indicator, .away-indicator { display: inline-block; font-size: 0.75rem; font-weight: 700; margin-left: 6px; padding: 1px 6px; border-radius: 4px; }
.home-indicator { background: var(--green-soft); color: var(--green); }
.away-indicator { background: var(--navy-soft); color: var(--navy); }

/* Score & Live badges */
.badge-win { background: #dcfce7; color: #166534; margin-left: 8px; font-size: 0.7rem; }
.badge-loss { background: #fef2f2; color: #991b1b; margin-left: 8px; font-size: 0.7rem; }
.badge-neutral { background: var(--bg); color: var(--text-muted); margin-left: 8px; font-size: 0.7rem; }
.badge-live { background: #b91c1c; color: white; font-size: 0.65rem; text-decoration: none; animation: pulse-live 2s infinite; }
.btn-live { background: #dc2626; color: white; }
.btn-live:hover { opacity: 0.9; }
.card-live { border-left: 3px solid #dc2626; }
@keyframes pulse-live { 0%,100% { opacity: 1; } 50% { opacity: 0.85; } }

/* Game result card tinting */
.card-win { background: linear-gradient(135deg, #f0fdf4 0%, var(--surface) 40%); border-left: 3px solid #16a34a; }
.card-loss { background: linear-gradient(135deg, #fef2f2 0%, var(--surface) 40%); border-left: 3px solid #dc2626; }
.card-tie { background: linear-gradient(135deg, #fefce8 0%, var(--surface) 40%); border-left: 3px solid #ca8a04; }

/* Score corner — top right of game card */
/* Past game score badge — top-right corner of card. Intentionally prominent because the
   score IS the thing users want to see at a glance in past view. W/L takes a bright bg color
   that pops against the card surface. Score value is large so it's scannable while scrolling. */
.score-corner { position: absolute; top: 0; right: 0; padding: 12px 16px; border-radius: 0 var(--radius) 0 var(--radius); text-align: center; line-height: 1; min-width: 64px; z-index: 1; }
.score-win { background: #15803d; color: white; }  /* green-700 — bumped from green-600 #16a34a for WCAG AA contrast (3.30 → 5.02) */
.score-loss { background: #dc2626; color: white; }
.score-tie { background: #64748b; color: white; }
.score-result { display: block; font-size: 0.78rem; font-weight: 800; letter-spacing: 1.5px; opacity: 0.95; margin-bottom: 4px; }
.score-value { display: block; font-size: 1.75rem; font-weight: 800; letter-spacing: -0.5px; }

/* =========================================================
   8. FILTERS
   ========================================================= */
/* View mode bar */
.view-mode-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 12px;
}
.view-mode-group {
    display: flex;
    gap: 0;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.mode-btn {
    background: var(--surface);
    border: none;
    border-right: 1px solid var(--border);
    color: var(--text);
    padding: 7px 14px;
    font-weight: 700;
    font-size: 0.8rem;
    cursor: pointer;
    transition: var(--transition);
    font-family: inherit;
}
.mode-btn:last-child { border-right: none; }
.mode-btn:hover { background: var(--gold-soft); }
.mode-btn.active { background: var(--gold); color: #000; }
.nav-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: none;
    border: none;
    font-weight: 400;
    font-size: 1.4rem;
    cursor: pointer;
    font-family: inherit;
    color: var(--text-muted);
    flex-shrink: 0;
    padding: 0;
    transition: color 0.15s;
}
.nav-arrow:hover { color: var(--navy); }
.date-label {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
}

.filter-bar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
/* When a sibling sub-filter-bar is active (sub-categories expanded), hide the
   filter-bar's bottom divider so the two rows read as one continuous filter
   block instead of being separated by a line. :has() support: Safari 15.4+,
   Chrome 105+, Firefox 121+ — covers 98%+ of users per caniuse. Older browsers
   see the line but nothing breaks; it's purely visual polish. */
.sticky-nav-bar:has(.sub-filter-bar.active) .filter-bar { border-bottom: none; padding-bottom: 4px; margin-bottom: 4px; }
.filter-group { display: flex; flex-wrap: wrap; gap: 6px; }
.src-btn { background: var(--surface); border: 1.5px solid var(--border); color: var(--text); padding: 7px 14px; border-radius: var(--radius-sm); font-weight: 700; font-size: 0.82rem; cursor: pointer; transition: var(--transition); font-family: inherit; display: flex; align-items: center; gap: 4px; }
.src-btn:hover { border-color: var(--gold); }
.src-btn.active { background: var(--gold); color: #000; border-color: var(--gold); }
.src-btn[data-feed] { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; position: relative; overflow: visible; }
.btn-icon { vertical-align: middle; margin-right: 2px; flex-shrink: 0; }

.filter-toggle { background: var(--surface); border: 1.5px solid var(--border); color: var(--text); padding: 0 12px; height: 34px; border-radius: var(--radius-sm); font-weight: 700; font-size: 0.8rem; cursor: pointer; font-family: inherit; transition: var(--transition); display: flex; align-items: center; gap: 4px; }
.filter-toggle:hover { border-color: var(--gold); }
.toolbar-compact .clear-btn { position: static; }
.filters-collapsible { }
.fab-submit { position: sticky; bottom: 20px; left: 16px; width: 48px; height: 48px; border-radius: 50%; background: var(--navy); color: white; border: none; font-size: 1.3rem; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.25); z-index: 100; display: flex; align-items: center; justify-content: center; transition: transform 0.2s, box-shadow 0.2s; float: left; margin-top: 12px; }
.fab-submit:hover { transform: scale(1.1); box-shadow: 0 6px 16px rgba(0,0,0,0.3); }
@media (max-width: 768px) {
    .filters-collapsible { display: none; }
    .date-label-inline { font-size: 0.9rem; min-width: 120px; }
}

.sub-filter-bar { display: none; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; padding-bottom: 0; }
.sub-filter-bar.active { display: flex; }
/* Sub-category chip — slightly smaller and muted vs .src-btn so the visual hierarchy reads:
   source row (primary) → sub row (secondary narrowing). */
.sub-tag-btn {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 5px 11px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.75rem;
    cursor: pointer;
    transition: var(--transition);
    font-family: inherit;
    white-space: nowrap;
}
.sub-tag-btn:hover { border-color: var(--gold); color: var(--text); }
.sub-tag-btn.active { background: var(--gold-soft); color: var(--navy); border-color: var(--gold); }
.sub-btn { background: var(--bg); border: 1px solid var(--border); color: var(--text); padding: 5px 12px; border-radius: var(--radius-sm); font-weight: 600; font-size: 0.8rem; cursor: pointer; transition: var(--transition); font-family: inherit; }
.sub-btn:hover { border-color: var(--gold); }
.sub-btn.active { background: var(--navy); color: var(--gold); border-color: var(--navy); }

.date-range-row { display: flex; align-items: center; gap: 6px; }
.date-input { padding: 7px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: inherit; font-size: 0.85rem; color: var(--text); background: var(--surface); width: 140px; text-align: center; }
.date-sep { font-weight: 700; color: var(--text-muted); font-size: 0.8rem; }

@media (max-width: 640px) {
    .date-range-row { width: 100%; }
    .date-input { flex: 1; }
}

/* =========================================================
   9. SPORTS-SPECIFIC
   ========================================================= */
.sp-source-row {
    align-items: center;
}
.ev-source-row {
    align-items: center;
    flex-wrap: wrap;
}
.ev-source-row .filter-group {
    display: contents;
}

.home-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: var(--surface);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: var(--transition);
    color: var(--text-muted);
    flex-shrink: 0;
}
.home-toggle:hover { border-color: #059669; color: #059669; }
.home-toggle.active {
    background: #059669;
    border-color: #059669;
    color: white;
}

.family-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: var(--surface);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: var(--transition);
    color: var(--text-muted);
    flex-shrink: 0;
}
.family-toggle:hover { border-color: #059669; color: #059669; }
.family-toggle.active {
    background: #059669;
    border-color: #059669;
    color: white;
}

.sport-tag-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.sport-pill { background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: 5px 12px; border-radius: var(--radius-pill); font-size: 0.78rem; font-weight: 600; cursor: pointer; transition: var(--transition); font-family: inherit; position: relative; overflow: visible; }
.sport-pill[data-feed] { -webkit-user-select: none; user-select: none; }
.sport-pill:hover { border-color: var(--gold); }
.sport-pill.active { background: var(--gold); color: #000; border-color: var(--gold); }

/* =========================================================
   10. PAGINATION
   ========================================================= */
.pagination { display: flex; justify-content: center; align-items: center; gap: 16px; margin-top: 20px; }
.page-btn { background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: 8px 16px; border-radius: var(--radius-sm); font-weight: 600; font-size: 0.85rem; cursor: pointer; transition: var(--transition); font-family: inherit; }
.page-btn:hover { border-color: var(--gold); background: var(--gold-soft); }
.page-info { font-weight: 700; font-size: 0.85rem; color: var(--text-muted); }

/* =========================================================
   11. HOME VIEW
   ========================================================= */
/* Homepage */
.home-weather-bar { margin-bottom: 16px; }
.weather-bar { background: linear-gradient(135deg, var(--navy) 0%, #1e40af 100%); color: white; padding: 12px 16px; border-radius: var(--radius); display: flex; justify-content: space-between; align-items: center; }
.weather-bar-left { display: flex; align-items: center; gap: 10px; }
.weather-bar-icon { font-size: 1.5rem; }
.weather-bar-temp { font-size: 1.3rem; font-weight: 800; }
.weather-bar-cond { font-size: 0.85rem; opacity: 0.85; }
.weather-bar-date { font-size: 0.85rem; font-weight: 600; opacity: 0.9; }

/* Home top row: weather (2/3) + MBA spotlight (1/3) as two separate rounded
   cards side by side. When there's no spotlight to show, .home-spotlight is
   hidden and the weather bar fills the row. */
.home-top-row { display: flex; gap: 10px; align-items: stretch; }
.home-top-row .weather-bar { flex: 2; }
.home-spotlight { flex: 1; display: flex; min-width: 0; }
.home-spotlight:empty { display: none; }

/* The spotlight card — white rounded rectangle matching the weather bar, so
   the two read as an aligned pair. Holds the member's logo (or name) and an
   optional tagline. Rotates among paid MBA spotlight members. */
.spotlight-card { display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 3px; width: 100%; height: 100%; text-decoration: none; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; box-sizing: border-box; transition: box-shadow 0.2s ease, opacity 0.4s ease; animation: spotlight-fade 0.5s ease; overflow: hidden; }
.spotlight-card:hover { box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.spotlight-logo { max-height: 44px; max-width: 100%; object-fit: contain; display: block; }
.spotlight-name { font-size: 0.85rem; font-weight: 800; color: var(--navy); text-align: center; line-height: 1.1; }
.spotlight-tagline { font-size: 0.62rem; color: var(--text-muted); text-align: center; line-height: 1.15; }
@keyframes spotlight-fade { from { opacity: 0; } to { opacity: 1; } }
/* On narrow phones keep it compact: drop the tagline. */
@media (max-width: 480px) {
    .spotlight-tagline { display: none; }
    .spotlight-logo { max-height: 38px; }
}

.home-section { margin-bottom: 20px; }
.home-section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; flex-wrap: wrap; gap: 8px; }
.home-section-title { font-size: 1.1rem; font-weight: 800; color: var(--text); margin: 0; }
.home-more-link { font-size: 0.8rem; font-weight: 600; color: var(--navy); text-decoration: none; white-space: nowrap; }
.home-more-link:hover { text-decoration: underline; }

/* Timeline items */
.tl-item { display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; border-bottom: 1px solid var(--border); cursor: pointer; transition: var(--transition); }
.tl-item:hover { background: var(--gold-soft); }
.tl-item:last-child { border-bottom: none; }
.tl-sport { border-left: 3px solid var(--navy); }
.tl-event { border-left: 3px solid #b45309; }
/* Favorited timeline items get a subtle gold tint background so they're
   visible at a scroll. Border-left stays the source-color (navy/amber) so
   provenance isn't lost. */
.tl-fav { background: rgba(216, 163, 46, 0.08); }
.tl-fav:hover { background: var(--gold-soft); }
.tl-time { font-size: 0.78rem; font-weight: 700; color: var(--gold-text); min-width: 60px; flex-shrink: 0; padding-top: 1px; }
/* 3-column flex row: [MU pill] [title (grows/wraps)] [badges (right-anchored)].
   Critical: flex-wrap: nowrap prevents badges from dropping to a new line
   beneath the title on narrow viewports — instead the title itself wraps
   characters inside its own box via min-width: 0 + overflow-wrap. */
.tl-content { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px; flex: 1; min-width: 0; }
.tl-src { font-size: 0.65rem; font-weight: 700; background: var(--navy); color: var(--gold); padding: 1px 7px; border-radius: var(--radius-pill); flex-shrink: 0; }
.tl-src-event { background: #b45309; color: white; }
.tl-title { font-size: 0.88rem; font-weight: 600; color: var(--text); line-height: 1.3; flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
/* Right-anchored cluster for emoji badges, score, LIVE indicator, stream icon.
   flex-shrink: 0 guarantees badges keep their full width — title shrinks instead.
   :empty hides the cluster entirely (no phantom gap) when an event has no badges. */
.tl-badges { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.tl-badges:empty { display: none; }
.tl-badge { font-size: 0.65rem; flex-shrink: 0; }
.tl-win { color: #166534; font-weight: 700; }
.tl-loss { color: #b91c1c; font-weight: 700; }
.tl-tie { color: #92400e; font-weight: 700; }
.tl-home { color: #166534; }
.tl-family { color: #92400e; }
/* Multi-day continuation badge — same color scheme as card-tag-multiday */
.tl-multiday { background: #dbeafe; color: var(--navy); border: 1px solid #93c5fd; padding: 1px 6px; border-radius: var(--radius-pill); font-size: 0.6rem; font-weight: 700; letter-spacing: 0.2px; }
.tl-stream { font-size: 0.85rem; text-decoration: none; flex-shrink: 0; }
.tl-ticket { font-size: 0.85rem; text-decoration: none; flex-shrink: 0; cursor: pointer; transition: transform 0.1s; }
.tl-ticket:hover { transform: scale(1.15); }

/* Mobile: tighten home timeline density.
   Base styles are tuned for desktop width; on narrow viewports the 10px vertical
   padding adds unnecessary airspace. With the nowrap 3-column layout above,
   each row is now predictably 1-2-3 lines of the title only (no more badge-line
   overflow), so the remaining tightening is all about padding/sizing. */
@media (max-width: 640px) {
    .tl-item { padding: 7px 10px; gap: 10px; }
    .tl-time { min-width: 54px; font-size: 0.76rem; }
    .tl-title { line-height: 1.25; }
    .home-section { margin-bottom: 14px; }
    .home-section-header { margin-bottom: 8px; }
}

/* News compact links */
.home-news-item { display: flex; gap: 8px; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--border); text-decoration: none; transition: var(--transition); }
.home-news-item:hover { background: var(--gold-soft); margin: 0 -8px; padding: 8px; border-radius: var(--radius-sm); }
.home-news-item:last-child { border-bottom: none; }
.home-news-src { font-size: 0.65rem; font-weight: 700; background: var(--surface); border: 1px solid var(--border); color: var(--text-muted); padding: 1px 7px; border-radius: var(--radius-pill); flex-shrink: 0; white-space: nowrap; }
.home-news-title { font-size: 0.88rem; font-weight: 600; color: var(--text); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }

/* Board preview */
.home-board-item { padding: 6px 0; border-bottom: 1px solid var(--border); cursor: pointer; font-size: 0.88rem; }
.home-board-item:last-child { border-bottom: none; }
.home-board-cat { font-weight: 700; font-size: 0.78rem; }
.home-board-title { color: var(--text); }
.home-signup-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border); text-decoration: none; }
.home-signup-item:last-child { border-bottom: none; }
.home-signup-main { display: flex; flex-direction: column; min-width: 0; }
.home-signup-org { font-weight: 700; font-size: 0.9rem; color: var(--text); }
.home-signup-sub { font-size: 0.78rem; color: var(--text-muted); }
.home-signup-deadline { display: flex; flex-direction: column; align-items: flex-end; flex-shrink: 0; }
.home-signup-by { font-weight: 700; font-size: 0.85rem; color: var(--navy); }
.home-signup-days { font-size: 0.74rem; color: var(--text-muted); }
.home-signup-urgent .home-signup-by { color: #b45309; }
.home-signup-urgent .home-signup-days { color: #b45309; font-weight: 600; }

/* Feed CTA */
.home-feed-cta-box { background: linear-gradient(135deg, var(--navy), #1e3a5f); border-radius: var(--radius); padding: 16px 20px; text-align: center; color: white; cursor: pointer; transition: var(--transition); }
.home-feed-cta-box:hover { transform: translateY(-1px); box-shadow: var(--shadow); }

/* Specials cards (kept) */
.home-scroll-row { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; padding-bottom: 8px; }
.home-scroll-row::-webkit-scrollbar { height: 4px; }
.home-scroll-row::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.home-special-card { min-width: 240px; max-width: 280px; flex-shrink: 0; scroll-snap-align: start; background: var(--gold-soft); border: 1px solid var(--gold); border-left: 3px solid var(--gold); border-radius: var(--radius); padding: 14px; }
.home-special-name { font-size: 0.95rem; font-weight: 800; color: var(--navy); margin: 0 0 4px 0; }
.home-special-note { font-size: 0.65rem; color: var(--text-muted); font-style: italic; margin: 0 0 6px 0; }
.home-special-item { font-size: 0.8rem; color: var(--text); margin: 2px 0; }
.home-empty { font-size: 0.85rem; color: var(--text-muted); font-style: italic; padding: 12px 0; }

/* Day-of-week subheading inserted into the home-page "Coming up next"
   list whenever consecutive events span different dates. Gives the
   user date context for what would otherwise be a list of times
   detached from any anchor day. Navy-tinted so it reads as an
   organizational heading rather than secondary muted text. First-child
   selector removes the top spacing when this is the first thing in
   the list (no event item preceding it to separate from). */
.tl-day-divider {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--navy);
    text-transform: none;
    letter-spacing: 0.01em;
    padding: 10px 0 4px;
    margin-top: 6px;
    border-top: 1px solid var(--border);
}
.tl-day-divider:first-of-type {
    border-top: 0;
    margin-top: 0;
    padding-top: 6px;
}

.partner-label { font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: var(--gold); margin-bottom: 4px; }
.special-item { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 0.88rem; }
.special-item:last-child { border-bottom: none; }
.special-day { display: inline-block; background: var(--gold-soft); color: var(--text); font-size: 0.7rem; font-weight: 700; padding: 1px 6px; border-radius: 4px; margin-left: 4px; }

/* =========================================================
   12. WEATHER VIEW
   ========================================================= */
.weather-hero { background: var(--surface); border-radius: var(--radius); padding: 30px 20px; text-align: center; margin-bottom: 20px; border: 1px solid var(--border); box-shadow: var(--shadow); }
.weather-hero-row { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 8px; }
.weather-hero-icon { font-size: 3.5rem; line-height: 1; }
.weather-hero h2 { font-size: 3.5rem; font-weight: 800; color: var(--navy); line-height: 1; margin: 0; }
.weather-feels { font-size: 0.9rem; color: var(--text-muted); margin-top: 2px; }
.weather-cond { font-size: 1.15rem; font-weight: 700; margin-top: 4px; }
.weather-details { font-size: 0.9rem; color: var(--text-muted); margin-top: 8px; }
.weather-updated { font-size: 0.75rem; color: var(--text-muted); margin-top: 8px; }
.weather-source { font-size: 0.7rem; color: var(--text-muted); margin-top: 4px; font-style: italic; }
.cam-wrapper { position: relative; border-radius: var(--radius); overflow: hidden; background: #000; }
.cam-wrapper img { width: 100%; display: block; }
.cam-time { padding: 8px 12px; color: #fff; font-size: 0.7rem; text-align: right; background: rgba(0,0,0,0.5); }
.live-badge { position: absolute; top: 10px; right: 10px; background: rgba(220, 38, 38, 0.9); color: white; padding: 3px 10px; border-radius: 4px; font-size: 0.7rem; font-weight: 700; z-index: 5; display: flex; align-items: center; gap: 5px; }
.live-dot { width: 7px; height: 7px; background: white; border-radius: 50%; animation: blink 1.5s infinite; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* =========================================================
   13. MISC
   ========================================================= */
.ext-link { font-size: 0.85rem; color: var(--navy); font-weight: 700; text-decoration: none; white-space: nowrap; }
.ext-link:hover { text-decoration: underline; }
.empty-state { padding: 32px 20px; text-align: center; color: var(--text-muted); font-size: 0.95rem; grid-column: 1 / -1; background: var(--surface); border: 1px dashed var(--border); border-radius: var(--radius); margin: 12px 0; }
.empty-state p { margin: 0; }
.empty-state p + p { margin-top: 6px; }

/* =========================================================
   14. FOOTER
   ========================================================= */
.site-footer { text-align: center; padding: 30px 20px; margin-top: 40px; border-top: 1px solid var(--border); font-size: 0.8rem; color: var(--text-muted); line-height: 1.6; }
.site-footer p { margin: 2px 0; }

/* =========================================================
   15. STORE PAGE
   ========================================================= */
.store-header { background: linear-gradient(135deg, var(--navy) 0%, #1e3a5f 100%); color: white; padding: 20px; border-radius: var(--radius); margin-bottom: 16px; }
.store-brand { margin-bottom: 14px; }
.store-title { font-size: 1.3rem; font-weight: 800; margin: 0; }
.store-sub { font-size: 0.82rem; opacity: 0.75; margin: 4px 0 0 0; }
.store-tools { display: flex; align-items: center; gap: 12px; }
.store-search-wrap { flex: 1; }
.store-search-wrap input { border-radius: var(--radius) !important; }
.ec-cart-widget { flex-shrink: 0; }

.store-categories { margin-bottom: 16px; padding: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow-x: auto; }
.store-products { min-height: 400px; }
.store-powered { text-align: center; font-size: 0.75rem; color: var(--text-muted); margin-top: 20px; }
.store-powered a { color: var(--navy); font-weight: 600; }

/* Header cart widget */
.header-actions { display: flex; align-items: center; gap: 8px; }
.header-cart { cursor: pointer; }
.header-cart-mobile { display: block; }
.nav-cart-widget { display: none; padding: 4px 12px; cursor: pointer; }

/* Feed gear button — mobile (in header-actions) */
#feed-gear { transition: background 0.15s, color 0.15s; border-radius: 50% !important; }
#feed-gear:hover { background: var(--border-light) !important; color: var(--navy) !important; }

/* Feed gear button — desktop (in nav) - hidden by default on mobile */
.feed-gear-desktop { display: none; }
.feed-dot-desktop { position: absolute; top: 4px; right: 4px; width: 8px; height: 8px; background: var(--gold); border-radius: 50%; }

@media (min-width: 1001px) {
    .header-cart-mobile { display: none; }
    .nav-cart-widget { display: flex; align-items: center; }
    /* Hide the mobile gear entirely on desktop */
    #feed-gear { display: none !important; }
    /* Show desktop gear in nav */
    .feed-gear-desktop {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: none;
        border: none;
        cursor: pointer;
        padding: 8px;
        width: 38px;
        height: 38px;
        margin-left: 4px;
        border-radius: 50%;
        color: var(--text-dark);
        position: relative;
        transition: background 0.15s, color 0.15s;
    }
    .feed-gear-desktop:hover { background: var(--border-light); color: var(--navy); }
    /* Search collapses to an icon button on desktop (label hidden) to claw back inline-nav width */
    .nav-search .nav-search-label { display: none; }
    .nav-search .nav-search-icon { display: inline-flex; }
    .nav-search {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        width: 34px;
        height: 34px;
        padding: 6px;
        border-radius: 50%;
        color: var(--text-dark);
    }
    .nav-search:hover { background: var(--border-light); color: var(--navy); }
}

/* Ecwid overrides to match app theme */
.ecwid .ecwid-productBrowser { font-family: inherit !important; }

/* Hide Mailchimp/Ecwid newsletter popups */
.mcforms-wrapper,
[id^="mcforms-"],
#PopupSignupForm_0, #PopupSignupForm_1,
.mc-banner, .mc-modal, .mc-closeModal,
[class*="mailchimp"], [id*="mailchimp"],
[class*="popup-signup"], [id*="PopupSignup"],
.ec-store__popup, .ec-modal,
[class*="newsletter-popup"], [class*="email-popup"] {
    display: none !important;
    visibility: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
    height: 0 !important;
    width: 0 !important;
    overflow: hidden !important;
    position: fixed !important;
    top: -9999px !important;
    left: -9999px !important;
}

/* Category card sizing — match source site */
.grid__categories .grid-category {
    max-width: 90px !important;
    flex-basis: 90px !important;
}
.grid-category__image-spacer {
    padding-bottom: 0 !important;
    height: 60px !important;
}
.grid-category__shadow-inner {
    font-size: 0.7rem !important;
}

/* =========================================================
   16. ADVERTISE PAGE
   ========================================================= */
.nav-advertise { color: var(--gold) !important; font-weight: 700; }

.adv-hero { background: linear-gradient(135deg, var(--navy) 0%, #1e3a5f 100%); color: white; padding: 32px 24px 20px; border-radius: var(--radius); margin-bottom: 24px; text-align: center; }
.adv-hero-title { font-size: 1.5rem; font-weight: 800; margin: 0 0 8px 0; line-height: 1.2; }
.adv-hero-sub { font-size: 0.9rem; opacity: 0.8; margin: 0 0 20px 0; line-height: 1.5; max-width: 400px; margin-left: auto; margin-right: auto; }
.adv-stats { display: flex; justify-content: center; gap: 32px; }
.adv-stat { text-align: center; }
.adv-stat-num { display: block; font-size: 1.4rem; font-weight: 800; color: var(--gold); }
.adv-stat-label { font-size: 0.65rem; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.5px; }

.adv-section-title { font-size: 1.1rem; font-weight: 800; color: var(--text); margin: 0 0 14px 0; }

/* Tier Grid  */
.adv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 24px; }
@media (max-width: 600px) { .adv-grid { grid-template-columns: 1fr; } }

/* Advertise is a single-tier marketing page — render it as one centered, readable
   column on desktop so the lone card doesn't sit left with dead space beside it.
   Mobile is already single-column and narrower than the cap, so this is desktop-only. */
#view-advertise { max-width: 680px; margin-left: auto; margin-right: auto; }
#view-advertise .adv-grid { grid-template-columns: 1fr; justify-items: center; }

.adv-tier { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; position: relative; display: flex; flex-direction: column; }
.adv-tier-premium { border: 2px solid var(--gold); background: linear-gradient(160deg, #fffbeb 0%, var(--surface) 50%, #fffdf5 100%); }
.adv-tier-cta-card { border: 2px dashed var(--border); background: var(--bg); justify-content: center; align-items: center; text-align: center; }
.adv-tier-badge { position: absolute; top: -9px; right: 14px; font-size: 0.6rem; font-weight: 700; padding: 2px 10px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: 0.3px; background: var(--gold); color: #000; }
.adv-tier-icon { font-size: 1.8rem; margin-bottom: 6px; line-height: 1; }
.adv-tier-name { font-size: 0.95rem; font-weight: 700; margin: 0 0 6px 0; }
.adv-tier-desc { font-size: 0.8rem; color: var(--text-muted); line-height: 1.5; margin: 0 0 12px 0; flex-grow: 1; }
.adv-tier-perks { display: flex; flex-direction: column; gap: 3px; }
.adv-tier-perks span { font-size: 0.75rem; color: var(--text); padding-left: 4px; }

/* CTA */
.adv-cta { background: var(--surface); border: 2px solid var(--gold); border-radius: var(--radius); padding: 28px 24px; text-align: center; margin-bottom: 24px; }
.adv-cta-title { font-size: 1.15rem; font-weight: 800; margin: 0 0 6px 0; }
.adv-cta-sub { font-size: 0.85rem; color: var(--text-muted); margin: 0 0 16px 0; }
.btn-lg { font-size: 1rem; padding: 14px 28px; display: inline-block; }
.adv-cta-note { font-size: 0.78rem; color: var(--text-muted); margin-top: 12px; }
.adv-cta-note a { color: var(--navy); font-weight: 600; }

/* FAQ Accordions */
.adv-accordions { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.adv-accordion { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.adv-accordion[open] { border-color: var(--gold); }
.adv-accordion summary { padding: 14px 18px; font-size: 0.88rem; font-weight: 700; color: var(--text); cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; transition: background 0.2s; }
.adv-accordion summary:hover { background: var(--bg); }
.adv-accordion summary::-webkit-details-marker { display: none; }
.adv-accordion summary::after { content: "+"; font-size: 1.2rem; font-weight: 300; color: var(--text-muted); transition: transform 0.2s; }
.adv-accordion[open] summary::after { content: "−"; color: var(--gold); }
.adv-accordion p { padding: 0 18px 14px; margin: 0; font-size: 0.82rem; color: var(--text-muted); line-height: 1.6; }

/* ============ Loading skeletons ============
   Shown when events.json hasn't loaded yet (first page paint, slow connections).
   Cards mimic the real .app-card shape so the layout doesn't shift when data
   arrives. Shimmer animation is pure CSS — gradient sweep on a translucent
   background. Honors prefers-reduced-motion by stopping the sweep but keeping
   the skeleton shape (still useful as a layout anchor without animation). */
.skel-bar {
    background: linear-gradient(90deg, var(--border) 0%, rgba(0,0,0,0.04) 50%, var(--border) 100%);
    background-size: 200% 100%;
    animation: skel-shimmer 1.4s ease-in-out infinite;
    border-radius: 4px;
    display: inline-block;
}
@keyframes skel-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .skel-bar { animation: none; background: var(--border); }
}
.card-skeleton, .tl-skeleton {
    pointer-events: none;
    /* Subtle gold-soft tint distinguishes loading state from real cards
       without being distracting. Disappears as soon as render fires. */
    opacity: 0.85;
}
.tl-skeleton { border-left-color: var(--border) !important; }

/* ============ Picker chip and pill styles ============
   Extracted from inline styles in app.js for maintainability. The favorites
   picker renders ~30-50 of these per modal open, so reducing inline-style
   duplication trims real bytes per render. Behavior identical to the
   inline versions — just named.
   
   .feed-chip:    small chip used for source pref subs (e.g. 🎵 Music/Arts)
   .feed-chip-tiny: extra-compact chip for nested sub-sports (e.g. ⚾ Baseball
                  inside the Club Sports composite)
   .feed-chip.is-checked: gold-soft background when chosen
   .feed-pill: full-width pill for composite linkedIds (e.g. Arts & Performance)
   .feed-pill.is-checked: gold border + soft background when chosen
*/
.feed-chip {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.82rem;
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    background: var(--bg);
    transition: background 0.15s;
}
.feed-chip-tiny {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.78rem;
    padding: 4px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    background: var(--bg);
    transition: background 0.15s;
}
.feed-chip.is-checked,
.feed-chip-tiny.is-checked {
    background: var(--gold-soft);
}
/* Club browser chip — same as tiny chip but never wraps; long official chapter
   names like "Sigma Alpha Iota International Music Fraternity Inc." would
   wrap into two lines and look broken inside the modal. */
.feed-chip-club { white-space: nowrap; }
.feed-pill {
    font-size: 0.88rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 9px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    transition: 0.15s;
}
.feed-pill > input[type="checkbox"],
.feed-pill-sm > input[type="checkbox"] {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}
.feed-pill.is-checked {
    border-color: var(--gold);
    background: var(--gold-soft);
}
/* Smaller composite pill used inside heading groups (e.g. MU University composites).
   Same shape, different size. */
.feed-pill-sm {
    font-size: 0.85rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 8px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    transition: 0.15s;
}
.feed-pill-sm.is-checked {
    border-color: var(--gold);
    background: var(--gold-soft);
}
/* Shared accent-color for all picker checkboxes. Was inline on every input. */
.feed-sub, .feed-group, .feed-club, .feed-subgroup-master {
    accent-color: var(--gold);
}

/* ============ Modal & overlay shared styles ============ */
.modal-close-btn {
    position: absolute;
    top: 12px;
    right: 12px;
    background: none;
    border: none;
    font-size: 1.2rem;
    cursor: pointer;
    color: var(--text-muted);
}

/* Compact section label inside modals (uppercase, muted, used for grouping
   search results). */
.modal-section-label {
    color: var(--text-muted);
    font-size: 0.8rem;
    text-transform: uppercase;
    margin-bottom: 8px;
}

/* Search-result row in the search overlay. */
.search-result {
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    margin-bottom: 4px;
    background: var(--surface);
}
.search-result:hover { background: var(--bg); }

/* ============ Home day navigator ============
   Replaces the old static "Today in Millersville" heading with a date-stepper.
   Layout: [‹] [📅 Today, Apr 28] [›] [Today]   ←  Today snap-back only when off-today
   Buttons are 32x32 to meet WCAG/iOS hit target guidelines on mobile. */
.home-day-nav {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
    min-width: 0;
}
.home-day-btn {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    font-size: 1.2rem;
    line-height: 1;
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
    transition: background 0.12s, border-color 0.12s;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.home-day-btn:hover { background: var(--gold-soft); border-color: var(--gold); }
.home-day-btn:active { transform: scale(0.95); }
.home-day-today-btn {
    background: var(--gold-soft);
    border: 1px solid var(--gold);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
    transition: background 0.12s;
    margin-left: 2px;
    flex: 0 0 auto;
    white-space: nowrap;
}
.home-day-today-btn:hover { background: var(--gold); }
.home-day-label {
    margin: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Slide-animation containers used during day-nav transitions. The timeline
   wraps a track containing two panels (outgoing + incoming) side-by-side;
   JS animates the track's translateX to reveal the incoming panel. */
.home-slide-track {
    display: flex;
    width: 200%;
    will-change: transform;
}
.home-slide-panel {
    width: 50%;
    flex-shrink: 0;
}
