/* ========== styles.css ========== */
/**
 * DJ SEIP BACKSTAGE v5.3 - Styles (FIXED + ENGAGEMENT)
 * Added: Daily bonus modal, combo HUD, fever mode, achievements, share bar
 */

/* ============ ROOT VARIABLES ============ */
:root {
    --bg: #0a0a0f;
    --surface: #13131a;
    --surface2: #1c1c26;
    --primary: #6c5ce7;
    --gold: #fdcb6e;
    --cyan: #00cec9;
    --danger: #e74c3c;
    --success: #00b894;
    --text: #fff;
    --text2: #9ca3af;
    --text3: #6b7280;
    --pad: 16px;
    --pad-lg: 24px;
    --radius: 12px;
    --radius-sm: 8px;
    --radius-lg: 20px;       /* missing var — used by modals/cards */
    --text1: #fff;           /* alias for --text, used in some components */
    --bg2: #1c1c26;          /* alias for --surface2, used in overlays */
}

/* ============ ACCESSIBILITY ============ */
/* Visually hidden but accessible to screen readers */
.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Skip link for keyboard navigation */
.skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: var(--primary);
    color: white;
    padding: 8px;
    z-index: 10000;
}

.skip-link:focus {
    top: 0;
}

/* ============ RESET & BASE ============ */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

html {
    font-size: 16px;
    height: 100%;
    height: 100dvh;
    overflow: hidden;
    position: fixed;
    width: 100%;
    top: 0;
    left: 0;
}

body {
    width: 100%;
    height: 100%;
    height: 100dvh;
    max-height: 100%;
    max-height: 100dvh;
    overflow: hidden;
    position: fixed;
    inset: 0;
    font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg);
    color: var(--text);
    touch-action: manipulation;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overscroll-behavior: none;
}

/* ============ SCREEN LAYOUT ============ */
.screen {
    position: fixed;
    inset: 0;
    display: none;
    flex-direction: column;
    height: 100%;
    height: 100dvh;
    max-height: 100%;
    max-height: 100dvh;
    overflow: hidden;
}

.screen.active {
    display: flex;
}

/* ============ BUTTONS ============ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.875rem 1.5rem;
    border: none;
    border-radius: var(--radius);
    font: 600 0.9375rem 'Space Grotesk', sans-serif;
    cursor: pointer;
    color: #fff;
    text-decoration: none;
    transition: transform 0.15s, opacity 0.15s, box-shadow 0.15s;
    min-height: 48px;
}

.btn:active {
    transform: scale(0.97);
    opacity: 0.9;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-primary {
    background: linear-gradient(135deg, var(--primary), #a55eea);
    box-shadow: 0 4px 15px rgba(108, 92, 231, 0.3);
}

.btn-gold {
    background: linear-gradient(135deg, var(--gold), #e17055);
    color: #000;
    box-shadow: 0 4px 15px rgba(253, 203, 110, 0.3);
}

.btn-secondary {
    background: var(--surface2);
    border: 1px solid rgba(255, 255, 255, 0.12);
}

.btn-danger {
    background: var(--danger);
}

.btn-success {
    background: var(--success);
}

.btn-cyan {
    background: linear-gradient(135deg, var(--cyan), #00a8cc);
    color: #000;
}

/* Spotify branded button */
.btn-spotify {
    background: linear-gradient(135deg, #1DB954, #1ed760);
    color: #000;
    box-shadow: 0 4px 15px rgba(29, 185, 84, 0.4);
    font-weight: 700;
    width: 100%;
    margin-bottom: 0.5rem;
    animation: spotifyPulse 2s ease-in-out infinite;
}

.btn-spotify:hover {
    background: linear-gradient(135deg, #1ed760, #1DB954);
    box-shadow: 0 6px 20px rgba(29, 185, 84, 0.5);
}

.btn-spotify .spotify-icon {
    font-size: 1.25rem;
}

@keyframes spotifyPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.02); }
}

/* Streaming bonus bar */
.streaming-bonus-bar {
    background: linear-gradient(135deg, var(--surface), rgba(29, 185, 84, 0.1));
    border: 1px solid rgba(29, 185, 84, 0.3);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin: 1rem auto;
    max-width: 340px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.streaming-bonus-info {
    flex: 1;
}

.streaming-bonus-title {
    font-weight: 600;
    font-size: 0.875rem;
    color: #1DB954;
}

.streaming-bonus-desc {
    font-size: 0.75rem;
    color: var(--text2);
}

.streaming-bonus-btn {
    background: linear-gradient(135deg, #1DB954, #1ed760);
    color: #000;
    padding: 0.5rem 1rem;
    border-radius: var(--radius-sm);
    font-weight: 700;
    font-size: 0.8125rem;
    border: none;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s;
}

.streaming-bonus-btn:hover {
    transform: scale(1.05);
    box-shadow: 0 4px 12px rgba(29, 185, 84, 0.4);
}

.streaming-bonus-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

/* Streaming Bonus Verification Modal */
.streaming-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.9);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 1rem;
}

.streaming-modal.show {
    display: flex;
}

.streaming-modal-box {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 1.5rem;
    max-width: 360px;
    width: 100%;
    text-align: center;
    position: relative;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-close-btn {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    background: none;
    border: none;
    color: var(--text2);
    font-size: 1.25rem;
    cursor: pointer;
    padding: 0.25rem;
}

.streaming-modal-icon {
    font-size: 3rem;
    margin-bottom: 0.5rem;
}

.streaming-modal-box h2 {
    color: #1DB954;
    margin-bottom: 1rem;
}

.streaming-step {
    margin: 1rem 0;
    padding: 1rem;
    background: var(--surface2);
    border-radius: var(--radius-sm);
}

.streaming-step-text {
    font-size: 0.875rem;
    color: var(--text2);
    margin-bottom: 0.75rem;
}

.streaming-question {
    font-weight: 700;
    color: var(--text);
    margin-bottom: 1rem;
    font-size: 1rem;
}

.streaming-answers {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.streaming-answer {
    padding: 0.75rem;
    background: var(--surface);
    border: 2px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
    text-align: left;
    font-size: 0.875rem;
}

.streaming-answer:hover {
    background: rgba(29, 185, 84, 0.1);
}

.streaming-answer.selected {
    border-color: #1DB954;
    background: rgba(29, 185, 84, 0.15);
}

.streaming-bonus-reward {
    font-size: 0.875rem;
    color: var(--gold);
    margin-top: 1rem;
}

.btn-sm {
    padding: 0.5rem 1rem;
    font-size: 0.8125rem;
    min-height: 40px;
    border-radius: var(--radius-sm);
}

/* ============ COOKIE BANNER ============ */
.cookie-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10000;
    background: var(--surface);
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding: var(--pad);
    display: none;
    flex-direction: column;
    gap: 0.875rem;
}

.cookie-banner.show {
    display: flex;
}

.cookie-title {
    font-weight: 700;
    font-size: 1rem;
}

.cookie-text {
    font-size: 0.875rem;
    color: var(--text2);
    line-height: 1.6;
}

.cookie-text a {
    color: var(--primary);
}

.cookie-options {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.cookie-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.9375rem;
    cursor: pointer;
    padding: 0.75rem;
    margin: -0.25rem;
    border-radius: var(--radius-sm);
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    -webkit-user-select: none;
}

.cookie-option:active {
    background: rgba(255, 255, 255, 0.05);
}

/* Hide native checkbox */
.cookie-option input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

/* Custom checkbox */
.cookie-option .checkbox-custom {
    width: 24px;
    height: 24px;
    min-width: 24px;
    min-height: 24px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    background: transparent;
}

/* Checkmark */
.cookie-option .checkbox-custom::after {
    content: '';
    width: 12px;
    height: 12px;
    background: var(--primary);
    border-radius: 3px;
    transform: scale(0);
    transition: transform 0.15s ease;
}

/* Checked state */
.cookie-option input[type="checkbox"]:checked + .checkbox-custom {
    border-color: var(--primary);
    background: rgba(108, 92, 231, 0.2);
}

.cookie-option input[type="checkbox"]:checked + .checkbox-custom::after {
    transform: scale(1);
}

/* Disabled state */
.cookie-option input[type="checkbox"]:disabled + .checkbox-custom {
    opacity: 0.5;
    cursor: not-allowed;
}

.cookie-btns {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* ============ PLATFORM SCREEN ============ */
.platform {
    background: linear-gradient(180deg, var(--surface), var(--bg));
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    padding: calc(env(safe-area-inset-top, 0px) + var(--pad)) var(--pad) calc(env(safe-area-inset-bottom, 0px) + 20px);
    height: 100%;
    height: 100dvh;
    max-height: 100%;
    max-height: 100dvh;
}

/* Hero Section */
.hero {
    text-align: center;
    padding: 2rem var(--pad);
}

.logo {
    width: 72px;
    height: 72px;
    margin: 0 auto 1rem;
    background: linear-gradient(135deg, var(--primary), #fd79a8);
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.25rem;
    box-shadow: 0 8px 30px rgba(108, 92, 231, 0.4);
}

.brand {
    font: 700 1.75rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.1em;
}

.brand span {
    color: var(--gold);
}

.tagline {
    color: var(--text2);
    font-size: 0.9375rem;
    max-width: 320px;
    margin: 0.75rem auto 0;
    line-height: 1.7;
}

/* Player Bar */
.player-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1rem;
    padding: 0.5rem 1rem;
    background: var(--surface);
    border-radius: 24px;
    font-size: 0.875rem;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
}

.player-bar button {
    padding: 0.25rem 0.625rem;
    font-size: 0.75rem;
}

.streak-badge {
    background: linear-gradient(135deg, #ff6b6b, #e17055);
    padding: 0.25rem 0.625rem;
    border-radius: 12px;
    font-size: 0.75rem;
    font-weight: 700;
    color: #fff;
}

.vinyl-count-badge {
    background: linear-gradient(135deg, #2d2940, #1e1a30);
    border: 1px solid rgba(253, 203, 110, 0.3);
    padding: 0.25rem 0.625rem;
    border-radius: 12px;
    font-size: 0.75rem;
    font-weight: 700;
    color: #fdcb6e;
    letter-spacing: 0.02em;
}

/* ============ SOCIAL SHARE BAR ============ */
.share-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin: 1.5rem auto;
    padding: 0.75rem 1.25rem;
    background: var(--surface);
    border-radius: var(--radius);
    max-width: 320px;
    width: 100%;
    /* Same robustness note as .dashboard-card/.referral-panel above —
       align-self is the unambiguous way to center a capped-width flex
       child in a column, rather than relying on margin:auto alone. */
    align-self: center;
}

.share-label {
    font-size: 0.75rem;
    color: var(--text2);
}

.share-btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: var(--surface2);
    color: #fff;
    font-size: 1rem;
    cursor: pointer;
    transition: transform 0.15s, background 0.15s;
}

.share-btn:hover {
    background: var(--primary);
    transform: scale(1.1);
}

.share-btn:active {
    transform: scale(0.95);
}

/* Name Modal */
.name-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 250;
    padding: var(--pad);
}

.name-modal.show {
    display: flex;
}

.name-modal-box {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 1.5rem;
    width: 100%;
    max-width: 320px;
    text-align: center;
}

.name-modal-box h3 {
    font: 700 1.25rem 'Bebas Neue', sans-serif;
    margin-bottom: 1rem;
}

.name-modal-box input {
    width: 100%;
    padding: 0.75rem;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: var(--bg);
    color: #fff;
    font-size: 1rem;
    margin-bottom: 1rem;
}

.name-modal-box .btns {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
}

/* ============ DAILY BONUS MODAL ============ */
.daily-bonus-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.92);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 300;
    padding: var(--pad);
}

.daily-bonus-modal.show {
    display: flex;
    animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.daily-bonus-box {
    background: linear-gradient(135deg, var(--surface), #1a1a28);
    border: 2px solid var(--gold);
    border-radius: 20px;
    padding: 2rem 1.5rem;
    width: 100%;
    max-width: 320px;
    text-align: center;
    animation: bounceIn 0.4s ease;
}

@keyframes bounceIn {
    0% { transform: scale(0.8); opacity: 0; }
    50% { transform: scale(1.05); }
    100% { transform: scale(1); opacity: 1; }
}

.daily-bonus-icon {
    font-size: 4rem;
    margin-bottom: 0.5rem;
    animation: bounce 1s infinite;
}

@keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
}

.daily-bonus-box h2 {
    font: 700 1.75rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    margin-bottom: 0.75rem;
}

.daily-bonus-streak {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    font-size: 1.125rem;
    font-weight: 700;
    color: #ff6b6b;
    margin-bottom: 1rem;
}

.daily-bonus-amount {
    font: 700 3rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    text-shadow: 0 4px 20px rgba(253, 203, 110, 0.4);
    margin-bottom: 0.5rem;
}

.daily-bonus-tip {
    font-size: 0.8125rem;
    color: var(--text2);
    margin-bottom: 1.25rem;
}

/* ============ TABS ============ */
.tabs {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin: 1rem auto;
    padding: 0 0.5rem;
    max-width: 500px;
    /* Same flexbox reasoning as .hero above — this is also a direct flex
       child of .platform and must never be allowed to shrink. */
    flex-shrink: 0;
}

.tab {
    padding: 0.5rem 0.75rem;
    background: var(--surface);
    border-radius: var(--radius-sm);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, transform 0.15s;
    white-space: nowrap;
    text-align: center;
    min-width: 0;
}

.tab:active {
    transform: scale(0.96);
}

.tab.active {
    background: var(--primary);
}

/* Mobile: 3 tabs on top row, 2 on bottom row
   NOTE: this base .tabs rule is superseded in production by the more
   specific `.platform .tabs` rule further down (balanced 3+2 column-span
   grid) — kept here only as the fallback for any context that renders
   .tabs outside .platform. */
@media (max-width: 420px) {
    .tabs {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 0.375rem;
        max-width: 360px;
        padding: 0 0.75rem;
    }
    
    .tab {
        padding: 0.5rem 0.375rem;
        font-size: 0.6875rem;
    }
    
    /* Last two tabs span bottom row */
    .tab:nth-child(4) {
        grid-column: 1 / 2;
    }
    .tab:nth-child(5) {
        grid-column: 2 / 4;
    }
}

@media (max-width: 320px) {
    .tab {
        font-size: 0.625rem;
        padding: 0.4rem 0.25rem;
    }
}

/* ============ SONG CARDS ============ */
.songs-list {
    max-width: 480px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0 0.25rem;
}

.songs-section {
    margin-bottom: 1.25rem;
}

.songs-section-title {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text3);
    margin-bottom: 0.625rem;
    padding: 0 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.songs-section-title::after {
    content: '';
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.1);
}

.featured-card {
    background: linear-gradient(135deg, var(--surface) 0%, rgba(108, 92, 231, 0.15) 100%);
    border: 1px solid rgba(108, 92, 231, 0.3);
    border-radius: 18px;
    padding: 1.25rem;
    margin-bottom: 0.875rem;
}

.featured-card .song-art {
    width: 72px;
    height: 72px;
    border-radius: 14px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}

.featured-card .song-title {
    font-size: 1.125rem;
}

.featured-card .play-btn {
    width: 48px;
    height: 48px;
    font-size: 1.125rem;
}

.song-card {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--radius);
    padding: 0.875rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s;
}

.song-card:active {
    transform: scale(0.98);
}

.song-card:hover {
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.song-card.completed {
    border-color: var(--primary) !important;
}

.song-art {
    width: 56px;
    height: 56px;
    border-radius: var(--radius);
    background: var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.375rem;
    overflow: hidden;
    flex-shrink: 0;
    position: relative;
}

.song-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.completed-check {
    position: absolute;
    bottom: -2px;
    right: -2px;
    width: 20px;
    height: 20px;
    background: var(--primary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.625rem;
    color: #fff;
    font-weight: 700;
}

.song-info {
    flex: 1;
    min-width: 0;
}

.song-title {
    font-size: 1rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.song-artist {
    color: var(--text2);
    font-size: 0.875rem;
    margin-top: 0.125rem;
}

.song-release {
    font-size: 0.75rem;
    color: var(--text3);
    margin-top: 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.badge {
    display: inline-block;
    margin-top: 0.25rem;
    padding: 0.1875rem 0.5rem;
    border-radius: 6px;
    font-size: 0.6875rem;
    font-weight: 600;
}

.badge.pre {
    background: rgba(253, 203, 110, 0.15);
    color: var(--gold);
}

.badge.out {
    background: rgba(0, 184, 148, 0.15);
    color: var(--success);
}

.badge.completed {
    background: rgba(108, 92, 231, 0.2);
    color: var(--primary);
}

.badge.exclusive {
    background: linear-gradient(135deg, rgba(255, 215, 0, 0.2), rgba(255, 140, 0, 0.2));
    color: #ffd700;
}

.badge.limited {
    background: rgba(231, 76, 60, 0.15);
    color: #e74c3c;
    margin-left: 0.25rem;
}

.badge.upcoming {
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.2), rgba(165, 94, 234, 0.2));
    color: var(--primary);
}

/* Upcoming Song Card */
.upcoming-card {
    opacity: 0.85;
    cursor: default !important;
}

.upcoming-card:hover {
    transform: none !important;
}

.upcoming-card .song-art {
    position: relative;
}

.upcoming-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    border-radius: inherit;
}

.play-btn {
    width: 44px;
    height: 44px;
    background: var(--primary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    flex-shrink: 0;
}

/* Song Reward Button */
.song-reward-btn {
    margin-top: 0.5rem;
    padding: 0.375rem 0.75rem !important;
    min-height: 32px !important;
}

/* Archive */
.archive-toggle {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    margin-top: 0.5rem;
    font-size: 0.875rem;
    color: var(--text2);
}

.archive-toggle:hover {
    background: var(--surface2);
}

.archive-toggle .arrow {
    transition: transform 0.2s;
}

.archive-toggle.open .arrow {
    transform: rotate(180deg);
}

.archive-list {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.archive-list.open {
    max-height: 1000px;
}

.archive-card {
    opacity: 0.7;
    transform: scale(0.98);
}

.archive-card:hover {
    opacity: 1;
}

/* ============ LEADERBOARD ============ */
.lb-list {
    max-width: 480px;
    margin: 0 auto;
    padding: 0 0.25rem 1rem;
    max-height: 60dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

.lb-header,
.scores-header {
    text-align: center;
    padding: 1rem var(--pad);
}

.lb-header h3,
.scores-header h3 {
    font-size: 1.25rem;
    margin-bottom: 0.25rem;
}

.lb-subtitle,
.scores-subtitle {
    font-size: 0.8125rem;
    color: var(--text3);
}

.lb-item {
    background: var(--surface);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.875rem;
}

/* Highlights the current player's own row when they appear in the visible
   top-20 — the backend already computed player_rank, this was just never
   surfaced anywhere. Seeing "that's me" is a real engagement/retention
   lever that cost nothing to add since the data already existed. */
.lb-item--me {
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.18), rgba(108, 92, 231, 0.06));
    border: 1px solid rgba(108, 92, 231, 0.4);
}

/* "Your rank" pinned summary — shown when the player isn't in the visible
   top-20, so they still get a concrete, motivating number instead of
   just seeing 20 strangers with no idea where they stand. */
.lb-your-rank {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.16), rgba(108, 92, 231, 0.05));
    border: 1px solid rgba(108, 92, 231, 0.3);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    margin-bottom: 0.875rem;
}
.lb-your-rank .lb-rank {
    background: var(--primary);
    color: #fff;
}
.lb-your-rank-label {
    font-size: 0.7rem;
    color: var(--text2);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
}
.lb-your-rank-value {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text);
}

/* Error state — was previously nonexistent: a failed fetch left the tab
   stuck on "Loading..." forever with no way to recover short of a full
   page reload. */
.lb-error {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--text2);
}
.lb-error button {
    margin-top: 0.75rem;
}

.lb-rank {
    width: 28px;
    height: 28px;
    background: var(--surface2);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.8125rem;
    flex-shrink: 0;
}

.lb-rank.gold {
    background: var(--gold);
    color: #000;
}

.lb-rank.silver {
    background: #c0c0c0;
    color: #000;
}

.lb-rank.bronze {
    background: #cd7f32;
    color: #000;
}

.lb-info {
    flex: 1;
    min-width: 0;
}

.lb-player {
    font-weight: 700;
    font-size: 1rem;
    color: var(--text1);
}

.lb-song {
    font-weight: 600;
}

.lb-meta {
    font-size: 0.75rem;
    color: var(--text3);
    margin-top: 0.125rem;
}

.lb-score {
    text-align: right;
}

.lb-vinyls {
    font-weight: 700;
    color: var(--gold);
}

.lb-status {
    font-size: 0.6875rem;
    color: var(--success);
    margin-top: 0.125rem;
}

/* ============ GAME HISTORY ============ */
.history-header {
    text-align: center;
    padding: 1rem 0 1.25rem;
}

.history-header h3 {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    margin-bottom: 0.375rem;
}

.history-subtitle {
    font-size: 0.875rem;
    color: var(--text2);
}

.history-stats-grid {
    display: grid;
    /* 3 columns × 2 rows fits the 6 stat cards now shown here evenly
       (Total Games / Chaos Mode / Best Score / Best Combo, plus Total
       Vinyls / Meters Run moved over from the old Challenges tab) -
       the previous 4-column grid left an awkward half-empty last row
       once there were more than 4 cards. */
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    margin-bottom: 1rem;
    padding: 0 var(--pad);
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
}

.history-stat-card {
    background: var(--surface);
    border-radius: var(--radius-sm);
    padding: 0.75rem 0.5rem;
    text-align: center;
}

.history-stat-value {
    display: block;
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--gold);
}

.history-stat-label {
    display: block;
    font-size: 0.625rem;
    color: var(--text3);
    margin-top: 0.25rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.history-list {
    max-width: 480px;
    margin: 0 auto;
    padding: 0 var(--pad) 1rem;
    max-height: 50dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

.history-item {
    background: var(--surface);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.history-type-icon {
    width: 36px;
    height: 36px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.125rem;
    flex-shrink: 0;
}

.history-type-icon.normal {
    background: linear-gradient(135deg, var(--primary), #8B5CF6);
}

.history-type-icon.chaos {
    background: linear-gradient(135deg, #EC4899, #F97316);
}

.history-type-icon.completed {
    background: linear-gradient(135deg, var(--success), #22D3EE);
}

.history-info {
    flex: 1;
    min-width: 0;
}

.history-song {
    font-weight: 600;
    font-size: 0.875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.history-meta {
    font-size: 0.6875rem;
    color: var(--text3);
    margin-top: 0.125rem;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.history-stats {
    text-align: right;
    flex-shrink: 0;
}

.history-score {
    font-weight: 700;
    color: var(--gold);
    font-size: 0.9375rem;
}

.history-details {
    font-size: 0.6875rem;
    color: var(--text3);
    margin-top: 0.125rem;
}

.history-time {
    font-size: 0.625rem;
    color: var(--text3);
    margin-top: 0.25rem;
}

@media (max-width: 360px) {
    .history-stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ============ CHALLENGES ============ */
.challenges-header {
    text-align: center;
    padding: 1rem 0 1.25rem;
}

.challenges-header h3 {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    margin-bottom: 0.375rem;
}

.challenges-subtitle {
    font-size: 0.875rem;
    color: var(--text2);
}

.challenges-stats {
    display: flex;
    justify-content: center;
    gap: 1.25rem;
    margin-top: 1.5rem;
    padding: 1.25rem;
    background: var(--surface);
    border-radius: var(--radius);
    max-width: 480px;
    margin-left: auto;
    margin-right: auto;
}

.stat-box {
    text-align: center;
    flex: 1;
}

.stat-num {
    display: block;
    font: 700 1.5rem 'Bebas Neue', sans-serif;
    color: var(--gold);
}

.stat-lbl {
    font-size: 0.6875rem;
    color: var(--text2);
}

.challenges-list {
    max-width: 480px;
    margin: 0 auto;
    padding: 0 0.25rem;
}

.challenge-card {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--radius);
    padding: 1rem;
    margin-bottom: 0.75rem;
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
}

.challenge-card.completed {
    border-color: var(--success);
    background: linear-gradient(135deg, rgba(0, 184, 148, 0.08), transparent);
}

.challenge-icon {
    width: 44px;
    height: 44px;
    background: var(--surface2);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.375rem;
    flex-shrink: 0;
}

.challenge-info {
    flex: 1;
    min-width: 0;
}

.challenge-title {
    font-size: 1rem;
    font-weight: 700;
}

.challenge-desc {
    font-size: 0.8125rem;
    color: var(--text2);
    margin-top: 0.125rem;
}

.challenge-progress {
    margin-top: 0.625rem;
}

.challenge-progress-bar {
    height: 8px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 4px;
    overflow: hidden;
}

.challenge-progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--primary), var(--gold));
    border-radius: 4px;
    transition: width 0.3s;
}

.challenge-progress-text {
    font-size: 0.75rem;
    color: var(--text2);
    margin-top: 0.25rem;
}

.challenge-status {
    font-size: 1.25rem;
}

/* ============ BADGES DISPLAY ============ */
.badges-header {
    text-align: center;
    padding: 1rem var(--pad);
}

.badges-header h3 {
    font-size: 1.25rem;
    margin-bottom: 0.25rem;
}

.badges-subtitle {
    font-size: 0.8125rem;
    color: var(--text2);
}

.badges-progress {
    margin-top: 0.75rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--gold);
}

.badges-grid {
    max-width: 480px;
    margin: 0 auto;
    padding: 0 var(--pad);
}

.badge-category {
    margin-bottom: 1.5rem;
}

.badge-category-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.badge-category-name {
    font-size: 0.875rem;
    font-weight: 600;
}

.badge-category-progress {
    font-size: 0.75rem;
    color: var(--text2);
}

.badge-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.75rem;
}

.badge-item {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--radius);
    padding: 0.875rem 0.5rem;
    text-align: center;
    cursor: pointer;
    transition: all 0.2s;
}

.badge-item:hover {
    transform: translateY(-2px);
    border-color: var(--primary);
}

.badge-item.earned {
    border-color: var(--gold);
    background: linear-gradient(135deg, rgba(253, 203, 110, 0.1), transparent);
}

.badge-item.locked {
    opacity: 0.6;
}

.badge-item.locked .badge-icon {
    filter: grayscale(100%);
}

.badge-icon {
    font-size: 1.75rem;
    margin-bottom: 0.375rem;
}

.badge-name {
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.2;
}

.badge-progress-bar {
    height: 4px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 2px;
    margin-top: 0.5rem;
    overflow: hidden;
}

.badge-progress-fill {
    height: 100%;
    background: var(--primary);
    border-radius: 2px;
    transition: width 0.3s;
}

/* Badge Detail Modal */
.badge-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: var(--pad);
    opacity: 0;
    transition: opacity 0.2s;
}

.badge-modal.show {
    opacity: 1;
}

.badge-modal-content {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 2rem;
    text-align: center;
    max-width: 300px;
    width: 100%;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.badge-modal-content.earned {
    border-color: var(--gold);
}

.badge-modal-icon {
    font-size: 3.5rem;
    margin-bottom: 1rem;
}

.badge-modal-title {
    font-size: 1.25rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.badge-modal-desc {
    font-size: 0.875rem;
    color: var(--text2);
    margin-bottom: 1rem;
}

.badge-modal-status {
    font-size: 1rem;
    color: var(--success);
    font-weight: 600;
    margin-bottom: 1rem;
}

.badge-modal-howto {
    background: rgba(108, 92, 231, 0.1);
    border: 1px solid var(--primary);
    border-radius: var(--radius);
    padding: 0.875rem;
    font-size: 0.8125rem;
    color: var(--text2);
    margin-bottom: 1rem;
    text-align: left;
}

.badge-modal-howto strong {
    color: var(--gold);
}

.badge-detail-progress {
    font-size: 0.875rem;
    color: var(--text2);
    margin-bottom: 1rem;
}

/* ============ REFERRAL PANEL ============ */
.referral-panel {
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.15), rgba(253, 203, 110, 0.1));
    border: 1px solid rgba(108, 92, 231, 0.3);
    border-radius: var(--radius);
    margin: 1rem auto;
    overflow: hidden;
    /* Same capped+centered treatment as .dashboard-card above it, and for
       the same reason — without this it stayed full-width at any size
       below 901px, which looked inconsistent under the now-centered card. */
    width: 100%;
    max-width: 900px;
    align-self: center;
}

.referral-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    background: rgba(108, 92, 231, 0.1);
    cursor: pointer;
}

.referral-header:hover {
    background: rgba(108, 92, 231, 0.15);
}

.referral-title {
    font: 600 0.875rem 'Space Grotesk', sans-serif;
    color: var(--gold);
}

.referral-toggle {
    background: none;
    border: none;
    color: var(--text2);
    font-size: 0.75rem;
    cursor: pointer;
    transition: transform 0.3s;
    padding: 0.25rem;
}

.referral-panel.collapsed .referral-toggle {
    transform: rotate(-90deg);
}

.referral-content {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.referral-panel.collapsed .referral-content {
    display: none;
}

.referral-code-box {
    background: var(--surface);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    text-align: center;
}

.referral-label {
    font-size: 0.7rem;
    color: var(--text3);
    display: block;
    margin-bottom: 0.25rem;
}

.referral-code {
    font: 600 0.9rem 'Space Grotesk', monospace;
    color: var(--primary);
    word-break: break-all;
    user-select: all;
}

.referral-share-buttons {
    display: flex;
    gap: 0.5rem;
}

.referral-btn {
    flex: 1;
    padding: 0.6rem 0.5rem;
    border: none;
    border-radius: var(--radius-sm);
    font: 600 0.75rem 'Space Grotesk', sans-serif;
    cursor: pointer;
    transition: all 0.2s;
    background: var(--surface2);
    color: var(--text);
}

.referral-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

.referral-btn.whatsapp {
    background: #25D366;
    color: #fff;
}

.referral-btn.twitter {
    background: #000;
    color: #fff;
}

.referral-rewards {
    display: flex;
    justify-content: space-around;
    padding: 0.5rem 0;
    border-top: 1px solid rgba(255,255,255,0.05);
    border-bottom: 1px solid rgba(255,255,255,0.05);
}

.referral-reward-item {
    text-align: center;
    font-size: 0.75rem;
    color: var(--text2);
}

.referral-reward-value {
    display: block;
    font: 700 1rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    margin-top: 0.25rem;
}

.referral-stats {
    display: flex;
    justify-content: space-around;
}

.referral-stat {
    text-align: center;
}

.referral-stat-value {
    font: 700 1.25rem 'Bebas Neue', sans-serif;
    color: var(--cyan);
    display: block;
}

.referral-stat-label {
    font-size: 0.65rem;
    color: var(--text3);
}

.referral-badges {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    flex-wrap: wrap;
}

.referral-badge {
    background: linear-gradient(135deg, var(--gold), #e17055);
    color: #000;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    font: 600 0.65rem 'Space Grotesk', sans-serif;
}

.referral-badge.legendary {
    background: linear-gradient(135deg, #a29bfe, #6c5ce7);
    color: #fff;
    animation: legendaryPulse 2s infinite;
}

@keyframes legendaryPulse {
    0%, 100% { box-shadow: 0 0 5px rgba(108, 92, 231, 0.5); }
    50% { box-shadow: 0 0 15px rgba(108, 92, 231, 0.8); }
}

/* Empty State */
.empty {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--text3);
}

.empty-icon {
    font-size: 2.5rem;
    margin-bottom: 0.625rem;
    opacity: 0.5;
}

/* Footer */
.footer {
    text-align: center;
    padding: 1.5rem var(--pad);
    border-top: 1px solid rgba(255, 255, 255, 0.05);
    margin-top: 2rem;
}

.footer-links {
    margin-bottom: 0.75rem;
}

.footer-links a {
    color: var(--text2);
    font-size: 0.8125rem;
    margin: 0 0.75rem;
    text-decoration: none;
}

.footer-links a:hover {
    color: var(--text);
}

.footer-lang {
    margin: 0.75rem 0;
}

.lang-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.75rem;
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 20px;
    color: var(--text2);
    font-size: 0.75rem;
    cursor: pointer;
    transition: all 0.2s;
}

.lang-btn:hover {
    background: var(--surface2);
    border-color: rgba(255, 255, 255, 0.2);
    color: var(--text);
}

.lang-flag {
    font-size: 1rem;
    line-height: 1;
}

.lang-code {
    font-weight: 600;
    text-transform: uppercase;
}

.footer-copy {
    font-size: 0.75rem;
    color: var(--text3);
    margin-top: 0.5rem;
}

/* Ad Banner */
.ad-banner {
    width: 100%;
    max-width: 480px;
    margin: 1rem auto;
    height: 90px;
    max-height: 90px;
    background: var(--surface);
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    color: var(--text3);
    overflow: hidden;
}

/* Strict control over AdSense element size */
.ad-banner .adsbygoogle {
    display: block !important;
    max-height: 90px !important;
    overflow: hidden !important;
}

/* Pre-game ad - compact thin banner below START button */
.ad-banner.pregame-ad {
    margin: 0.75rem auto 0;
    height: 50px;
    max-height: 50px;
    min-height: unset;
    background: transparent;
}

.ad-banner.pregame-ad .adsbygoogle {
    max-height: 50px !important;
}

/* Hide pregame ad on very small screens */
@media (max-height: 550px) {
    .ad-banner.pregame-ad {
        display: none;
    }
}

/* Mobile: center the fixed-size ad */
@media (max-width: 768px) {
    .ad-banner {
        height: 90px;
        max-height: 90px;
        justify-content: center;
    }
    
    .ad-banner.pregame-ad {
        height: 50px;
        max-height: 50px;
    }
}

/* ============ LEGAL PAGES ============ */
.legal-page {
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: calc(env(safe-area-inset-top, 0px) + var(--pad)) var(--pad) calc(env(safe-area-inset-bottom, 0px) + 100px);
    height: 100%;
}

.legal-content {
    max-width: 680px;
    margin: 0 auto;
}

.legal-content h1 {
    font-size: 1.75rem;
    color: var(--gold);
    margin-bottom: 1.25rem;
}

.legal-content h2 {
    font-size: 1.25rem;
    color: var(--primary);
    margin: 1.75rem 0 0.625rem;
}

.legal-content h3 {
    font-size: 1.0625rem;
    color: var(--text);
    margin: 1.25rem 0 0.5rem;
}

.legal-content p,
.legal-content li {
    font-size: 1rem;
    color: var(--text2);
    line-height: 1.75;
    margin-bottom: 0.875rem;
}

.legal-content ul {
    padding-left: 1.75rem;
    margin-bottom: 0.875rem;
}

.back-link {
    color: var(--text2);
    font-size: 0.9375rem;
    text-decoration: none;
    display: inline-block;
    margin-bottom: 1.75rem;
}

/* ============ GAME SCREEN ============ */
.game-screen {
    background: #000;
}

#gameCanvas {
    width: 100%;
    height: 100%;
}

#gameCanvas.fever-active {
    animation: feverPulse 0.5s infinite alternate;
}

@keyframes feverPulse {
    from { filter: brightness(1); }
    to { filter: brightness(1.1) saturate(1.2); }
}

/* HUD */
.hud {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    padding: calc(env(safe-area-inset-top, 0px) + 10px) 10px 10px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    z-index: 10;
    pointer-events: none;
    gap: 8px;
}

.hud-left, .hud-right {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.hud-left {
    flex-wrap: wrap;
    max-width: 70%;
}

.hud-pill {
    background: rgba(8, 8, 16, 0.78);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    padding: 6px 12px;
    display: flex;
    align-items: center;
    gap: 5px;
    pointer-events: auto;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    white-space: nowrap;
}

.hud-val {
    font: 700 1.5rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.04em;
    line-height: 1;
}

.hud-val.gold {
    color: var(--gold);
    text-shadow: 0 0 12px rgba(253,203,110,0.45);
}

.hud-val.cyan {
    color: var(--cyan);
    text-shadow: 0 0 12px rgba(0,206,201,0.35);
}

.hud-pill .icon {
    font-size: 1rem;
    line-height: 1;
    opacity: 0.8;
}

.hud-pill .unit {
    font-size: 0.7rem;
    color: var(--text2);
    margin-left: 1px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    align-self: flex-end;
    padding-bottom: 2px;
}

/* Combo HUD */
.combo-pill {
    background: linear-gradient(135deg, rgba(253, 203, 110, 0.2), rgba(253, 203, 110, 0.1));
    border-color: rgba(253, 203, 110, 0.4);
}

.hud-combo {
    font: 700 1.125rem 'Bebas Neue', sans-serif;
    color: var(--gold);
}

.hud-combo.hot {
    color: #ff6b6b;
    animation: comboPulse 0.3s infinite alternate;
}

.hud-combo.fire {
    color: #ff4757;
    animation: comboPulse 0.15s infinite alternate;
    text-shadow: 0 0 10px #ff4757;
}

@keyframes comboPulse {
    from { transform: scale(1); }
    to { transform: scale(1.1); }
}

/* Fever HUD */
.hud-fever {
    background: linear-gradient(135deg, #ff6b6b, #e17055);
    padding: 0.375rem 0.75rem;
    border-radius: var(--radius-sm);
    font: 700 0.875rem 'Space Grotesk', sans-serif;
    color: #fff;
    animation: feverBlink 0.5s infinite alternate;
}

@keyframes feverBlink {
    from { opacity: 1; box-shadow: 0 0 10px #ff6b6b; }
    to { opacity: 0.8; box-shadow: 0 0 20px #ff6b6b; }
}

.close-btn {
    width: 40px;
    height: 40px;
    min-width: 40px;
    min-height: 40px;
    background: rgba(8, 8, 16, 0.78);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    color: rgba(255,255,255,0.7);
    font-size: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    pointer-events: auto;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: transform 0.1s, color 0.15s;
    flex-shrink: 0;
}

.close-btn:active {
    transform: scale(0.92);
    color: #fff;
}

/* Progress Bar */
/* ============================================================
   LAYER TOWER — right edge, below ✕ button
   Dashboard / racing-indicator aesthetic:
   - SVG outline icons (stroke-based, no fill)
   - Semi-transparent ring container
   - Locked = dim outline only
   - Current = bright ring arc animates, icon glows
   - Active = full ring, solid accent, persistent glow
   ============================================================ */

.layer-tower {
    position: absolute;
    /* Sit directly below the HUD bar (which is ~50px tall) */
    top: calc(env(safe-area-inset-top, 0px) + 56px);
    right: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    z-index: 11;
    pointer-events: none;
}

/* Each node: column = circle + label */
.layer-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    opacity: 0.22;
    transition: opacity 0.35s ease, filter 0.35s ease;
}

/* The actual circle container */
.layer-node-circle {
    position: relative;
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* SVG progress ring — inside .layer-node-circle */
.layer-node-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
    overflow: visible;
}

.ring-bg {
    fill: none;
    stroke: rgba(255,255,255,0.07);
    stroke-width: 3;
}

.ring-fill {
    fill: none;
    stroke: rgba(108, 92, 231, 0.9);
    stroke-width: 3.5;
    stroke-linecap: round;
    /* No CSS transition on stroke-dasharray — iOS Safari doesn't support it.
       Progress updates instantly per vinyl collected, which feels responsive. */
}

/* The instrument icon SVG — positioned inside .layer-node-circle */
.layer-icon-svg {
    width: 28px;
    height: 28px;
    position: relative;
    z-index: 2;
    stroke: rgba(255,255,255,0.45);
    transition: stroke 0.35s ease, filter 0.35s ease;
    overflow: visible;
    flex-shrink: 0;
}

/* Black key fill for piano */
.layer-icon-svg .black-key {
    fill: rgba(255,255,255,0.45);
    stroke: none;
    transition: fill 0.35s ease;
}

/* ── CURRENT: next to unlock ── */
.layer-node.current {
    opacity: 0.85;
}

.layer-node.current .layer-icon-svg {
    stroke: rgba(180, 160, 255, 0.9);
}

.layer-node.current .black-key {
    fill: rgba(180, 160, 255, 0.9);
}

.layer-node.current .ring-fill {
    stroke: rgba(162, 155, 254, 1);
    filter: drop-shadow(0 0 4px rgba(108,92,231,0.8));
}

/* ── ACTIVE: fully unlocked ── */
.layer-node.active {
    opacity: 1;
}

.layer-node.active .layer-node-circle {
    filter: drop-shadow(0 0 6px rgba(253,203,110,0.45));
}

.layer-node.active .layer-icon-svg {
    stroke: rgba(253, 203, 110, 1);
}

.layer-node.active .black-key {
    fill: rgba(253, 203, 110, 1);
}

.layer-node.active .ring-fill {
    stroke: var(--gold, #fdcb6e);
    filter: drop-shadow(0 0 4px rgba(253,203,110,0.9));
}

/* ── JUST UNLOCKED animation ── */
@keyframes node-pop {
    0%   { transform: scale(1);    filter: drop-shadow(0 0 0   rgba(253,203,110,0)); }
    35%  { transform: scale(1.22); filter: drop-shadow(0 0 14px rgba(253,203,110,0.9)); }
    70%  { transform: scale(0.94); }
    100% { transform: scale(1);    filter: drop-shadow(0 0 6px rgba(253,203,110,0.5)); }
}

.layer-node.just-unlocked .layer-node-circle {
    animation: node-pop 0.6s cubic-bezier(.34,1.56,.64,1) forwards;
}

/* ── FEVER: all active nodes pulse ── */
.fever-mode .layer-node.active .layer-node-circle {
    filter: drop-shadow(0 0 10px rgba(253,203,110,0.8));
}

/* ── ALMOST: pulse current node when close ── */
@keyframes node-almost {
    0%,100% { opacity: 0.85; }
    50%      { opacity: 1; filter: drop-shadow(0 0 8px rgba(162,155,254,0.9)); }
}

.layer-node.current.almost .layer-node-circle {
    animation: node-almost 0.5s ease-out 2;
}

/* ── Tutorial highlight ── */
@keyframes tower-highlight {
    0%,100% { filter: none; }
    50%      { filter: drop-shadow(0 0 8px rgba(253,203,110,0.8)); }
}

.layer-tower.tutorial-highlight .layer-node.current .layer-node-circle {
    animation: tower-highlight 0.75s ease-in-out 3;
}

/* ── Node label — shows instrument name normally, countdown when current ── */
.layer-node-label {
    font: 600 0.46rem 'Space Grotesk', sans-serif;
    color: rgba(255,255,255,0.22);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
    pointer-events: none;
    transition: color 0.35s, font-size 0.25s;
    line-height: 1;
    text-align: center;
}

.layer-node.active  .layer-node-label {
    color: rgba(253,203,110,0.7);
}

.layer-node.current .layer-node-label {
    color: rgba(162,155,254,0.9);
    font: 700 0.52rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.06em;
    text-shadow: 0 0 5px rgba(108,92,231,0.6);
}

/* ── Phone portrait (≤ 480px) ── */
@media (max-width: 480px) {
    .layer-tower       { top: calc(env(safe-area-inset-top, 0px) + 50px); right: 6px; gap: 8px; }
    .layer-node-circle { width: 42px; height: 42px; }
    .layer-icon-svg    { width: 20px; height: 20px; }
    .ring-fill         { stroke-width: 2.8; }
    .ring-bg           { stroke-width: 2.2; }
    .layer-node-label  { font-size: 0.42rem; }
}

/* ── Tablet (481–900px) ── */
@media (min-width: 481px) and (max-width: 900px) {
    .layer-tower       { right: 10px; gap: 10px; }
    .layer-node-circle { width: 54px; height: 54px; }
    .layer-icon-svg    { width: 26px; height: 26px; }
    .layer-node-label  { font-size: 0.48rem; }
}

/* ── Desktop (> 900px) ── */
@media (min-width: 901px) {
    .layer-tower       { right: 14px; gap: 12px; }
    .layer-node-circle { width: 58px; height: 58px; }
    .layer-icon-svg    { width: 30px; height: 30px; }
    .layer-node-label  { font-size: 0.5rem; }
}

/* ── Landscape phone: compact vertically, hide labels ── */
@media (max-height: 450px) and (orientation: landscape) {
    .layer-tower       { gap: 4px; top: calc(env(safe-area-inset-top, 0px) + 46px); }
    .layer-node-circle { width: 34px; height: 34px; }
    .layer-icon-svg    { width: 15px; height: 15px; }
    .layer-node-label  { display: none; }
    .ring-fill         { stroke-width: 2.5; }
}

/* ── Tower hint: slim progress bar + "X more" below tower ── */
.tower-hint {
    position: absolute;
    /* Default: approximate position below tower (refined by JS on first updateHUD) */
    top: calc(env(safe-area-inset-top, 0px) + 310px);
    right: 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    z-index: 11;
    pointer-events: none;
    width: 52px; /* matches default node size */
}

.tower-hint-bar {
    width: 100%;
    height: 2px;
    background: rgba(255,255,255,0.08);
    border-radius: 1px;
    overflow: hidden;
}

.tower-hint-fill {
    height: 100%;
    width: 0%;
    background: rgba(162,155,254,0.8);
    border-radius: 1px;
    /* No transition - update directly for iOS Safari compatibility */
}

.tower-hint-text {
    font: 600 0.44rem 'Space Grotesk', sans-serif;
    color: rgba(162,155,254,0.7);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
    text-align: center;
}

/* Active (all done) */
.tower-hint.complete .tower-hint-fill { background: rgba(253,203,110,0.8); }
.tower-hint.complete .tower-hint-text { color: rgba(253,203,110,0.8); }

/* Responsive positions — widths mirror layer-node-circle sizes */
@media (max-width: 480px) {
    .tower-hint { right: 6px; width: 42px; top: calc(env(safe-area-inset-top,0px) + 248px); }
}
@media (min-width: 481px) and (max-width: 900px) {
    .tower-hint { right: 10px; width: 54px; top: calc(env(safe-area-inset-top,0px) + 340px); }
}
@media (min-width: 901px) {
    .tower-hint { right: 14px; width: 58px; top: calc(env(safe-area-inset-top,0px) + 370px); }
}
@media (max-height: 450px) and (orientation: landscape) {
    .tower-hint { display: none; }
}
.layer-dots    { display: none !important; }
.vinyl-hud     { display: none !important; }
.layer-strip   { display: none !important; }
.layer-tower-count { display: none !important; }
.layer-tower-next  { display: none !important; }

/* Game Overlays */
.overlay {
    position: absolute;
    inset: 0;
    background: rgba(10, 10, 15, 0.97);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    z-index: 50;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s;
    padding: var(--pad);
    /* iOS notched devices safe areas */
    padding-top: max(var(--pad), env(safe-area-inset-top));
    padding-bottom: max(var(--pad), env(safe-area-inset-bottom));
    padding-left: max(var(--pad), env(safe-area-inset-left));
    padding-right: max(var(--pad), env(safe-area-inset-right));
    /* iOS/Mobile scroll support */
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.overlay.show {
    opacity: 1;
    pointer-events: auto;
}

.overlay-box {
    max-width: 320px;
    width: 100%;
    padding: 1.5rem;
    /* Ensure content is centered but can scroll */
    margin: auto;
    flex-shrink: 0;
    /* Add bottom margin for safe scroll area */
    margin-bottom: 2rem;
}

.overlay h2 {
    font: 700 2rem 'Bebas Neue', sans-serif;
    margin-bottom: 0.375rem;
    letter-spacing: 0.02em;
}

.overlay p {
    color: var(--text2);
    margin-bottom: 1rem;
    font-size: 0.9375rem;
    line-height: 1.6;
}

.overlay .btns {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Tip Box */
.tip-box {
    background: rgba(253, 203, 110, 0.1);
    border: 1px solid rgba(253, 203, 110, 0.2);
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.75rem;
    font-size: 0.75rem;
    color: var(--gold);
    margin: 1rem 0;
}

/* Play Mode Selection */
.play-mode-btn {
    background: var(--surface2);
    border: 2px solid var(--text3);
    border-radius: var(--radius-sm);
    color: var(--text2);
    padding: 0.625rem 1rem;
    font: 600 0.8125rem 'Space Grotesk', sans-serif;
    cursor: pointer;
    transition: all 0.2s ease;
    min-height: 44px;
}

.play-mode-btn:hover {
    border-color: var(--primary);
    color: var(--text);
}

.play-mode-btn.active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
    box-shadow: 0 4px 15px rgba(108, 92, 231, 0.3);
}

/* Loading */
.loading-spinner {
    width: 48px;
    height: 48px;
    border: 3px solid var(--surface2);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 1s linear infinite;
    -webkit-animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}
@-webkit-keyframes spin {
    to { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}

.loading-progress {
    width: 100%;
    max-width: 200px;
    margin: 1rem auto;
}

.loading-progress-track {
    height: 6px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    overflow: hidden;
}

.loading-progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--primary), var(--gold));
    border-radius: 3px;
    transition: width 0.2s;
    width: 0%;
}

.loading-progress-text {
    font-size: 0.75rem;
    color: var(--text2);
    margin-top: 0.5rem;
    text-align: center;
}

/* Controls Grid */
.ctrl-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    margin: 1.25rem 0;
}

.ctrl-item {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 0.75rem 0.5rem;
    text-align: center;
}

.ctrl-icon {
    font-size: 1.5rem;
    margin-bottom: 0.25rem;
}

.ctrl-label {
    font-size: 0.75rem;
    color: var(--text2);
    font-weight: 500;
}

/* Unlock Popup */
.unlock-popup {
    position: fixed;
    top: calc(env(safe-area-inset-top) + 70px);
    left: 50%;
    transform: translateX(-50%) translateY(-100px);
    max-width: min(420px, calc(100vw - 2.5rem));
    background: linear-gradient(135deg, rgba(253, 203, 110, 0.2), rgba(253, 203, 110, 0.08));
    border: 1px solid rgba(253, 203, 110, 0.5);
    border-radius: 20px;
    padding: 0.625rem 1.125rem;
    z-index: 85;
    transition: transform 0.35s ease-out, opacity 0.35s ease-out;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    backdrop-filter: blur(12px);
    opacity: 0;
    pointer-events: none;
    text-align: center;
}

.unlock-popup.show {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
    pointer-events: auto;
}

.unlock-popup-main {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.unlock-popup .icon {
    font-size: 1.125rem;
}

.unlock-popup .text {
    font: 600 0.875rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    white-space: nowrap;
}

/* Admin-entered per-layer story text (story_layer1/2/3) — was previously
   generated by the JS but had no DOM element or styling to render into,
   so it silently never appeared on mobile or desktop. */
.unlock-story-line {
    font: 400 0.8rem/1.4 'Space Grotesk', sans-serif;
    color: rgba(255, 255, 255, 0.85);
    max-width: 340px;
}

.unlock-popup.enhanced {
    padding: 0.75rem 1.25rem;
    border-radius: 22px;
}

.unlock-popup.enhanced .unlock-popup-main .text {
    white-space: normal;
}

/* Score Popup */
.score-popup {
    position: fixed;
    pointer-events: none;
    font: 700 1.5rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
    z-index: 80;
    animation: float-up 0.8s ease-out forwards;
}

@keyframes float-up {
    0% { opacity: 1; transform: translateY(0) scale(1); }
    100% { opacity: 0; transform: translateY(-80px) scale(1.3); }
}

/* Peripheral variant: anchored to the HUD vinyl counter (top-left) so it
   never overlaps the runner lane / obstacles in the center of the screen. */
.score-popup--peripheral {
    font-size: 1.1rem;
    animation: float-up-peripheral 0.8s ease-out forwards;
}

@keyframes float-up-peripheral {
    0%   { opacity: 1; transform: translate(-50%, 0) scale(1); }
    100% { opacity: 0; transform: translate(-50%, -34px) scale(1.15); }
}

/* ============ ACHIEVEMENT POPUP ============ */
.achievement-popup {
    position: fixed;
    top: calc(env(safe-area-inset-top) + 20px);
    left: 50%;
    transform: translateX(-50%) translateY(-100px);
    background: linear-gradient(135deg, var(--surface), #1a1a28);
    border: 2px solid var(--gold);
    border-radius: var(--radius);
    padding: 0.75rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    z-index: 400;
    opacity: 0;
    transition: transform 0.4s ease-out, opacity 0.4s ease-out;
    box-shadow: 0 8px 32px rgba(253, 203, 110, 0.3);
}

.achievement-popup.show {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
}

.achievement-icon {
    font-size: 2rem;
}

.achievement-info {
    text-align: left;
}

.achievement-title {
    font: 700 1rem 'Space Grotesk', sans-serif;
    color: var(--gold);
}

.achievement-desc {
    font-size: 0.75rem;
    color: var(--text2);
}

/* Ad Modal */
.ad-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.98);
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: var(--pad);
}

.ad-modal.show {
    display: flex;
}

.ad-modal-box {
    max-width: 360px;
    width: 100%;
    text-align: center;
    padding: 1rem;
}

.ad-modal h2 {
    font: 700 1.75rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    margin-bottom: 0.5rem;
}

.ad-modal p {
    color: var(--text2);
    font-size: 0.9375rem;
    margin-bottom: 1rem;
    line-height: 1.6;
}

.ad-container {
    width: 100%;
    min-height: 250px;
    background: var(--surface);
    border-radius: var(--radius);
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.ad-timer {
    font: 700 2rem 'Bebas Neue', sans-serif;
    color: #fff;
    margin-bottom: 0.5rem;
}

.ad-skip {
    opacity: 0.6;
    font-size: 0.8125rem;
    color: var(--text2);
}

/* Reward Video Modal — 2026 "prize reveal" card, not text floating on a
   black backdrop. Backdrop dims/blurs the app behind it; the actual
   content lives inside a proper elevated, animated card (.reward-card),
   matching the visual language already used for the daily-bonus popup
   elsewhere in this file (gradient surface, gold border, bounce-in). */
.reward-modal {
    position: fixed;
    inset: 0;
    background: rgba(8, 6, 14, 0.88);
    backdrop-filter: blur(6px);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 200;
    padding: var(--pad);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.reward-modal.show {
    display: flex;
}

.reward-card {
    position: relative;
    width: 100%;
    max-width: 420px;
    margin: auto;
    background: linear-gradient(160deg, #1c1a2b 0%, #14121e 100%);
    border: 1px solid rgba(253, 203, 110, 0.28);
    border-radius: 24px;
    padding: 1.75rem 1.5rem 1.5rem;
    box-shadow:
        0 20px 60px rgba(0, 0, 0, 0.5),
        0 0 0 1px rgba(255, 255, 255, 0.03) inset;
    animation: rewardCardIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes rewardCardIn {
    0%   { transform: scale(0.9) translateY(12px); opacity: 0; }
    100% { transform: scale(1) translateY(0); opacity: 1; }
}

.reward-modal video {
    max-width: 100%;
    max-height: 60vh;
    border-radius: var(--radius);
    margin-top: 0.5rem;
}

.reward-modal-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    width: 36px;
    height: 36px;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    border: none;
    color: var(--text2);
    font-size: 1.05rem;
    cursor: pointer;
    z-index: 1;
    transition: background 0.15s, color 0.15s;
}
.reward-modal-close:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
}

.reward-modal-title {
    font: 700 1.4rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.02em;
    color: var(--gold);
    margin: 0.25rem 0 0.75rem;
    text-align: center;
}

.reward-modal-message {
    color: var(--text2);
    font-size: 1rem;
    text-align: center;
    max-width: none;
}

/* "Fully unlocked" pill — sits above the title, same visual family as the
   card-badge--unlocked pill used on song cards, so the reward reveal reads
   as a continuation of that state rather than a different UI language. */
.reward-unlocked-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin: 0 auto 0.625rem;
    padding: 0.3rem 0.75rem;
    background: linear-gradient(135deg, #1fcc5e 0%, #15a04a 100%);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 999px;
    width: fit-content;
}
.reward-unlocked-wrap {
    display: flex;
    justify-content: center;
}

/* Reward / Story tab switcher — keeps the popup from dumping a big wall of
   text and a row of buttons on top of each other. Reward (the actionable
   part) is front and center by default; the story is one tap away, same
   pattern mobile games use for a post-completion "loot" screen. */
.reward-tabs {
    display: flex;
    gap: 0.4rem;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 12px;
    padding: 0.25rem;
    margin: 0 0 1rem;
}
.reward-tab {
    flex: 1;
    border: none;
    background: transparent;
    color: var(--text2);
    font: 700 0.78rem 'Space Grotesk', sans-serif;
    letter-spacing: 0.02em;
    padding: 0.5rem 0.5rem;
    border-radius: 9px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.reward-tab.active {
    background: var(--primary);
    color: #fff;
}
.reward-pane {
    text-align: left;
}

/* Full release story — the admin-written "story_full" text, shown here so
   a fan who already completed a song can re-read it any time without
   having to replay the whole thing. */
.reward-story {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(253, 203, 110, 0.2);
    border-radius: var(--radius);
    padding: 1rem 1.125rem;
    margin-bottom: 1rem;
    text-align: left;
    color: var(--text);
    font-size: 0.9rem;
    line-height: 1.65;
    white-space: pre-line;
}

/* Per-layer story recap (story_layer1/2/3) — the short lines shown briefly
   during the run itself, collected here for an easy re-read. */
.reward-journey {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}
.reward-journey-item {
    display: flex;
    gap: 0.625rem;
    align-items: flex-start;
    font-size: 0.85rem;
    color: var(--text2);
    line-height: 1.5;
}
.reward-journey-icon {
    flex-shrink: 0;
    font-size: 1rem;
    line-height: 1.5;
}

/* ============ VICTORY SCREEN ============ */
.victory {
    background: linear-gradient(180deg, #151520, var(--bg));
    justify-content: center;
    align-items: center;
    padding: var(--pad);
    text-align: center;
}

.victory-box {
    max-width: 360px;
    width: 100%;
}

.trophy {
    font-size: 4rem;
    margin-bottom: 0.5rem;
}

.victory h1 {
    font: 700 2.5rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.02em;
}

.stats {
    display: flex;
    justify-content: center;
    gap: 2.5rem;
    margin: 1.25rem 0;
}

.stat-val {
    font: 700 2rem 'Bebas Neue', sans-serif;
    color: var(--gold);
}

.stat-label {
    font-size: 0.75rem;
    color: var(--text3);
    margin-top: 0.125rem;
}

.victory .msg {
    color: var(--text2);
    margin-bottom: 1.25rem;
    font-size: 0.9375rem;
    line-height: 1.6;
}

.victory .btns {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ============ FRONTEND TOAST ============ */
.frontend-toast {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom) + 90px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--surface);
    border: 1px solid var(--gold);
    padding: 0.625rem 1.25rem;
    border-radius: var(--radius);
    font-size: 0.875rem;
    z-index: 200;
    animation: fadeInOut 2.5s ease-out forwards;
}

@keyframes fadeInOut {
    0% { opacity: 0; transform: translateX(-50%) translateY(20px); }
    10% { opacity: 1; transform: translateX(-50%) translateY(0); }
    80% { opacity: 1; transform: translateX(-50%) translateY(0); }
    100% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
}

/* ============ ADMIN PANEL ============ */
.admin {
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: var(--pad);
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 100px);
    height: 100%;
}

.admin-wrap {
    max-width: 720px;
    margin: 0 auto;
}

.admin-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
    gap: 0.875rem;
}

.admin-header h1 {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--primary);
}

.admin-tabs {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
}

.admin-tab {
    padding: 0.625rem 1rem;
    background: var(--surface);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: 500;
    transition: background 0.2s;
}

.admin-tab.active {
    background: var(--primary);
}

.admin-panel {
    display: none;
}

.admin-panel.active {
    display: block;
}

.admin-section {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 1.25rem;
    margin-bottom: 1rem;
}

.admin-section h3 {
    font-size: 1rem;
    color: var(--gold);
    margin-bottom: 0.75rem;
}

.form-group {
    margin-bottom: 0.75rem;
}

.form-group label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text2);
    margin-bottom: 0.375rem;
}

.form-group small {
    font-size: 0.75rem;
    color: var(--text3);
    display: block;
    margin-top: 0.25rem;
}

input,
select,
textarea {
    width: 100%;
    padding: 0.75rem 0.875rem;
    background: var(--bg);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: var(--radius-sm);
    color: #fff;
    font-size: 0.9375rem;
    font-family: inherit;
    transition: border-color 0.2s;
    /* Mobile optimizations */
    -webkit-appearance: none;
    appearance: none;
}

/* Checkbox inputs - restore native appearance */
input[type="checkbox"] {
    width: auto;
    height: auto;
    padding: 0;
    margin-right: 0.5rem;
    -webkit-appearance: checkbox;
    appearance: checkbox;
    vertical-align: middle;
    cursor: pointer;
    accent-color: var(--primary);
}

/* Checkbox label inline styling */
.form-group label:has(input[type="checkbox"]) {
    display: flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
}

/* Fallback for browsers without :has() support */
.form-group label > input[type="checkbox"]:first-child {
    margin-right: 0.5rem;
}

/* PIN input masking for type="tel" */
input[type="tel"][style*="-webkit-text-security"] {
    -webkit-text-security: disc;
}

/* Prevent iOS zoom on input focus */
@media screen and (max-width: 768px) {
    input, select, textarea {
        font-size: 16px !important;
    }
}

/* PWA safe area support */
@supports (padding-top: env(safe-area-inset-top)) {
    body {
        padding-top: env(safe-area-inset-top);
        padding-bottom: env(safe-area-inset-bottom);
        padding-left: env(safe-area-inset-left);
        padding-right: env(safe-area-inset-right);
    }
}

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--primary);
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.625rem;
}

.form-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}

.form-section {
    margin: 1.25rem 0;
    padding-top: 1rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.form-section h4 {
    font-size: 0.875rem;
    color: var(--primary);
    margin-bottom: 0.625rem;
}

.info-box {
    background: rgba(108, 92, 231, 0.1);
    border: 1px solid var(--primary);
    border-radius: var(--radius-sm);
    padding: 0.875rem;
    margin-bottom: 0.875rem;
    font-size: 0.875rem;
    color: var(--text2);
    line-height: 1.7;
}

.info-box strong {
    color: var(--gold);
}

.info-box code {
    background: rgba(0, 0, 0, 0.3);
    padding: 0.125rem 0.5rem;
    border-radius: 4px;
    font-size: 0.8125rem;
}

.admin-cards {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* Stats Grid */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.625rem;
}

.stat-card {
    background: var(--surface);
    border-radius: var(--radius-sm);
    padding: 0.875rem;
    text-align: center;
}

.stat-card.small {
    padding: 0.625rem;
}

.stat-value {
    font: 700 1.75rem 'Bebas Neue', sans-serif;
    color: var(--primary);
}

.stat-card.small .stat-value {
    font-size: 1.375rem;
}

.song-stat {
    display: flex;
    justify-content: space-between;
    padding: 0.5rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    font-size: 0.875rem;
}

.song-stat:last-child {
    border: none;
}

/* Admin Cards */
.admin-card {
    background: var(--surface);
    border-radius: var(--radius);
    padding: 1.25rem;
}

.admin-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 0.75rem;
    gap: 0.625rem;
}

.admin-card-title h4 {
    font-size: 1rem;
    font-weight: 700;
}

.admin-card-title p {
    font-size: 0.8125rem;
    color: var(--text2);
    margin-top: 0.25rem;
}

.status-badge {
    padding: 0.25rem 0.625rem;
    border-radius: 6px;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
}

.status-badge.live {
    background: rgba(0, 184, 148, 0.15);
    color: var(--success);
}

.status-badge.draft {
    background: rgba(107, 114, 128, 0.2);
    color: var(--text3);
}

.status-badge.upcoming {
    background: rgba(108, 92, 231, 0.15);
    color: var(--primary);
}

.status-badge.expired {
    background: rgba(255, 107, 107, 0.15);
    color: var(--danger);
}

/* Upload Grid */
.upload-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.upload-item {
    background: var(--bg);
    border-radius: 6px;
    padding: 0.5rem;
    text-align: center;
}

.upload-item .name {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--text2);
}

.upload-item .indicator {
    font-size: 0.6875rem;
    margin: 0.125rem 0;
}

.upload-item .indicator.yes {
    color: var(--success);
}

.upload-item .indicator.no {
    color: var(--danger);
}

.upload-item input {
    display: none;
}

.upload-item label {
    display: inline-block;
    margin-top: 0.125rem;
    padding: 0.25rem 0.5rem;
    background: var(--primary);
    border-radius: 4px;
    font-size: 0.6875rem;
    cursor: pointer;
}

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

/* Modal */
.modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.92);
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--pad);
    z-index: 200;
    overflow-y: auto;
}

.modal.show {
    display: flex;
}

.modal-box {
    background: var(--surface);
    border-radius: 18px;
    padding: 1.5rem;
    max-width: 480px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
}

.modal h2 {
    font-size: 1.25rem;
    margin-bottom: 1.25rem;
    color: var(--gold);
}

/* Toast */
.toast {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom) + 1.75rem);
    left: 50%;
    transform: translateX(-50%) translateY(60px);
    padding: 0.75rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--success);
    border-radius: var(--radius);
    font-size: 0.9375rem;
    z-index: 300;
    transition: transform 0.25s ease-out;
}

.toast.show {
    transform: translateX(-50%) translateY(0);
}

.toast.error {
    border-color: var(--danger);
}

/* ============ RESPONSIVE ============ */
@media (min-width: 768px) {
    :root {
        --pad: 24px;
    }
    
    html {
        font-size: 17px;
    }
    
    .hero {
        padding: 3rem 2rem;
    }
    
    .logo {
        width: 88px;
        height: 88px;
        font-size: 2.75rem;
    }
    
    .brand {
        font-size: 2rem;
    }
    
    .songs-list,
    .lb-list,
    .challenges-list {
        max-width: 540px;
    }
    
    .hud-val {
        font-size: 1.5rem;
    }
    
    .progress-wrap {
        max-width: 480px;
        left: 50%;
        right: auto;
        transform: translateX(-50%);
    }
    
    .overlay-box {
        max-width: 380px;
        padding: 2rem;
    }
    
    .victory-box {
        max-width: 420px;
    }
    
    .admin-wrap {
        max-width: 800px;
    }
}
/**
 * DJ SEIP BACKSTAGE v5.4 - Additional Styles
 * New features: Tutorial, Interstitial, Referral, Ad Blocker message
 * 
 * APPEND THIS TO styles.css
 */

/* ============ TUTORIAL MODAL ============ */
.tutorial-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.95);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 400;
    padding: var(--pad);
}

.tutorial-modal.show {
    display: flex;
    animation: fadeIn 0.3s ease;
}

.tutorial-box {
    background: linear-gradient(135deg, var(--surface), #1a1a28);
    border: 2px solid var(--primary);
    border-radius: 20px;
    padding: 2rem 1.5rem;
    width: 100%;
    max-width: 360px;
    text-align: center;
    max-height: 90vh;
    overflow-y: auto;
}

.tutorial-box h2 {
    font: 700 1.75rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    margin-bottom: 1rem;
}

.tutorial-step {
    background: var(--surface2);
    border-radius: var(--radius);
    padding: 1rem;
    margin-bottom: 0.75rem;
    text-align: left;
}

.tutorial-step-number {
    display: inline-block;
    width: 28px;
    height: 28px;
    background: var(--primary);
    border-radius: 50%;
    text-align: center;
    line-height: 28px;
    font-weight: 700;
    margin-right: 0.5rem;
}

.tutorial-step-title {
    font-weight: 700;
    color: var(--text);
    display: inline;
}

.tutorial-step-desc {
    font-size: 0.875rem;
    color: var(--text2);
    margin-top: 0.5rem;
    margin-left: 36px;
}

.tutorial-controls {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    margin: 1.25rem 0;
}

.tutorial-control {
    background: var(--surface2);
    border-radius: var(--radius);
    padding: 0.75rem;
    text-align: center;
}

.tutorial-control-icon {
    font-size: 2rem;
    margin-bottom: 0.25rem;
}

.tutorial-control-label {
    font-size: 0.75rem;
    color: var(--text2);
}

.tutorial-btns {
    display: flex;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.tutorial-btns .btn {
    flex: 1;
}

/* ============ INTERSTITIAL AD MODAL ============ */
.interstitial-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.98);
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 500;
    padding: var(--pad);
}

.interstitial-modal.show {
    display: flex;
    animation: fadeIn 0.3s ease;
}

.interstitial-box {
    text-align: center;
    max-width: 360px;
}

.interstitial-box h3 {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--text2);
    margin-bottom: 0.75rem;
}

.interstitial-ad-container {
    width: 300px;
    min-height: 250px;
    background: var(--surface);
    border-radius: var(--radius);
    margin: 0 auto 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.interstitial-timer {
    font: 700 2.5rem 'Bebas Neue', sans-serif;
    color: var(--gold);
    margin-bottom: 0.5rem;
}

.interstitial-close-btn {
    display: none;
}

.interstitial-close-btn.show {
    display: inline-flex;
}

/* ============ REFERRAL SECTION ============ */
.referral-section {
    background: linear-gradient(135deg, var(--surface), rgba(108, 92, 231, 0.1));
    border: 1px solid rgba(108, 92, 231, 0.3);
    border-radius: var(--radius);
    padding: 1.25rem;
    margin: 1.5rem auto;
    max-width: 360px;
    text-align: center;
}

.referral-title {
    font: 700 1.125rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    margin-bottom: 0.5rem;
}

.referral-desc {
    font-size: 0.875rem;
    color: var(--text2);
    margin-bottom: 1rem;
}

.referral-code-box {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.referral-code-input {
    flex: 1;
    background: var(--bg);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    color: var(--gold);
    font: 700 1rem 'Space Grotesk', sans-serif;
    text-align: center;
    letter-spacing: 0.1em;
}

.referral-copy-btn {
    padding: 0.75rem 1rem;
}

.referral-stats {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 0.75rem;
    font-size: 0.75rem;
    color: var(--text3);
}

.referral-stat-value {
    font-weight: 700;
    color: var(--primary);
}

/* ============ AD BLOCKER MESSAGE ============ */
.ad-blocker-message {
    background: rgba(231, 76, 60, 0.1);
    border: 1px solid rgba(231, 76, 60, 0.3);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    margin: 0.75rem 0;
    font-size: 0.8125rem;
    color: #e74c3c;
    display: none;
}

.ad-blocker-message.show {
    display: block;
}

/* ============ IMPROVED PLAYER BAR ============ */
.player-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1rem;
    padding: 0.625rem 1.25rem;
    background: var(--surface);
    border-radius: 24px;
    font-size: 0.875rem;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
}

.player-avatar {
    width: 32px;
    height: 32px;
    background: linear-gradient(135deg, var(--primary), #fd79a8);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.875rem;
}

.player-info {
    text-align: left;
}

.player-name {
    font-weight: 600;
    font-size: 0.9375rem;
}

.player-vinyls {
    font-size: 0.75rem;
    color: var(--gold);
}

/* ============ LEADERBOARD IMPROVEMENTS ============ */
.lb-player-highlight {
    background: rgba(108, 92, 231, 0.15) !important;
    border: 1px solid var(--primary) !important;
}

.lb-rank-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.lb-rank-badge.top-3::before {
    content: '👑';
    font-size: 0.75rem;
}

/* ============ ONBOARDING TOOLTIP ============ */
.onboarding-tooltip {
    position: absolute;
    background: var(--gold);
    color: #000;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-sm);
    font-size: 0.8125rem;
    font-weight: 600;
    z-index: 100;
    animation: bounce 1s infinite;
    white-space: nowrap;
}

.onboarding-tooltip::after {
    content: '';
    position: absolute;
    bottom: -6px;
    left: 50%;
    transform: translateX(-50%);
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid var(--gold);
}

/* ============ PWA INSTALL PROMPT ============ */
.pwa-install-prompt {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom) + 1rem);
    left: var(--pad);
    right: var(--pad);
    background: var(--surface);
    border: 1px solid var(--primary);
    border-radius: var(--radius);
    padding: 1rem;
    display: none;
    align-items: center;
    gap: 1rem;
    z-index: 200;
    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.3);
}

.pwa-install-prompt.show {
    display: flex;
    animation: slideUp 0.3s ease;
}

@keyframes slideUp {
    from { transform: translateY(100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

.pwa-install-icon {
    width: 48px;
    height: 48px;
    background: linear-gradient(135deg, var(--primary), #fd79a8);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    flex-shrink: 0;
}

.pwa-install-info {
    flex: 1;
}

.pwa-install-title {
    font-weight: 700;
    font-size: 0.9375rem;
}

.pwa-install-desc {
    font-size: 0.75rem;
    color: var(--text2);
}

.pwa-install-close {
    width: 32px;
    height: 32px;
    background: transparent;
    border: none;
    color: var(--text2);
    font-size: 1.25rem;
    cursor: pointer;
}

/* ============ SESSION TIMEOUT WARNING ============ */
.session-warning {
    position: fixed;
    top: calc(env(safe-area-inset-top) + var(--pad));
    left: var(--pad);
    right: var(--pad);
    background: linear-gradient(135deg, #e74c3c, #c0392b);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    display: none;
    align-items: center;
    gap: 0.75rem;
    z-index: 300;
}

.session-warning.show {
    display: flex;
    animation: slideDown 0.3s ease;
}

@keyframes slideDown {
    from { transform: translateY(-100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

/* ============ IMPROVED LOADING STATES ============ */
.skeleton {
    background: linear-gradient(
        90deg,
        var(--surface) 0%,
        var(--surface2) 50%,
        var(--surface) 100%
    );
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s infinite;
    border-radius: var(--radius-sm);
}

@keyframes skeleton-loading {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-song-card {
    height: 80px;
    margin-bottom: 0.75rem;
}

.skeleton-text {
    height: 1rem;
    margin-bottom: 0.5rem;
}

.skeleton-text.short {
    width: 60%;
}

/* ============ BETTER ERROR STATES ============ */
.error-state {
    text-align: center;
    padding: 3rem var(--pad);
}

.error-icon {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.6;
}

.error-title {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: var(--text);
    margin-bottom: 0.5rem;
}

.error-desc {
    font-size: 0.875rem;
    color: var(--text2);
    margin-bottom: 1rem;
}

/* ============ OFFLINE INDICATOR ============ */
.offline-indicator {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background: #e74c3c;
    color: #fff;
    text-align: center;
    padding: 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    z-index: 9999;
    display: none;
}

.offline-indicator.show {
    display: block;
}

/* ============ CONFETTI ANIMATION ============ */
.confetti {
    position: fixed;
    pointer-events: none;
    z-index: 1000;
}

.confetti-piece {
    position: absolute;
    width: 10px;
    height: 10px;
    animation: confetti-fall 3s ease-out forwards;
}

@keyframes confetti-fall {
    0% {
        opacity: 1;
        transform: translateY(0) rotate(0deg);
    }
    100% {
        opacity: 0;
        transform: translateY(100vh) rotate(720deg);
    }
}

/* ============ NOTIFICATION BADGE ============ */
.notification-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 18px;
    height: 18px;
    background: #e74c3c;
    border-radius: 9px;
    font-size: 0.625rem;
    font-weight: 700;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
}

.notification-badge.pulse {
    animation: badge-pulse 2s infinite;
}

@keyframes badge-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.2); }
}

/* ============ BETTER TOUCH FEEDBACK ============ */
@media (hover: none) and (pointer: coarse) {
    .btn:active,
    .song-card:active,
    .tab:active {
        transform: scale(0.96);
        opacity: 0.9;
    }
    
    .hud-pill:active {
        transform: scale(0.95);
    }
}

/* ============ REDUCED MOTION ============ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============ HIGH CONTRAST MODE ============ */
@media (prefers-contrast: high) {
    :root {
        --surface: #000;
        --surface2: #1a1a1a;
        --text: #fff;
        --text2: #ccc;
    }
    
    .btn {
        border: 2px solid currentColor;
    }
    
    .song-card,
    .challenge-card {
        border-width: 2px;
    }
}

/* ============ PRINT STYLES ============ */
@media print {
    .hud,
    .cookie-banner,
    .toast,
    .modal,
    .overlay,
    .ad-banner {
        display: none !important;
    }
}

/* ============ iOS MOBILE FIXES ============ */
@supports (-webkit-touch-callout: none) {
    /* iOS specific - fallback for older iOS */
    html, body {
        height: -webkit-fill-available;
        max-height: -webkit-fill-available;
    }
    
    .screen {
        height: -webkit-fill-available;
        max-height: -webkit-fill-available;
    }
    
    .platform {
        height: -webkit-fill-available;
        max-height: -webkit-fill-available;
    }
}

/* Prevent any overflow on mobile */
@media (max-width: 767px) {
    html, body {
        position: fixed;
        overflow: hidden;
        width: 100%;
        height: 100%;
        height: 100dvh;
    }
    
    .screen {
        position: fixed;
        inset: 0;
        overflow: hidden;
        height: 100%;
        height: 100dvh;
    }
    
    /* Admin page needs scrolling - override .screen overflow:hidden */
    .screen.admin {
        overflow-y: auto !important;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
    
    /* Legal pages need scrolling - override .screen overflow:hidden */
    .screen.legal-page {
        overflow-y: auto !important;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
    
    .platform {
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }
    
    .admin-tabs {
        flex-wrap: wrap;
        gap: 0.375rem;
    }
    
    .admin-tab {
        padding: 0.5rem 0.75rem;
        font-size: 0.75rem;
    }
    
    .hero {
        padding: 1rem var(--pad);
    }
    
    .logo {
        width: 56px;
        height: 56px;
        font-size: 1.75rem;
        margin-bottom: 0.75rem;
    }
    
    .brand {
        font-size: 1.5rem;
    }
    
    .tagline {
        font-size: 0.875rem;
        margin-top: 0.5rem;
    }
    
    .lb-list {
        max-height: 50dvh;
    }
    
    .songs-list {
        padding-bottom: 120px;
    }
    
    .challenges-list {
        padding-bottom: 120px;
    }
    
    .badges-grid {
        padding-bottom: 120px;
    }
    
    .share-bar {
        margin: 1rem auto;
    }
    
    .footer {
        margin-top: 1rem;
        padding: 1rem var(--pad);
        padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 1rem);
    }
    
    .ad-banner {
        margin: 1rem auto;
        min-height: 40px;
    }
}/**
 * DJ SEIP BACKSTAGE v5.6 - Additional Styles
 * Replay system and Artwork challenge styles
 */

/* ============ REPLAY MODAL ============ */
.replay-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.95);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
}

.replay-modal.show {
    opacity: 1;
    visibility: visible;
}

.replay-modal-box {
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
    border-radius: 16px;
    padding: 1.5rem;
    width: 90%;
    max-width: 400px;
    max-height: 90vh;
    overflow-y: auto;
    border: 1px solid rgba(108, 92, 231, 0.3);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.replay-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.replay-modal-title {
    font-size: 1.25rem;
    font-weight: 700;
    color: #fff;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.replay-close-btn {
    background: rgba(255, 255, 255, 0.1);
    border: none;
    color: #fff;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.replay-close-btn:hover {
    background: rgba(255, 255, 255, 0.2);
}

.replay-video-container {
    background: #000;
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 1rem;
    aspect-ratio: 9/16;
    max-height: 50vh;
}

.replay-video-container video {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.replay-stats {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    padding: 0.75rem;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 8px;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: var(--gold);
}

.replay-share-bonus {
    background: linear-gradient(135deg, rgba(253, 203, 110, 0.2), rgba(253, 203, 110, 0.1));
    border: 1px solid rgba(253, 203, 110, 0.4);
    border-radius: 8px;
    padding: 0.75rem;
    text-align: center;
    margin-bottom: 1rem;
}

.share-bonus-text {
    font-size: 0.875rem;
    color: var(--text);
}

.share-bonus-text strong {
    color: var(--gold);
}

.replay-actions {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.replay-actions.secondary {
    margin-bottom: 0;
}

.btn-tiktok {
    flex: 1;
    background: linear-gradient(135deg, #25F4EE 0%, #FE2C55 50%, #000 100%);
    color: #fff;
    font-weight: 700;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    font-size: 0.875rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    transition: transform 0.2s, box-shadow 0.2s;
}

.btn-instagram {
    flex: 1;
    background: linear-gradient(135deg, #833AB4 0%, #FD1D1D 50%, #F77737 100%);
    color: #fff;
    font-weight: 700;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    font-size: 0.875rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    transition: transform 0.2s, box-shadow 0.2s;
}

.btn-twitter {
    flex: 1;
    background: #000;
    color: #fff;
    font-weight: 700;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: 1px solid #333;
    cursor: pointer;
    font-size: 0.875rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    transition: transform 0.2s, box-shadow 0.2s;
}

.btn-tiktok:hover,
.btn-instagram:hover,
.btn-twitter:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}

.btn-tiktok:active,
.btn-instagram:active,
.btn-twitter:active {
    transform: translateY(0);
}

/* ============ TIKTOK INSTRUCTIONS MODAL ============ */
.tiktok-instructions-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.95);
    z-index: 1150;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
}

.tiktok-instructions-modal.show {
    opacity: 1;
    visibility: visible;
}

.tiktok-instructions-box {
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
    border-radius: 16px;
    padding: 1.5rem;
    width: 90%;
    max-width: 400px;
    border: 1px solid rgba(254, 44, 85, 0.3);
}

.tiktok-instructions-header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.tiktok-logo {
    font-size: 3rem;
    margin-bottom: 0.5rem;
}

.tiktok-instructions-steps {
    margin-bottom: 1.5rem;
}

.tiktok-step {
    display: flex;
    gap: 1rem;
    margin-bottom: 1rem;
    align-items: flex-start;
}

.tiktok-step-number {
    background: linear-gradient(135deg, #FE2C55, #25F4EE);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.875rem;
    flex-shrink: 0;
}

.tiktok-step-text {
    color: var(--text2);
    font-size: 0.9rem;
    line-height: 1.4;
}

.tiktok-caption-container {
    margin-bottom: 1rem;
}

.tiktok-caption-container label {
    display: block;
    font-size: 0.8rem;
    color: var(--text2);
    margin-bottom: 0.5rem;
}

.tiktok-caption-container textarea {
    width: 100%;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    padding: 0.75rem;
    color: #fff;
    font-size: 0.85rem;
    resize: none;
    min-height: 100px;
}

.tiktok-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ============ ARTWORK CHALLENGE STYLES ============ */
.artwork-progress-container {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + 60px);
    right: 10px;
    left: auto;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid rgba(253, 203, 110, 0.4);
    border-radius: 12px;
    padding: 0.75rem;
    z-index: 100;
    backdrop-filter: blur(8px);
    transition: all 0.3s ease;
    max-width: 120px;
}

/* Compact mode for mobile - just shows icon + count */
.artwork-progress-container.compact {
    padding: 0.4rem 0.6rem;
    border-radius: 20px;
    cursor: pointer;
}

.artwork-progress-container.compact .artwork-progress-title,
.artwork-progress-container.compact .artwork-progress-grid {
    display: none;
}

.artwork-progress-container.compact .artwork-progress-count {
    font-size: 0.75rem;
    margin: 0;
}

/* Mini indicator that shows on mobile */
.artwork-mini-indicator {
    display: none;
    align-items: center;
    gap: 0.35rem;
}

.artwork-mini-indicator .mini-icon {
    font-size: 1rem;
}

.artwork-mini-indicator .mini-dots {
    display: flex;
    gap: 3px;
}

.artwork-mini-indicator .mini-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.3);
}

.artwork-mini-indicator .mini-dot.collected {
    background: var(--gold);
    border-color: var(--gold);
}

.artwork-progress-container.compact .artwork-mini-indicator {
    display: flex;
}

/* Expanded state toggle */
.artwork-expand-btn {
    display: none;
    position: absolute;
    top: -8px;
    right: -8px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--surface2);
    border: 1px solid var(--gold);
    color: var(--gold);
    font-size: 0.65rem;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}

.artwork-progress-title {
    font-size: 0.7rem;
    color: var(--gold);
    text-align: center;
    margin-bottom: 0.5rem;
    font-weight: 600;
}

.artwork-progress-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 4px;
    margin-bottom: 0.5rem;
}

.artwork-piece-slot {
    width: 36px;
    height: 36px;
    background: rgba(255, 255, 255, 0.05);
    border: 2px dashed rgba(255, 255, 255, 0.2);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}

.artwork-piece-slot.collected {
    border: 2px solid var(--gold);
    background: rgba(253, 203, 110, 0.1);
}

.artwork-piece-slot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 4px;
}

.artwork-piece-slot .piece-number {
    color: rgba(255, 255, 255, 0.3);
    font-weight: 700;
    font-size: 0.875rem;
}

.artwork-progress-count {
    font-size: 0.65rem;
    color: var(--text2);
    text-align: center;
}

/* ============ ARTWORK PIECE POPUP ============ */
.artwork-piece-popup {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.5);
    background: linear-gradient(135deg, rgba(253, 203, 110, 0.95), rgba(230, 126, 34, 0.95));
    border-radius: 16px;
    padding: 1.5rem;
    z-index: 1200;
    text-align: center;
    opacity: 0;
    transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    box-shadow: 0 20px 60px rgba(253, 203, 110, 0.4);
}

.artwork-piece-popup.show {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

.artwork-piece-popup .piece-image {
    width: 100px;
    height: 100px;
    margin: 0 auto 1rem;
    border: 4px solid #fff;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}

.artwork-piece-popup .piece-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.artwork-piece-popup .piece-text {
    color: #000;
    font-weight: 700;
    font-size: 1.125rem;
}

/* ============ STEM DOWNLOAD MODAL ============ */
.stem-download-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.95);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s ease;
}

.stem-download-modal.show {
    opacity: 1;
    visibility: visible;
}

.stem-download-box {
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
    border-radius: 20px;
    padding: 2rem;
    width: 90%;
    max-width: 400px;
    text-align: center;
    border: 2px solid var(--gold);
    box-shadow: 0 0 60px rgba(253, 203, 110, 0.3);
}

.stem-download-icon {
    font-size: 4rem;
    margin-bottom: 1rem;
    animation: bounce 0.6s ease infinite alternate;
}

@keyframes bounce {
    from { transform: translateY(0); }
    to { transform: translateY(-10px); }
}

.stem-download-title {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--gold);
    margin-bottom: 0.5rem;
}

.stem-download-subtitle {
    color: var(--text2);
    font-size: 0.9rem;
    margin-bottom: 1.5rem;
}

.stem-artwork-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
    margin-bottom: 1.5rem;
    max-width: 200px;
    margin-left: auto;
    margin-right: auto;
}

.stem-artwork-piece {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 8px;
    border: 2px solid var(--gold);
}

.stem-download-actions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.btn-stem-download {
    background: linear-gradient(135deg, var(--gold) 0%, #e67e22 100%);
    color: #000;
    font-weight: 700;
    padding: 1rem 2rem;
    border-radius: 12px;
    border: none;
    cursor: pointer;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    transition: transform 0.2s, box-shadow 0.2s;
}

.btn-stem-download:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(253, 203, 110, 0.5);
}

/* ============ CRASH OVERLAY REPLAY BUTTON ============ */
.crash-replay-btn {
    background: linear-gradient(135deg, #25F4EE 0%, #FE2C55 100%);
    color: #fff;
    font-weight: 600;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    width: 100%;
}

.crash-replay-btn:hover {
    filter: brightness(1.1);
}

/* ============ ADMIN PANEL ADDITIONS ============ */
.piece-distances-input {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
}

.piece-distance-field {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.piece-distance-field label {
    font-size: 0.75rem;
    color: var(--text2);
    min-width: 50px;
}

.piece-distance-field input {
    flex: 1;
    padding: 0.5rem;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    color: #fff;
    font-size: 0.875rem;
}

.stem-url-section {
    margin-top: 1rem;
    padding: 1rem;
    background: rgba(253, 203, 110, 0.1);
    border: 1px solid rgba(253, 203, 110, 0.3);
    border-radius: 8px;
}

.stem-url-section h5 {
    color: var(--gold);
    margin-bottom: 0.5rem;
    font-size: 0.9rem;
}

/* ============ RESPONSIVE ADJUSTMENTS ============ */
@media (max-width: 480px) {
    .replay-modal-box,
    .tiktok-instructions-box,
    .stem-download-box {
        width: 95%;
        padding: 1rem;
    }
    
    /* Style artwork indicator as a HUD pill on mobile */
    .artwork-progress-container {
        position: fixed;
        top: calc(env(safe-area-inset-top, 0px) + 8px);
        left: auto;
        right: auto;
        bottom: auto;
        /* Dynamic positioning - will be set by JS, fallback to after 2 pills */
        left: 130px;
        padding: 5px 8px;
        border-radius: var(--radius);
        background: rgba(10, 10, 15, 0.92);
        border: 1px solid rgba(253, 203, 110, 0.4);
        backdrop-filter: blur(8px);
        z-index: 10;
    }
    
    /* Always show compact mini indicator on mobile - looks like HUD */
    .artwork-progress-container .artwork-progress-title,
    .artwork-progress-container .artwork-progress-grid,
    .artwork-progress-container .artwork-progress-count,
    .artwork-progress-container .artwork-expand-btn {
        display: none !important;
    }
    
    .artwork-progress-container .artwork-mini-indicator {
        display: flex !important;
        gap: 4px;
    }
    
    .artwork-mini-indicator .mini-icon {
        font-size: 0.875rem;
    }
    
    .artwork-mini-indicator .mini-dot {
        width: 6px;
        height: 6px;
    }
    
    /* Disable expand behavior on mobile */
    .artwork-progress-container.expanded {
        padding: 5px 8px;
        border-radius: var(--radius);
    }
    
    .artwork-progress-container.expanded .artwork-mini-indicator {
        display: flex !important;
    }
    
    .artwork-progress-container.expanded .artwork-progress-title,
    .artwork-progress-container.expanded .artwork-progress-grid,
    .artwork-progress-container.expanded .artwork-progress-count {
        display: none !important;
    }
    
    .replay-video-container {
        max-height: 40vh;
    }
    
    /* Compact HUD on small screens */
    .hud {
        padding: calc(env(safe-area-inset-top, 0px) + 8px) 8px 8px;
        gap: 6px;
    }
    
    .hud-pill {
        padding: 5px 10px;
        gap: 3px;
        border-radius: 12px;
    }
    
    .hud-val {
        font-size: 1.25rem;
    }
    
    .hud-left {
        gap: 4px;
    }
    
    .close-btn {
        width: 36px;
        height: 36px;
        min-width: 36px;
        min-height: 36px;
        font-size: 0.9rem;
        border-radius: 12px;
    }
}

/* Tablet breakpoint */
@media (min-width: 481px) and (max-width: 768px) {
    .artwork-progress-container {
        top: calc(env(safe-area-inset-top, 0px) + 55px);
        right: 10px;
        left: auto;
    }
    
    .hud {
        padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px 10px;
    }
}

/* Landscape mode on phones - hide artwork to save space */
@media (max-height: 450px) and (orientation: landscape) {
    .artwork-progress-container {
        display: none;
    }
    
    .progress-wrap {
        bottom: calc(env(safe-area-inset-bottom, 0px) + 50px);
    }
    
    .layer-dots {
        bottom: calc(env(safe-area-inset-bottom, 0px) + 30px);
    }
}

/* Very small screens */
@media (max-width: 350px) {
    .hud-pill {
        padding: 4px 6px;
    }
    
    .hud-val {
        font-size: 0.875rem;
    }
    
    .hud-left {
        gap: 3px;
        max-width: 65%;
    }
    
    .combo-pill {
        display: none;
    }
}

/* ============ CHALLENGE SONG BADGE ============ */
.challenge-song-badge {
    display: inline-block;
    background: linear-gradient(135deg, var(--primary) 0%, #a29bfe 100%);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    margin-bottom: 0.35rem;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============ WEEKLY CHALLENGES ADMIN ============ */
.weekly-settings-box {
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 12px;
    padding: 1.25rem;
    margin-top: 1rem;
}

.weekly-settings-box h4 {
    margin: 0 0 1rem 0;
    color: var(--text);
    font-size: 1rem;
}

.weekly-current-info {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(255,255,255,0.1);
    font-size: 0.85rem;
    color: var(--text2);
}

.weekly-status {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    margin-right: 0.5rem;
}

.weekly-status.enabled {
    background: rgba(0, 200, 83, 0.2);
    color: #00c853;
}

.weekly-status.disabled {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text2);
}

.weekly-active-card {
    border-left: 3px solid var(--primary);
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.1) 0%, rgba(0, 0, 0, 0) 100%);
}

.admin-card.inactive {
    opacity: 0.6;
}

.admin-card .card-desc {
    margin-top: 0.5rem;
    font-size: 0.8rem;
    color: var(--text2);
}

.admin-card .card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.5rem;
    font-size: 0.75rem;
    color: var(--text2);
}

.admin-card .card-meta span {
    background: rgba(255,255,255,0.05);
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
}

.text-success { color: #00c853 !important; }
.text-muted { color: var(--text2) !important; }

.empty.small {
    padding: 1.5rem;
}

.empty.small .empty-icon {
    font-size: 2rem;
}

/* Weekly Template Modal specific */
#weeklyTemplateModal .form-section {
    background: rgba(255,255,255,0.03);
    border-radius: 8px;
    padding: 1rem;
    margin: 1rem 0;
}

#weeklyTemplateModal .form-section h4 {
    margin: 0 0 0.5rem 0;
    font-size: 0.9rem;
}

#weeklyTemplateModal small {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.7rem;
}

#weeklyTemplateModal code {
    background: rgba(108, 92, 231, 0.2);
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
    font-family: monospace;
}

/* ============ WEEKLY CHALLENGE PLAYER UI ============ */
.challenge-weekly-badge {
    display: inline-block;
    background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 600;
    padding: 0.15rem 0.4rem;
    border-radius: 4px;
    margin-right: 0.3rem;
}

.challenge-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-bottom: 0.25rem;
}

.challenge-card.weekly {
    border-left: 3px solid #00b894;
}

.challenge-card.weekly .challenge-progress-fill {
    background: linear-gradient(90deg, #00b894 0%, #00cec9 100%);
}

.claimed-badge {
    display: inline-block;
    color: #00c853;
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0.3rem 0.6rem;
    background: rgba(0, 200, 83, 0.15);
    border-radius: 6px;
}

/* Weekly Celebration Overlay */
.weekly-celebration-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10000;
    animation: fadeIn 0.3s ease;
}

.weekly-celebration-content {
    text-align: center;
    padding: 2rem;
    animation: bounceIn 0.5s ease;
}

.weekly-celebration-content .celebration-icon {
    font-size: 4rem;
    animation: pulse 1s infinite;
}

.weekly-celebration-content h2 {
    color: #fff;
    margin: 1rem 0 0.5rem;
    font-size: 1.5rem;
}

.weekly-celebration-content .celebration-bonus {
    font-size: 3rem;
    font-weight: 700;
    color: #ffd700;
    text-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
}

.weekly-celebration-content .celebration-label {
    color: var(--text2);
    margin-bottom: 1.5rem;
    font-size: 1rem;
}

@keyframes bounceIn {
    0% { transform: scale(0.5); opacity: 0; }
    70% { transform: scale(1.1); }
    100% { transform: scale(1); opacity: 1; }
}

@keyframes pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.1); }
}

/* ============ CHARACTER SYSTEM - ADMIN ============ */
.character-card {
    position: relative;
}

.character-card.default {
    border-left: 3px solid var(--gold);
}

.character-sprite-preview {
    width: 100%;
    height: 80px;
    background: rgba(0,0,0,0.3);
    border-radius: 8px;
    margin-bottom: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.character-sprite-preview img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    image-rendering: pixelated;
}

.character-sprite-preview .no-sprite {
    color: var(--text2);
    font-size: 0.75rem;
}

.character-sprite-preview.trait-swatch-preview .trait-swatch {
    width: 56px;
    height: 56px;
    font-size: 1.3rem;
}

.sprite-preview {
    margin-top: 0.5rem;
    text-align: center;
}

.sprite-preview img {
    max-width: 100%;
    max-height: 100px;
    border-radius: 8px;
    image-rendering: pixelated;
}

/* ============ CHARACTER SYSTEM - PLAYER UI ============ */
.btn-character {
    width: 100%;
    margin-bottom: 0.5rem;
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.3) 0%, rgba(253, 121, 168, 0.3) 100%);
    border: 1px solid rgba(108, 92, 231, 0.5);
    color: #fff;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.btn-character:hover {
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.5) 0%, rgba(253, 121, 168, 0.5) 100%);
}


.char-btn-icon {
    font-size: 1.2rem;
}

/* Character Select Modal */
.character-modal .modal-box {
    max-width: 500px;
    max-height: 85vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.character-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid rgba(255,255,255,0.1);
}

.character-modal-header h2 {
    margin: 0;
    font-size: 1.25rem;
}

.char-modal-vinyls {
    background: linear-gradient(135deg, var(--gold) 0%, #f39c12 100%);
    color: #000;
    font-weight: 700;
    padding: 0.35rem 0.75rem;
    border-radius: 20px;
    font-size: 0.9rem;
}

.character-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 1rem;
    overflow-y: auto;
    flex: 1;
    padding: 0.5rem;
    margin: -0.5rem;
}

.character-select-card {
    background: rgba(255,255,255,0.05);
    border-radius: 12px;
    padding: 1rem;
    text-align: center;
    border: 2px solid transparent;
    transition: all 0.2s ease;
    position: relative;
}

.character-select-card.selected {
    border-color: var(--primary);
    background: rgba(108, 92, 231, 0.15);
}

.character-select-card.locked {
    opacity: 0.85;
}

.character-select-card:hover {
    transform: translateY(-2px);
    background: rgba(255,255,255,0.08);
}

.char-sprite {
    width: 80px;
    height: 80px;
    margin: 0 auto 0.75rem;
    background: rgba(0,0,0,0.3);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

.char-sprite img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    image-rendering: pixelated;
}

.char-placeholder {
    font-size: 2.5rem;
}

.char-lock-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    border-radius: 12px;
}

.char-name {
    font-weight: 700;
    font-size: 0.95rem;
    margin-bottom: 0.25rem;
}

.char-desc {
    font-size: 0.7rem;
    color: var(--text2);
    margin-bottom: 0.5rem;
    line-height: 1.3;
}

.char-badge {
    display: inline-block;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.char-badge.selected {
    background: rgba(0, 200, 83, 0.2);
    color: #00c853;
}

.char-badge.price {
    background: linear-gradient(135deg, rgba(255, 215, 0, 0.2) 0%, rgba(243, 156, 18, 0.2) 100%);
    color: var(--gold);
}

.char-action {
    margin-top: 0.5rem;
}

.char-action .btn {
    width: 100%;
    font-size: 0.75rem;
    padding: 0.4rem 0.75rem;
}

.character-modal-footer {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(255,255,255,0.1);
    text-align: center;
}

/* Mobile responsive */
@media (max-width: 480px) {
    .character-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }
    
    .character-select-card {
        padding: 0.75rem;
    }
    
    .char-sprite {
        width: 60px;
        height: 60px;
    }
}

/* Character button change indicator */
.char-btn-change {
    font-size: 0.7rem;
    opacity: 0.7;
    margin-left: 0.25rem;
}

.btn-character:hover .char-btn-change {
    opacity: 1;
}

/* Recovery Modal */
.recovery-modal .modal-box {
    text-align: center;
}

.recovery-modal input {
    width: 100%;
    margin-bottom: 0.5rem;
}

#recoveryCodeDisplay {
    cursor: pointer;
}

#recoveryCodeDisplay:hover {
    background: var(--bg2);
}

/* ============ PWA / HOMESCREEN MODE ============ */
/* iOS PWA specific fixes */
.ios-pwa {
    /* Use custom viewport height variable for iOS */
    --real-vh: calc(var(--vh, 1vh) * 100);
}

.ios-pwa .platform,
.ios-pwa .game-screen,
.ios-pwa .modal {
    /* Use the JS-calculated viewport height */
    height: calc(var(--vh, 1vh) * 100);
    max-height: calc(var(--vh, 1vh) * 100);
}

/* PWA mode - extra padding for notch/home indicator */
.pwa-mode {
    /* Ensure safe areas are respected */
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
}

.pwa-mode .platform {
    min-height: 100%;
    min-height: 100dvh;
    min-height: -webkit-fill-available;
}

/* Prevent overscroll bounce in PWA */
.pwa-mode {
    overscroll-behavior: none;
    -webkit-overflow-scrolling: touch;
}

/* Fix for iOS PWA status bar area */
.ios-pwa .game-screen {
    padding-top: env(safe-area-inset-top);
}

.ios-pwa #gameHud {
    top: calc(env(safe-area-inset-top) + 10px);
}

/* Ensure modals are visible in PWA mode */
.pwa-mode .modal {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
}

/* Hide browser-specific UI hints in PWA mode */
.pwa-mode .install-prompt,
.pwa-mode .browser-hint {
    display: none !important;
}

/* Fix touch targets in PWA mode */
.pwa-mode button,
.pwa-mode .btn,
.pwa-mode a {
    -webkit-tap-highlight-color: transparent;
}

/* Smooth scrolling in PWA */
.pwa-mode .scrollable {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}
/* ============================================================
   DUEL MODE — Complete UI Styles
   ============================================================ */

/* ── btn-duel — pregame overlay button (logged-in users only) ── */
.btn-duel {
    background: linear-gradient(135deg, #e17055, #d63031);
    color: #fff;
    box-shadow: 0 4px 15px rgba(225, 112, 85, 0.35);
    width: 100%;
    margin-top: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    font-weight: 700;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-duel:hover,
.btn-duel:focus-visible {
    background: linear-gradient(135deg, #d63031, #c0392b);
    box-shadow: 0 6px 20px rgba(225, 112, 85, 0.5);
    transform: translateY(-1px);
    outline: none;
}
.btn-duel:active {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(225, 112, 85, 0.35);
}

/* ── Duel HUD (live overlay during a duel run) ─────────────── */
.duel-hud {
    display: none;
    position: fixed;
    top: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 900;
    background: rgba(10, 10, 15, 0.88);
    border: 1px solid rgba(225, 112, 85, 0.4);
    border-radius: 30px;
    padding: 0.35rem 1rem;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    pointer-events: none;
    min-width: 220px;
    max-width: 90vw;
}
.duel-hud.show {
    display: block;
}
.duel-hud-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    font-family: 'Space Grotesk', sans-serif;
}
.duel-hud-player,
.duel-hud-opp {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.8rem;
}
.duel-hud-label {
    color: var(--text2);
    font-size: 0.72rem;
    max-width: 72px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.duel-hud-score {
    color: var(--gold);
    font-weight: 700;
    font-size: 0.9rem;
    min-width: 24px;
    text-align: right;
}
.duel-hud-unit {
    color: var(--text3);
    font-size: 0.72rem;
}
.duel-hud-vs {
    color: var(--danger);
    font-weight: 800;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    flex-shrink: 0;
}
.duel-opp-online {
    font-size: 0.6rem;
    line-height: 1;
}
.duel-item-inventory {
    display: flex;
    justify-content: center;
    gap: 0.4rem;
    margin-top: 0.3rem;
    flex-wrap: wrap;
    pointer-events: all;
}
.duel-item-btn {
    background: rgba(253, 203, 110, 0.15);
    border: 1px solid rgba(253, 203, 110, 0.4);
    border-radius: 8px;
    color: var(--gold);
    font-size: 1.2rem;
    width: 2.25rem;
    height: 2.25rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, transform 0.1s;
    line-height: 1;
}
.duel-item-btn:hover {
    background: rgba(253, 203, 110, 0.3);
    transform: scale(1.1);
}
.duel-item-btn:active {
    transform: scale(0.95);
}

/* ── Duel Countdown Overlay ────────────────────────────────── */
.duel-countdown-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: rgba(10, 10, 15, 0.75);
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.duel-countdown-overlay.show {
    display: flex;
}
.duel-countdown-number {
    font-family: 'Bebas Neue', 'Space Grotesk', sans-serif;
    font-size: clamp(5rem, 20vw, 9rem);
    color: var(--gold);
    text-shadow: 0 0 60px rgba(253, 203, 110, 0.6);
    animation: duelCountdownPop 0.9s ease-out;
    line-height: 1;
}
@keyframes duelCountdownPop {
    0%   { transform: scale(1.6); opacity: 0; }
    40%  { transform: scale(1);   opacity: 1; }
    80%  { transform: scale(1);   opacity: 1; }
    100% { transform: scale(0.8); opacity: 0; }
}

/* ── Duel Result Overlay ───────────────────────────────────── */
.duel-result-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1100;
    background: rgba(10, 10, 15, 0.9);
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
.duel-result-overlay.show {
    display: flex;
}
.duel-result-content {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-lg);
    padding: 2rem 1.75rem;
    max-width: 380px;
    width: 100%;
    text-align: center;
    animation: duelResultSlide 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes duelResultSlide {
    from { transform: translateY(40px) scale(0.95); opacity: 0; }
    to   { transform: translateY(0)    scale(1);    opacity: 1; }
}
.duel-result-icon {
    font-size: 3.5rem;
    margin-bottom: 0.5rem;
    line-height: 1;
}
.duel-result-headline {
    font-family: 'Bebas Neue', 'Space Grotesk', sans-serif;
    font-size: 2.25rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    line-height: 1;
    margin-bottom: 1.25rem;
}
.duel-result-scores {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
    background: rgba(255, 255, 255, 0.04);
    border-radius: var(--radius);
    padding: 1rem;
}
.duel-score-block {
    flex: 1;
    text-align: center;
}
.duel-score-label {
    font-size: 0.75rem;
    color: var(--text2);
    margin-bottom: 0.3rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.duel-score-value {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--text);
}
.duel-vs {
    font-family: 'Bebas Neue', sans-serif;
    font-size: 1.25rem;
    color: var(--text3);
    letter-spacing: 0.05em;
    flex-shrink: 0;
}
.duel-result-rewards {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}
.duel-result-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.duel-result-actions .btn {
    width: 100%;
}

/* ── Duel Lobby Modal ──────────────────────────────────────── */
.duel-invite-url {
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: var(--bg2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-sm);
    color: var(--text1);
    font-size: 0.78rem;
    font-family: monospace;
    box-sizing: border-box;
    cursor: text;
    margin-bottom: 1rem;
}
.duel-lobby-status {
    color: var(--text2);
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

/* ── Duel Invite Modal ─────────────────────────────────────── */
.duel-challenger-name {
    color: var(--gold);
    font-weight: 700;
}

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 380px) {
    .duel-hud {
        padding: 0.3rem 0.75rem;
        min-width: 190px;
    }
    .duel-hud-label {
        max-width: 56px;
    }
    .duel-hud-score {
        font-size: 0.82rem;
    }
    .duel-result-content {
        padding: 1.5rem 1.25rem;
    }
    .duel-result-headline {
        font-size: 1.875rem;
    }
}
/* ═══════════════════════════════════════════════════════════════════════════
   SONG CARD V2 — added 2026-06-09
   Merged Featured-into-list layout, square cover left + progress/stems right,
   full-width action button at the bottom.

   Structure:
     .song-card.song-card--v2
       .card-top
         .card-art       ← square cover image
           .card-badges  ← FEATURED / EXCLUSIVE / UNLOCKED pills
         .card-body
           .card-titlerow      ← title + artist
           .card-status        ← OUT / SOLD OUT / Xd badges
           .card-progress      ← progress bar with %
           .card-stems         ← 4 stem icons (lit when unlocked)
       .card-action            ← full-width play / reward button

   Mobile: card-top stacks (art on top, body below) for small screens? NO —
   stays horizontal because the art is what the user recognizes first.
   ─────────────────────────────────────────────────────────────────────────── */

/* Section gap */
.songs-section { margin-bottom: 1.5rem; }

/* Base card */
.song-card.song-card--v2 {
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 16px;
    padding: 0;
    margin-bottom: 0.875rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
    position: relative;
}
.song-card.song-card--v2:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
    transform: translateY(-1px);
}
.song-card.song-card--v2:active { transform: scale(0.99); }

/* Top section — art + body side-by-side */
.song-card--v2 .card-top {
    display: flex;
    gap: 0.875rem;
    padding: 0.875rem;
    align-items: stretch;
}

/* Cover art — square, fills the height */
.song-card--v2 .card-art {
    width: 128px;
    height: 128px;
    border-radius: 12px;
    flex-shrink: 0;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    background: var(--primary);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
.song-card--v2 .card-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}
/* If the cover has important content at the edges (like "FREE DOWNLOAD" text),
   the page can opt-in to contain instead of cover by adding .card-art--fit
   class. By default cover (= fills the square, may crop edges). */
.song-card--v2 .card-art--fit img {
    object-fit: contain;
    background: rgba(0, 0, 0, 0.3);
}

/* Top-left badges stacked on the art (FEATURED / EXCLUSIVE / UNLOCKED) */
.song-card--v2 .card-badges {
    position: absolute;
    top: 6px;
    left: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    z-index: 2;
    align-items: flex-start;
}
.song-card--v2 .card-badge {
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.8px;
    padding: 3px 7px;
    border-radius: 5px;
    text-transform: uppercase;
    line-height: 1;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
    white-space: nowrap;
}
.card-badge--featured {
    background: linear-gradient(135deg, #e6b84a 0%, #c89630 100%);
    color: #0a0a0a;
}
.card-badge--exclusive {
    background: linear-gradient(135deg, #c4a544 0%, #a08428 100%);
    color: #1a1a1a;
}
.card-badge--unlocked {
    background: linear-gradient(135deg, #1fcc5e 0%, #15a04a 100%);
    color: #fff;
}
.card-badge--remix {
    background: linear-gradient(135deg, #9b59b6 0%, #8e44ad 100%);
    color: #fff;
}
.card-badge--remix-locked {
    background: rgba(255, 255, 255, 0.08);
    color: var(--text2);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

/* .song-hero-badges reuses the same .card-badge / .card-badge--* classes as
   the song grid cards (FEATURED, EXCLUSIVE, UNLOCKED, latest-release, and
   the two Remix Mode variants above) but sits outside .song-card--v2, so it
   never inherited the base sizing rule above (font-size/padding/radius) —
   only the color modifiers applied, leaving badges on the main dashboard
   stage rendering as unstyled full-size text. Mirrors the v2 card rule. */
.song-hero-badges .card-badge {
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.8px;
    padding: 3px 7px;
    border-radius: 5px;
    text-transform: uppercase;
    line-height: 1;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
    white-space: nowrap;
}

/* Card body (right side of top) */
.song-card--v2 .card-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    justify-content: space-between;
}

.song-card--v2 .card-titlerow {
    min-width: 0;
}
.song-card--v2 .card-title {
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
}
.song-card--v2 .card-artist {
    font-size: 0.82rem;
    color: var(--text2);
    margin-top: 2px;
}

.song-card--v2 .card-status {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    font-size: 11px;
    /* uses existing .badge styles */
}

/* Progress bar */
.song-card--v2 .card-progress {
    margin-top: 2px;
}
.song-card--v2 .card-progress-label {
    display: flex;
    justify-content: space-between;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--text3);
    text-transform: uppercase;
    margin-bottom: 4px;
}
.song-card--v2 .card-progress-pct {
    color: var(--text);
    font-weight: 800;
}
.song-card--v2 .card-progress-bar {
    height: 6px;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 3px;
    overflow: hidden;
}
.song-card--v2 .card-progress-fill {
    height: 100%;
    border-radius: 3px;
    transition: width 0.4s ease;
    box-shadow: 0 0 8px currentColor;
}

/* Stem icons row */
.song-card--v2 .card-stems {
    display: flex;
    gap: 4px;
    margin-top: 4px;
}
.song-card--v2 .stem {
    flex: 1;
    text-align: center;
    padding: 6px 2px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
    transition: background 0.2s;
    min-width: 0;
}
.song-card--v2 .stem-icon {
    font-size: 14px;
    line-height: 1;
    margin-bottom: 2px;
    filter: grayscale(1) brightness(0.5);
    transition: filter 0.3s;
}
.song-card--v2 .stem-label {
    font-size: 8px;
    font-weight: 700;
    letter-spacing: 0.5px;
    color: var(--text3);
    text-transform: uppercase;
    transition: color 0.3s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.song-card--v2 .stem--on {
    background: rgba(108, 92, 231, 0.12);
}
.song-card--v2 .stem--on .stem-icon {
    filter: none;
}
.song-card--v2 .stem--on .stem-label {
    color: #b6a8ff;
}

/* Card action button — full-width strip at the bottom */
.song-card--v2 .card-action {
    width: 100%;
    border: none;
    padding: 0.875rem 1rem;
    font-size: 0.85rem;
    font-weight: 800;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
    color: #fff;
    transition: filter 0.15s, transform 0.1s;
    font-family: inherit;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.song-card--v2 .card-action:hover { filter: brightness(1.1); }
.song-card--v2 .card-action:active { transform: scale(0.99); }

.song-card--v2 .card-action--play {
    /* Background set inline with song color */
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.song-card--v2 .card-action--reward {
    background: linear-gradient(135deg, #e6b84a 0%, #c89630 100%);
    color: #0a0a0a;
    text-shadow: none;
}

/* ─── COMPLETED STATE — green glow + ring ────────────────────────────────── */
.song-card.song-card--v2.song-card--completed {
    border-color: rgba(31, 204, 94, 0.4);
    box-shadow:
        0 0 0 1px rgba(31, 204, 94, 0.2),
        0 4px 20px rgba(31, 204, 94, 0.15);
}
.song-card--v2.song-card--completed .card-art {
    box-shadow:
        0 0 0 3px rgba(31, 204, 94, 0.4),
        0 4px 16px rgba(0, 0, 0, 0.3);
}

/* ─── FEATURED STATE — purple/gold accent ────────────────────────────────── */
.song-card.song-card--v2.song-card--featured:not(.song-card--completed) {
    border-color: rgba(230, 184, 74, 0.3);
    box-shadow:
        0 0 0 1px rgba(230, 184, 74, 0.15),
        0 4px 20px rgba(230, 184, 74, 0.1);
}

/* ─── DESKTOP — 2-3 columns side by side (max 1100px wide grid) ──────────────
   NOTE (fix): this grid used to be dead code — its parent .songs-list was
   hard-capped at max-width:480px (later 540px at >=768px) with no override
   at any desktop breakpoint, so this 1100px grid could never actually take
   effect; the "desktop layout" was just the mobile column stretched into a
   sea of empty space. This block now also widens the parent so the grid
   this file already ships can finally render. ──────────────────────────── */
@media (min-width: 901px) {
    .songs-list {
        max-width: 1100px;
    }
    .songs-section {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
        gap: 1rem;
        max-width: 1100px;
        margin-left: auto;
        margin-right: auto;
    }
    .songs-section-title {
        grid-column: 1 / -1;
    }
    .song-card.song-card--v2 {
        margin-bottom: 0; /* grid gap handles spacing */
    }
    .archive-toggle,
    .archive-list {
        max-width: 1100px;
        margin-left: auto;
        margin-right: auto;
    }

    /* Other dashboard tabs — same fix in spirit: give them real desktop
       breathing room instead of staying pinned to the 480/540px mobile
       measure. Kept narrower than the song grid since these are simple
       stacked lists / fixed 3-col badge grids, not multi-column layouts. */
    .challenges-list,
    .lb-list,
    .badges-grid {
        max-width: 720px;
    }

    /* Compact header: the 768px breakpoint below grows the hero (bigger
       logo, bigger padding) for tablet — on real desktop that just wastes
       vertical space above the fold before any actual content. Pull it
       back down and bring the player-bar visually closer so the two
       stacked blocks read as one compact header unit. */
    .hero {
        padding: 1.5rem var(--pad) 0.5rem;
    }
    .logo {
        width: 64px;
        height: 64px;
        font-size: 2rem;
        margin-bottom: 0.75rem;
    }
    .brand {
        font-size: 1.75rem;
    }
    .tagline {
        margin-top: 0.5rem;
    }
    .player-bar {
        margin-top: 0.75rem;
    }
    .tabs {
        max-width: 720px;
    }

    /* Unified dashboard card — desktop gets a real two-column layout
       (stage + panel side by side) instead of just the same phone-style
       stacked card stretched or centered with a lot of dead space on
       either side. Header, dividers, thumbnail strip, and icon tabs stay
       full-width rows above/below; only the stage+panel pair goes side by
       side, since that's the pairing with room to actually use extra
       width meaningfully (a bigger character showcase + a roomier info
       panel) rather than just stretching short text across more space. */
    .dashboard-card {
        max-width: 1040px; /* base rule already handles width/centering/align-self */
        display: flex;
        flex-wrap: wrap;
    }
    .dc-header,
    #tabSongs,
    #tabChallenges,
    #tabBadges,
    #tabScores,
    #tabHistory,
    .dc-divider,
    .song-thumb-strip,
    .tabs.tabs--icons {
        flex: 0 0 100%; /* each still gets its own full-width row */
    }
    /* #tabSongs wraps .song-hero + .song-hero-panel one level deeper than
       before (moved there so switching tabs swaps content within the same
       card — see the HTML comment above #tabSongs), so it needs to be a
       flex container itself now for the stage+panel pair below to go
       side by side; the flex-basis rules on them alone aren't enough
       once their direct parent isn't .dashboard-card anymore. */
    #tabSongs {
        display: flex;
        flex-wrap: wrap;
    }
    .song-hero {
        flex: 0 0 44%;
        height: 440px;
    }
    .song-hero-panel {
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding: 2rem 2.5rem;
        border-left: 1px solid rgba(255, 255, 255, 0.06);
    }
    /* Bigger card → bigger character again, scaled to match. Re-checked
       clearance from nav arrows at the NARROWEST this can actually render
       (viewport exactly 901px → card capped to ~869px → stage ≈382px,
       not the full 1040px-card math): character 240px centered leaves
       ~71px each side, arrows (46px wide, 10px from edge) reach ~56px in
       — ~15px of real clearance at the tightest point, not just at the
       comfortable end of the range. */
    .song-hero-character {
        width: 240px;
        height: 240px;
        bottom: 28px;
    }
    .char-hero-crop {
        width: 135px;
        height: 228px; /* 135px * (845/500), same single-frame aspect ratio */
    }
    .char-hero-swap-badge {
        width: 44px;
        height: 44px;
        font-size: 1.25rem;
    }
    .song-hero-nav {
        width: 46px;
        height: 46px;
        font-size: 1.6rem;
    }
    /* Panel content no longer needs to be squeezed for a narrow phone
       column — let the title/stems breathe a bit more. */
    .song-hero-title {
        font-size: 1.7rem;
    }
    .song-hero-artist {
        font-size: 1rem;
    }
    .song-hero-play {
        max-width: 380px;
    }

    /* At this width, Challenges/Badges as a single narrow stacked column
       would waste most of the card's horizontal space — same "not
       utilizing the screen" problem as the old Songs card list had. Give
       them a real multi-column layout at desktop instead. */
    .dc-tab-panel .challenges-list {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }
    .dc-tab-panel .challenge-card {
        margin-bottom: 0; /* grid gap handles spacing now */
    }
    .dc-tab-panel .badge-row {
        grid-template-columns: repeat(6, 1fr);
    }
}

/* Tighten the gap between the dashboard card and the referral/share
   section below it on desktop — those still render as their own
   (deliberately separate, dismissible/toggleable) elements below the
   main card, but the vertical gap read as much bigger than intended next
   to how tight everything inside the unified card now is. Width/centering
   for .referral-panel is now handled at its base rule (applies at every
   size, not just ≥901px) — only the max-width bump and margin tightening
   are desktop-specific here. .share-bar's own max-width:320px + centering
   was already correct as-is for a small utility row like that. */
@media (min-width: 901px) {
    .referral-panel {
        max-width: 1040px;
        margin-top: 0.75rem;
        margin-bottom: 0.75rem;
    }
    .share-bar {
        margin-top: 0.75rem;
        margin-bottom: 0.75rem;
    }
}

/* ─── MOBILE — tighter padding, smaller art, but stays horizontal ────────── */
@media (max-width: 480px) {
    .song-card--v2 .card-top {
        gap: 0.625rem;
        padding: 0.625rem;
    }
    .song-card--v2 .card-art {
        width: 96px;
        height: 96px;
    }
    .song-card--v2 .card-title {
        font-size: 0.95rem;
    }
    .song-card--v2 .card-artist {
        font-size: 0.78rem;
    }
    .song-card--v2 .stem-icon {
        font-size: 13px;
    }
    .song-card--v2 .stem-label {
        font-size: 7px;
    }
    .song-card--v2 .card-action {
        padding: 0.75rem 1rem;
        font-size: 0.8rem;
    }
    .song-card--v2 .card-badge {
        font-size: 8px;
        padding: 2px 5px;
    }
}

/* ─── VERY SMALL SCREENS — hide stem labels to save room ─────────────────── */
@media (max-width: 360px) {
    .song-card--v2 .card-art {
        width: 80px;
        height: 80px;
    }
    .song-card--v2 .stem {
        padding: 4px 1px;
    }
    .song-card--v2 .stem-label {
        display: none; /* icons only on tiny phones */
    }
    .song-card--v2 .stem-icon {
        font-size: 15px;
        margin-bottom: 0;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   END SONG CARD V2
   ═════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   HEADER UPGRADE — chip-style profile bar (matches the ChatGPT mockup look)
   Targets the existing .player-bar / .streak-badge / .vinyl-count-badge
   elements without changing the HTML, so all existing JS keeps working.
   ─────────────────────────────────────────────────────────────────────────── */

.player-bar {
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: rgba(30, 28, 50, 0.6);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 18px;
    margin-top: 1.25rem;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.2);
    font-size: 1rem;
}

#playerNameDisplay {
    font-weight: 700;
    font-size: 1rem;
    color: var(--text);
}

/* The streak badge styled as a chip with bold number + small "LEVEL" subtitle */
.streak-badge {
    background: linear-gradient(135deg, #ff6b6b 0%, #e85d3c 100%);
    padding: 0.4rem 0.75rem;
    border-radius: 12px;
    font-size: 0.95rem;
    font-weight: 800;
    color: #fff;
    box-shadow: 0 2px 8px rgba(232, 93, 60, 0.3);
    letter-spacing: 0.5px;
    line-height: 1;
}

/* Vinyls chip — gold accent on dark background */
.vinyl-count-badge {
    background: rgba(20, 18, 30, 0.7);
    border: 1px solid rgba(253, 203, 110, 0.35);
    padding: 0.4rem 0.85rem;
    border-radius: 12px;
    font-size: 0.95rem;
    font-weight: 800;
    color: #fdcb6e;
    letter-spacing: 0.5px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
/* Pre-pend gold vinyl-disc icon */
.vinyl-count-badge::before {
    content: '';
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background:
        radial-gradient(circle at center,
            #1a1612 0%, #1a1612 22%,
            #fdcb6e 24%, #d4a82e 70%, #b08820 100%);
    border: 1px solid #b08820;
    flex-shrink: 0;
    box-shadow: 0 0 4px rgba(253, 203, 110, 0.4);
}

/* Hide the trailing 💿 emoji JS adds since we have ::before now */
/* Note: JS does textContent.toLocaleString() so no trailing emoji — pseudo-elem alone is correct */

/* Edit pencil button — cleaner */
.player-bar button {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--text2);
    padding: 0.4rem 0.6rem;
    border-radius: 10px;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.player-bar button:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.15);
}

/* On mobile keep it tight */
@media (max-width: 480px) {
    .player-bar {
        gap: 0.5rem;
        padding: 0.6rem 0.75rem;
        font-size: 0.9rem;
    }
    .streak-badge,
    .vinyl-count-badge {
        font-size: 0.85rem;
        padding: 0.35rem 0.6rem;
    }
    #playerNameDisplay {
        font-size: 0.95rem;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   END HEADER UPGRADE
   ═════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   HUB HEADER REDESIGN — v3 (mobile-first, iPhone 12 Pro verified)
   added 2026-06-09

   3 distinct cards:
     1. Hero card     — "BACKSTAGE" + tagline (vinyl on side, no avatar)
     2. Profile card  — name + level chip + vinyls chip + edit
     3. Tab card      — 2-row tab grid on mobile (no ellipsis)

   Mobile (iPhone 12 Pro, 390px wide) was failing because:
     - Hero brand was cut off (z-index/overflow)
     - 5 tabs in 1 row don't fit → text was being ellipsized
   Fix: hero title above the vinyl decoration (no overlap),
        tabs go 3-then-2 grid on mobile so all labels stay readable.
   ─────────────────────────────────────────────────────────────────────────── */

/* ─── 1. Hero card — compact, single unified card (title + identity) ─────
   Previously: title + 3-line tagline + a decorative CSS "vinyl" circle in
   one card, then a SEPARATE player-bar card stacked right below it — two
   boxes, two shadows, extra vertical space before any real content.
   Now: one card. Tagline and decorative circle removed per request (they
   didn't carry their weight visually); player identity moved inside as a
   second row separated by a thin divider, so it reads as one compact,
   deliberate unit instead of two stacked panels. ─────────────────────── */
.platform .hero {
    background: linear-gradient(135deg,
        rgba(108, 92, 231, 0.18) 0%,
        rgba(108, 92, 231, 0.06) 55%,
        rgba(40, 35, 65, 0.4) 100%);
    border: 1px solid rgba(108, 92, 231, 0.22);
    border-radius: 18px;
    padding: 1.125rem 1.125rem 0.875rem;
    margin: 0.875rem 1rem;
    text-align: left;
    position: relative;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    /* CRITICAL: .platform is a flex column (via .screen.active) with a
       fixed height (100dvh) and overflow-y:auto. A flex item whose own
       overflow is non-"visible" (this element uses overflow:hidden for
       the corner glow below) gets its automatic minimum size treated as 0
       instead of its content size — so the flexbox algorithm is legally
       allowed to squash this card down when total page content is taller
       than the viewport, and overflow:hidden then silently clips whatever
       got squeezed out. That's what was cutting off the title and hiding
       the player-bar row entirely. flex-shrink:0 opts this out of the
       shrinking algorithm — it always renders at its full content height,
       and the page scrolls (via .platform's own overflow-y:auto) instead. */
    flex-shrink: 0;
}

/* Signature touch replacing the old literal "vinyl" circle: a soft glow
   tucked in the corner, not a decorative shape competing with the title. */
.platform .hero::before {
    content: '';
    position: absolute;
    top: -35%;
    right: -10%;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(108, 92, 231, 0.3) 0%, transparent 70%);
    pointer-events: none;
    z-index: 0;
}
.platform .hero::after {
    content: none;
}

/* Hide the old emoji logo */
.platform .hero .logo {
    display: none;
}

/* Hero title */
.platform .hero .brand {
    font: 800 1.375rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.14em;
    color: #b6a8ff;
    position: relative;
    z-index: 2;
    margin: 0;
    line-height: 1.1;
}
.platform .hero .brand span {
    color: #b6a8ff;
}

/* Player identity row nested inside the hero card — thin divider instead
   of a whole separate card. */
.player-bar.player-bar--nested {
    background: transparent;
    border: none;
    box-shadow: none;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    margin: 0.75rem 0 0 0;
    padding: 0.75rem 0 0 0;
    width: 100%;
    max-width: none;
    justify-content: space-between;
    position: relative;
    z-index: 2;
}

/* ─── ONE unified dashboard card ─────────────────────────────────────────
   Everything below — header, song stage, info panel, thumbnail strip, icon
   tabs — is ONE continuous surface now: one background, one border, one
   radius, one shadow. Previously these were 4 separate floating boxes with
   their own backgrounds/borders/margins, which read as 4 disconnected
   widgets rather than one game screen. Internal sections are separated by
   thin hairline dividers (.dc-divider) instead of gaps between cards.
   Lives inside #platformScreen so it's automatically hidden for guests by
   the existing rule near the top of this file — no extra guest-gating
   needed here. ──────────────────────────────────────────────────────────── */
.dashboard-card {
    margin: 0.75rem 1rem 1rem;
    border-radius: 22px;
    overflow: hidden;
    border: 1px solid rgba(108, 92, 231, 0.18);
    background: var(--surface);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
    flex-shrink: 0; /* same flex-column collapse risk as everything else in
                        this flex column — see the .song-hero note below */
    /* Capped + centered at every width, not just ≥901px — previously there
       was no max-width at all below 901px, so a moderately-resized desktop
       browser window (anywhere under that breakpoint) rendered the card
       fully stretched with no cap, and separately, relying only on
       margin:auto to center a stretch-sized flex child in a column is a
       flexbox edge case that isn't uniformly reliable. align-self:center
       here is the unambiguous, always-correct centering mechanism, scoped
       to just this element — it doesn't touch how .platform's OTHER
       children (referral panel, share bar, footer) size themselves, unlike
       changing align-items on the parent would have. width:100% ensures
       it still fills up to whatever max-width applies at a given size
       (true phone widths never reach 900px anyway, so this is invisible
       there) rather than shrinking to its content's natural width once
       align-self stops it from being force-stretched. */
    width: 100%;
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
    align-self: center;
}

.dc-header {
    padding: 1.125rem 1.125rem 0.875rem;
    background: linear-gradient(135deg,
        rgba(108, 92, 231, 0.18) 0%,
        rgba(108, 92, 231, 0.06) 55%,
        rgba(40, 35, 65, 0.4) 100%);
    position: relative;
    overflow: hidden;
}
/* Same corner glow that used to live on the standalone header card —
   kept as the one decorative flourish since the header no longer has its
   own border to visually separate it, this fills that role instead. */
.dc-header::before {
    content: '';
    position: absolute;
    top: -35%;
    right: -10%;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(108, 92, 231, 0.3) 0%, transparent 70%);
    pointer-events: none;
    z-index: 0;
}
.dc-header .brand {
    font: 800 1.375rem 'Bebas Neue', sans-serif;
    letter-spacing: 0.14em;
    color: #b6a8ff;
    position: relative;
    z-index: 2;
    margin: 0;
    line-height: 1.1;
}
.dc-header .brand span { color: #b6a8ff; }

/* Top row of the header - just the brand now (vinyl count moved down
   next to the username per updated request). */
.dc-header-top {
    display: flex;
    align-items: center;
    position: relative;
    z-index: 2;
}

/* Left-hand group in the identity row: edit-pencil, name, vinyl count -
   all together so they read as one "who am I" unit, with the hamburger
   menu as its own separate item pinned to the right (space-between on
   the parent .player-bar--nested handles that split). */
.player-identity {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
/* Plain icon button, no chip/background/border - just the pencil glyph
   sitting next to the name it edits. Overrides .player-bar button's
   default chip styling (background/border) which would otherwise apply
   to every button inside .player-bar, this one included. */
.player-bar .edit-name-btn {
    background: none;
    border: none;
    padding: 0.2rem 0.3rem;
}
.player-bar .edit-name-btn:hover {
    background: rgba(255, 255, 255, 0.06);
}

/* Hamburger menu — replaces the old bottom icon-tab row. Same showTab()
   calls under the hood, just reachable from a dropdown next to the
   pencil/edit-name button instead of a separate row of icons at the very
   bottom of the card.
   Uses position:fixed (positioned via JS from the button's own
   bounding rect) rather than position:absolute - .dc-header and
   .dashboard-card both set overflow:hidden for their rounded corners,
   which silently clipped/hid an absolutely-positioned dropdown nested
   inside them. Fixed positioning is anchored to the viewport instead,
   so it always renders on top, unclipped, regardless of what overflow
   rules any ancestor card/header has. */
.hamburger-wrap {
    position: relative;
}
.hamburger-menu {
    display: none;
    position: fixed;
    min-width: 180px;
    background: var(--surface2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 14px;
    box-shadow: 0 10px 32px rgba(0, 0, 0, 0.45);
    padding: 0.4rem;
    z-index: 9999;
    flex-direction: column;
    gap: 0.15rem;
}
.hamburger-menu.show {
    display: flex;
}
.hamburger-item {
    background: none;
    border: none;
    color: var(--text);
    text-align: left;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
    white-space: nowrap;
}
.hamburger-item:hover {
    background: rgba(255, 255, 255, 0.06);
}
.hamburger-item.active {
    background: rgba(108, 92, 231, 0.25);
    color: #fff;
}

/* Thin hairline separating logical sections within the one card — replaces
   what used to be a visible gap between separate cards. */
.dc-divider {
    height: 1px;
    background: rgba(255, 255, 255, 0.06);
    margin: 0 1rem;
}

.song-hero {
    position: relative;
    /* Bumped from 200px → 240px to fit the larger character (160px, up
       from 116px) with real clearance from the position-dots row at the
       top — at the old height there was only ~2px of gap between them. */
    height: 240px;
    overflow: hidden; /* keep the character/background contained to the
       stage - without this, a tall character crop can spill above the
       stage bounds and sit on top of the dots/change-character button */
    background: linear-gradient(135deg, var(--surface2), var(--surface));
    /* flex-column collapse guard: .dashboard-card (the actual flex child of
       .platform) already carries flex-shrink:0, which is sufficient — this
       element is a normal-flow child of that card, not of .platform
       directly, so it doesn't need its own flex-shrink rule anymore. */
}

.song-hero-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-color: var(--surface2); /* shows while/if no cover art is set */
    filter: brightness(0.6) saturate(1.1);
    transform: scale(1.08); /* hides any edge gap from the blur-safe overscale */
    z-index: 0;
}

/* Light scrim — the stage no longer carries any text, this is only here
   so the character silhouette reads clearly against a busy cover image. */
.song-hero-stage-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10, 10, 15, 0.05) 0%, rgba(10, 10, 15, 0.35) 100%);
    z-index: 1;
}

.song-hero-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(6px);
    color: #fff;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
}
.song-hero-nav:hover { background: rgba(0, 0, 0, 0.5); }
.song-hero-nav:active { transform: translateY(-50%) scale(0.94); }
.song-hero-nav.prev { left: 0.625rem; }
.song-hero-nav.next { right: 0.625rem; }

/* Character "stands" centered in the stage, in front of the cover-art
   background — same visual idea as Talking Tom standing in front of the
   farmhouse scene. Pure visual tap-target, opens the character picker —
   the ONLY place characters are reachable from now (no character button
   on the pre-game screen, no separate shop entry point anymore). Sized up
   from the original 116px — against a busy, colorful cover-art photo the
   character was reading as small and easy to miss. */
.song-hero-character {
    position: absolute;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    z-index: 2;
    width: 160px;
    height: 160px;
    display: flex;
    align-items: flex-end; /* character "stands" on the box's bottom edge */
    justify-content: center;
    cursor: pointer;
}

/* Sprite sheets store 2 walking-animation frames side by side in one
   image (left half / right half). We only ever want to display ONE
   frame - centered, not both frames squeezed into the box. This
   wrapper clips to exactly half the sprite's (scaled) width so only
   the left frame is visible. Height is scaled by the SAME factor as
   width (200%), so the frame keeps its correct aspect ratio - it's
   cropped horizontally only, never stretched or squashed.
   Sized to 90x152 (not the full 160px parent width) so the character
   actually fits inside the stage with room to spare above for the
   dots/change-character button - matching the box to the parent's
   full 160px width made the character as tall as ~270px, taller than
   the 240px stage itself, spilling out and overlapping the button. */
.char-hero-crop {
    width: 90px;
    height: 152px; /* 90px * (845/500) - matches a single frame's aspect ratio */
    overflow: hidden;
    position: relative;
    filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.5));
}
.char-hero-img {
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;   /* full 2-frame sheet, scaled so 1 frame = container width */
    height: auto;  /* preserves aspect ratio - no distortion */
    image-rendering: pixelated;
}
.char-hero-placeholder {
    font-size: 5.5rem;
    filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.5));
}

/* ── Equipped trait effect on the dashboard hero stage ────────────────────
   Sits behind .char-hero-crop (z-index below it via source order — the crop
   div comes after this one in the DOM) so it reads as a backlight/aura
   around the character, matching how the in-game canvas draws glow_aura
   BEFORE the sprite. Populated by applyHeroTraitEffect() in game-ui.js. */
.hero-trait-fx {
    position: absolute;
    left: 50%;
    bottom: 18px;
    width: 140px;
    height: 140px;
    transform: translateX(-50%);
    pointer-events: none;
    /* No explicit z-index: .char-hero-crop also has no z-index (auto), and
       auto-stacked siblings paint in DOM source order — this div comes
       first in the markup, so it paints below the crop/sprite without
       needing a z-index war. (An explicit z-index here, even z-index:1,
       would incorrectly paint ABOVE the crop despite coming first in the
       DOM, since z-index:1 always beats z-index:auto regardless of order.) */
}
.hero-trait-fx.glow::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(circle, var(--trait-color, #fdcb6e) 0%, transparent 70%);
    opacity: 0.65;
    animation: heroTraitGlowPulse 2.4s ease-in-out infinite;
}
@keyframes heroTraitGlowPulse {
    0%, 100% { transform: scale(0.92); opacity: 0.55; }
    50% { transform: scale(1.08); opacity: 0.8; }
}
.hero-trait-particle {
    position: absolute;
    left: 50%;
    bottom: 10px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--p-color, #fff);
    box-shadow: 0 0 6px var(--p-color, #fff);
    opacity: 0;
    animation: heroTraitParticleFloat 2.4s ease-out infinite;
    animation-delay: var(--p-delay, 0s);
}
@keyframes heroTraitParticleFloat {
    0%   { transform: translate(0, 0) scale(0.6); opacity: 0; }
    15%  { opacity: 1; }
    100% { transform: translate(var(--p-x, 0), -130px) scale(1); opacity: 0; }
}
/* "Tap to change character" hint badge — was getting visually lost
   against busy/colorful cover art at the old 26px size with only a thin
   dark border for contrast. Bigger now, plus a glow/shadow so it reads
   clearly regardless of what's behind it. */
.char-hero-swap-badge {
    position: absolute;
    right: -4px;
    bottom: 6px;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--primary);
    border: 3px solid var(--bg);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.15);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
}

.song-hero-dots {
    position: absolute;
    top: 0.75rem;
    left: 0;
    right: 0;
    z-index: 3;
    display: flex;
    justify-content: center;
    gap: 0.3rem;
}
.song-hero-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.4);
    transition: background 0.15s, width 0.15s;
}
.song-hero-dot.active {
    background: var(--gold);
    width: 14px;
    border-radius: 3px;
}

/* This button existed in the HTML with no matching CSS rule at all, so it
   rendered as a plain static (non-positioned) element. Every sibling in
   .song-hero (bg, scrim, dots, nav arrows, character) is position:absolute,
   so this was the ONLY normal-flow content left in the stage - painted in
   the base layer, underneath the absolutely-positioned cover-art
   background and scrim (which paint on top of in-flow content). Net
   effect: the button existed and was clickable-in-theory but was
   completely hidden behind the stage background. Positioning it (with a
   z-index above the scrim) and adding real styling fixes both the
   invisibility and gives it the pill look the surrounding buttons have. */
.song-hero-change-char-btn {
    position: absolute;
    top: 2.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(6px);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
}
.song-hero-change-char-btn:hover { background: rgba(0, 0, 0, 0.6); }
.song-hero-change-char-btn:active { transform: translateX(-50%) scale(0.96); }

/* Second pill (Traits) sits beside the character-change pill instead of
   stacking on the same centered transform — shift each half-width apart. */
.song-hero-change-char-btn:not(.song-hero-traits-btn) { transform: translateX(calc(-100% - 0.3rem)); }
.song-hero-change-char-btn.song-hero-traits-btn { left: 50%; transform: translateX(0.3rem); }
.song-hero-change-char-btn:not(.song-hero-traits-btn):active { transform: translateX(calc(-100% - 0.3rem)) scale(0.96); }
.song-hero-change-char-btn.song-hero-traits-btn:active { transform: translateX(0.3rem) scale(0.96); }

/* ── Trait cards — reuse .character-select-card layout, swap the sprite
   image for a colored effect swatch since traits have no uploaded art. ── */
.trait-swatch {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    background: radial-gradient(circle, var(--swatch-color, #8a8fa3) 0%, rgba(0,0,0,0) 72%);
    border: 2px solid var(--swatch-color, #8a8fa3);
    box-shadow: 0 0 14px var(--swatch-color, #8a8fa3);
}
.trait-swatch.rainbow {
    background: conic-gradient(from 0deg, #ff5f6d, #fdcb6e, #4dff88, #00d4ff, #a66bff, #ff5f6d);
    border-color: transparent;
    box-shadow: 0 0 14px rgba(255,255,255,0.5);
}

/* ── Remix Mode "NEW" teaser — first-time nudge on the pregame button so a
   freshly-unlocked feature doesn't sit silently under Start. Stops once
   launchRemixMode() marks the song's remixTried flag (see game-ui.js /
   game-remix-mode.js). ─────────────────────────────────────────────────── */
.remix-btn-teaser {
    animation: remixTeaserPulse 1.8s ease-in-out infinite;
}
@keyframes remixTeaserPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(155, 89, 182, 0.55); }
    50% { box-shadow: 0 0 0 8px rgba(155, 89, 182, 0); }
}
.remix-btn-new {
    display: inline-block;
    margin-left: 0.3rem;
    padding: 0.05rem 0.35rem;
    border-radius: 999px;
    background: #ffd54a;
    color: #1a1a1a;
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    vertical-align: middle;
}

/* ── Info panel — solid surface, sits BELOW the stage in normal flow.
   Everything the old vertical card used to show, now here instead. ────── */
.song-hero-panel {
    padding: 0.875rem 1rem 0.875rem;
    background: var(--surface);
}
.song-hero-badges {
    display: flex;
    gap: 0.375rem;
    margin-bottom: 0.375rem;
    flex-wrap: wrap;
    /* Reserves space for one badge row even when a song has none/only one —
       without this, switching between a song with 3 badges and one with
       just "✓ OUT" made the whole panel (and so the whole card) visibly
       change height as you swipe between songs. */
    min-height: 1.5rem;
}
.song-hero-titlerow {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.625rem;
}
.song-hero-title {
    font: 700 1.15rem 'Space Grotesk', sans-serif;
    color: var(--text);
}
.song-hero-artist {
    font-size: 0.78rem;
    color: var(--text2);
}
.song-hero-stems {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}
.song-hero-stem {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.375rem 0.25rem;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.03);
    opacity: 0.4;
}
.song-hero-stem.on {
    opacity: 1;
    background: rgba(108, 92, 231, 0.12);
}
.song-hero-stem-icon { font-size: 1rem; }
.song-hero-stem-label {
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--text3);
}
.song-hero-stem.on .song-hero-stem-label { color: var(--primary); }

.song-hero-progress-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}
.song-hero-progress-bar {
    flex: 1;
    height: 6px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 3px;
    overflow: hidden;
}
.song-hero-progress-fill {
    height: 100%;
    background: var(--gold);
    border-radius: 3px;
    transition: width 0.25s ease;
}
.song-hero-progress-pct {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text2);
    min-width: 32px;
    text-align: right;
}
.song-hero-play {
    width: 100%;
    padding: 0.8rem;
    border: none;
    border-radius: 12px;
    background: var(--primary);
    color: #fff;
    font: 700 0.9rem 'Space Grotesk', sans-serif;
    cursor: pointer;
    box-shadow: 0 4px 16px rgba(108, 92, 231, 0.4);
}
.song-hero-play:active { transform: scale(0.98); }

/* Row that holds the main action button plus the "Play Again" button that
   appears once a song is completed - without a flex row here the second
   button would just stack full-width below the first instead of sitting
   compactly beside it. */
.song-hero-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.song-hero-actions .song-hero-play {
    flex: 1;
    width: auto;
}
/* Secondary style - a completed song's main button becomes the reward CTA
   (kept as the bold primary-colored button), so "Play Again" is styled as
   a lower-emphasis outline button instead of competing with it. */
.song-hero-play--secondary {
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    box-shadow: none;
}
.song-hero-play--secondary:active { transform: scale(0.98); }

/* Remix Mode button on the dashboard hero — same footprint as the other
   two action buttons, but keeps the purple identity Remix Mode has used
   everywhere else (admin panel, victory CTA, crash motivator) instead of
   blending into the plain "Play Again" outline style. */
.song-hero-play--remix {
    background: linear-gradient(135deg, #9b59b6, #8e44ad);
    border: none;
    color: #fff;
    box-shadow: 0 4px 16px rgba(155, 89, 182, 0.35);
}
.song-hero-play--remix:active { transform: scale(0.98); }
.song-hero-play--remix:disabled { opacity: 0.7; cursor: default; }

/* ─── Thumbnail strip — tap a cover to jump straight to that song. This
   plus the panel above is the entire song-browsing interface now — no
   separate vertical card list, no collapsible "Archive" section. Sits
   inside .dashboard-card between two .dc-divider hairlines now, so it no
   longer needs its own bottom margin or flex-shrink (that's the card's
   job as a whole). ──────────────────────────────────────────────────────── */
.song-thumb-strip {
    display: flex;
    gap: 0.625rem;
    overflow-x: auto;
    padding: 0.75rem 1rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.song-thumb-strip::-webkit-scrollbar { display: none; }
.song-thumb {
    position: relative;
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    border-radius: 12px;
    overflow: hidden; /* clips the <img> to the rounded corners below */
    border: 2px solid transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    transition: border-color 0.15s, transform 0.15s;
}
.song-thumb img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.song-thumb-icon {
    position: relative;
    z-index: 1;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.song-thumb.active {
    border-color: var(--gold);
    transform: scale(1.06);
}
.song-thumb.locked {
    opacity: 0.7;
    font-size: 1rem;
}
/* Countdown badge on a scheduled/upcoming song's thumbnail — visible while
   scanning the strip, not just after swiping all the way to it. */
.song-thumb-countdown {
    position: absolute;
    bottom: -5px;
    right: -5px;
    background: var(--gold);
    color: #1a1400;
    font-size: 0.6rem;
    font-weight: 800;
    padding: 0.1rem 0.3rem;
    border-radius: 6px;
    border: 1.5px solid var(--bg);
    line-height: 1.3;
}

/* Hint shown in the (now otherwise empty) Songs tab panel — since songs are
   browsed via the always-visible stage/panel/strip above rather than a
   list inside this tab, a brief pointer avoids the tab looking broken. */
.songs-tab-hint {
    text-align: center;
    color: var(--text3);
    font-size: 0.8rem;
    padding: 2rem 1rem;
}

/* ─── Icon-only tab row (Talking-Tom-style compact menu) — same #tab*
   elements, same showTab() calls as the old full-width text tab bar,
   restyled only. Keeps every tab reachable including Songs (no dead-end
   navigation), just visually smaller so the hero above stays the focal
   point. ─────────────────────────────────────────────────────────────── */
/* ─── Icon-only tab row (Talking-Tom-style compact menu) — same #tab*
   elements, same showTab() calls as the old full-width text tab bar,
   restyled only. Now the last section inside .dashboard-card (hence the
   safe-area-aware bottom padding), so it no longer needs its own margin,
   max-width, or flex-shrink — that's the card's job as a whole. ────────── */
.tabs.tabs--icons {
    display: flex;
    justify-content: center;
    gap: 0.625rem;
    margin: 0;
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
    max-width: none;
}
.tabs--icons .tab {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    padding: 0;
    /* Slightly lighter than the card's own background (was --surface
       before, which now blends invisibly into the card sitting behind it
       — --surface2 keeps these reading as distinct buttons). */
    background: var(--surface2);
    border: 1px solid rgba(255, 255, 255, 0.06);
}
.tabs--icons .tab.active {
    background: var(--primary);
    border-color: transparent;
    box-shadow: 0 4px 14px rgba(108, 92, 231, 0.4);
}

/* ─── Challenges/Badges/Scores/History now live inside .dashboard-card too
   (moved there so switching tabs swaps content within the same card
   instead of jumping to differently-styled panels floating below it —
   previously each of these was designed as a page-level section sitting
   directly on the app's base --bg, with --surface cards for contrast; now
   the CARD ITSELF is --surface, so those same cards would blend in
   almost invisibly against their own new parent. Bumping every card-like
   element in here to --surface2 restores the contrast, and padding
   matches .song-hero-panel so all 5 tabs feel like one consistent
   interface rather than 4 old page layouts pasted into a box. ─────────── */
.dc-tab-panel {
    padding: 0.875rem 1rem;
}
.dc-tab-panel .challenge-card,
.dc-tab-panel .challenges-stats,
.dc-tab-panel .badge-item,
.dc-tab-panel .lb-item,
.dc-tab-panel .lb-your-rank,
.dc-tab-panel .history-item,
.dc-tab-panel .history-stat-card {
    background: var(--surface2);
}
.dc-tab-panel .challenge-card.completed {
    background: linear-gradient(135deg, rgba(0, 184, 148, 0.14), var(--surface2));
}
/* These sub-lists previously centered themselves on a full page with
   max-width:480px — now they're already bounded by the card, so let them
   use its full content width instead of an extra, now-redundant cap. */
.dc-tab-panel .challenges-list,
.dc-tab-panel .challenges-stats,
.dc-tab-panel .lb-list,
.dc-tab-panel .badges-grid,
.dc-tab-panel .history-stats-grid {
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
}
/* Headers previously had page-level top padding (assuming they were the
   first thing on the screen) — now they're the first thing in the card's
   content area, which already has its own padding, so trim the double
   spacing. */
.dc-tab-panel .challenges-header,
.dc-tab-panel .badges-header,
.dc-tab-panel .scores-header,
.dc-tab-panel .history-header {
    padding-top: 0;
}

/* ─── 2. Profile card — NO avatar, just name + chips + edit ──────────────── */
.player-bar {

    gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    background: rgba(30, 28, 50, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 16px;
    margin: 0 1rem 1rem 1rem;
    width: auto;
    max-width: none;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.2);
    font-size: 1rem;
    justify-content: flex-start;
    flex-wrap: nowrap;
}

#playerNameDisplay {
    font-weight: 700;
    font-size: 1rem;
    color: var(--text);
    flex: 1;
    min-width: 0;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
}
/* No avatar — removed */

/* Level chip (🔥) */
.streak-badge {
    background: linear-gradient(135deg, #ff7a5c 0%, #e85d3c 100%);
    padding: 0.4rem 0.7rem;
    border-radius: 12px;
    font-size: 0.92rem;
    font-weight: 800;
    color: #fff;
    box-shadow: 0 2px 8px rgba(232, 93, 60, 0.32);
    letter-spacing: 0.3px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
}

/* Vinyls chip with CSS vinyl-disc icon */
.vinyl-count-badge {
    background: rgba(20, 18, 30, 0.75);
    border: 1px solid rgba(253, 203, 110, 0.4);
    padding: 0.4rem 0.75rem;
    border-radius: 12px;
    font-size: 0.92rem;
    font-weight: 800;
    color: #fdcb6e;
    letter-spacing: 0.3px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}
.vinyl-count-badge::before {
    content: '';
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background:
        radial-gradient(circle at center,
            #1a1612 0%, #1a1612 22%,
            #fdcb6e 24%, #d4a82e 70%, #b08820 100%);
    border: 1px solid #b08820;
    flex-shrink: 0;
    box-shadow: 0 0 5px rgba(253, 203, 110, 0.45);
}

/* Edit pencil button */
.player-bar > button {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--text2);
    padding: 0.4rem 0.55rem;
    border-radius: 10px;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    flex-shrink: 0;
}
.player-bar > button:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.18);
}

/* ─── 3. Tab navigation — readable on every screen ───────────────────────── */
.platform .tabs {
    background: rgba(30, 28, 50, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 16px;
    padding: 0.5rem;
    margin: 0 1rem 1rem 1rem;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.2);
    max-width: none;
    display: grid;
    /* Desktop: 5 columns in one row */
    grid-template-columns: repeat(5, 1fr);
    gap: 0.375rem;
}

.platform .tabs .tab {
    background: transparent;
    border: none;
    border-radius: 11px;
    padding: 0.625rem 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    color: var(--text2);
    cursor: pointer;
    transition: all 0.15s;
    text-align: center;
    /* NEVER ellipsize — wrap to next line instead if needed */
    white-space: normal;
    word-break: keep-all;
    line-height: 1.2;
    min-width: 0;
    overflow: visible;
}
.platform .tabs .tab:hover {
    background: rgba(255, 255, 255, 0.04);
    color: var(--text);
}
.platform .tabs .tab.active {
    background: linear-gradient(135deg, #6c5ce7 0%, #5046c4 100%);
    color: #fff;
    box-shadow:
        0 2px 8px rgba(108, 92, 231, 0.4),
        inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* ─── MOBILE BREAKPOINTS ─────────────────────────────────────────────────── */

/* Tablet & narrower (≤768px): tighten hero a bit */
@media (max-width: 768px) {
    .platform .hero {
        padding: 1.25rem 1.125rem;
        margin: 0.75rem 0.875rem 0.875rem 0.875rem;
    }
    .player-bar,
    .platform .tabs {
        margin-left: 0.875rem;
        margin-right: 0.875rem;
    }
}

/* Mobile (≤480px): tabs go to 2 rows so every label is readable */
@media (max-width: 480px) {
    .platform .hero {
        padding: 1.1rem 1rem;
        margin: 0.625rem 0.75rem 0.75rem 0.75rem;
        border-radius: 16px;
    }
    .platform .hero .brand {
        font-size: 1.4rem;
    }

    .player-bar,
    .platform .tabs {
        margin-left: 0.75rem;
        margin-right: 0.75rem;
    }

    .player-bar {
        padding: 0.625rem 0.75rem;
        gap: 0.5rem;
        font-size: 0.9rem;
    }
    #playerNameDisplay {
        font-size: 0.95rem;
    }
    .streak-badge,
    .vinyl-count-badge {
        font-size: 0.82rem;
        padding: 0.35rem 0.55rem;
    }
    .player-bar > button {
        padding: 0.35rem 0.5rem;
        font-size: 0.8rem;
    }

    /* Tabs: 3 in top row, 2 in bottom row — both rows fully balanced.
       Use a 6-column grid so we can span tabs perfectly:
         Row 1: tabs 1,2,3 each span 2 cols (3 × 2 = 6 cols, full row)
         Row 2: tabs 4,5 each span 3 cols (2 × 3 = 6 cols, full row)
       Every tab is wide enough for its label, nothing ellipsized. */
    .platform .tabs {
        grid-template-columns: repeat(6, 1fr);
        padding: 0.4rem;
        gap: 0.3rem;
    }
    .platform .tabs .tab:nth-child(1),
    .platform .tabs .tab:nth-child(2),
    .platform .tabs .tab:nth-child(3) {
        grid-column: span 2;
    }
    .platform .tabs .tab:nth-child(4),
    .platform .tabs .tab:nth-child(5) {
        grid-column: span 3;
    }
    .platform .tabs .tab {
        font-size: 0.75rem;
        padding: 0.6rem 0.4rem;
    }
}

/* Very small (≤360px): 2 columns × 3 rows fallback */
@media (max-width: 360px) {
    .platform .tabs {
        grid-template-columns: repeat(2, 1fr);
    }
    .platform .tabs .tab:nth-child(1),
    .platform .tabs .tab:nth-child(2),
    .platform .tabs .tab:nth-child(3),
    .platform .tabs .tab:nth-child(4),
    .platform .tabs .tab:nth-child(5) {
        grid-column: auto;
    }
    .platform .tabs .tab {
        font-size: 0.78rem;
        padding: 0.65rem 0.5rem;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   END HUB HEADER REDESIGN v3
   ═════════════════════════════════════════════════════════════════════════ */

/* ========== tutorial-styles.css ========== */
/**
 * DJ SEIP BACKSTAGE - Tutorial Styles
 * First-time user experience overlay and animations
 */

/* ============ TUTORIAL OVERLAY ============ */
.tutorial-overlay {
    position: fixed;
    inset: 0;
    /* Was z-index:90 — higher than the crash/victory end-of-run overlay
       (.overlay, z-index:50), which meant leftover tutorial prompt text /
       hand-pointer / spotlight could visually sit ON TOP of and obscure
       the crash screen if a crash happened while tutorial UI was still
       showing (see crash() in game-core.js for the accompanying state-
       level fix). Moved below 50 so any end-of-run overlay always wins,
       while staying comfortably above the game canvas/HUD (z-index 2–11)
       so it still works correctly during normal tutorial operation. */
    z-index: 45;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.tutorial-overlay.active {
    opacity: 1;
}

.tutorial-overlay.fade-out {
    opacity: 0;
}

/* ============ TUTORIAL PROMPT ============ */
.tutorial-prompt {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -120%);
    background: linear-gradient(135deg, rgba(108, 92, 231, 0.95), rgba(108, 92, 231, 0.8));
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 20px;
    padding: 1rem 1.75rem;
    text-align: center;
    backdrop-filter: blur(12px);
    box-shadow: 
        0 8px 32px rgba(108, 92, 231, 0.4),
        0 0 60px rgba(108, 92, 231, 0.2);
    min-width: 260px;
    animation: tutorialFloat 2s ease-in-out infinite;
}

.tutorial-text {
    font: 700 1.25rem 'Space Grotesk', sans-serif;
    color: #fff;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    white-space: nowrap;
}

@keyframes tutorialFloat {
    0%, 100% { transform: translate(-50%, -120%) translateY(0); }
    50% { transform: translate(-50%, -120%) translateY(-8px); }
}

@keyframes tutorialPulse {
    0% { transform: scale(1.1); opacity: 0.7; }
    100% { transform: scale(1); opacity: 1; }
}

/* ============ DIRECTIONAL ARROWS ============ */
.tutorial-arrow {
    position: absolute;
    width: 60px;
    height: 60px;
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

.tutorial-arrow.show {
    opacity: 1;
}

.tutorial-arrow.left {
    left: -80px;
    top: 50%;
    transform: translateY(-50%);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fdcb6e'%3E%3Cpath d='M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z'/%3E%3C/svg%3E") center/contain no-repeat;
    animation: arrowBounceLeft 0.8s ease-in-out infinite;
}

.tutorial-arrow.right {
    right: -80px;
    top: 50%;
    transform: translateY(-50%);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fdcb6e'%3E%3Cpath d='M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z'/%3E%3C/svg%3E") center/contain no-repeat;
    animation: arrowBounceRight 0.8s ease-in-out infinite;
}

.tutorial-arrow.up {
    left: 50%;
    bottom: -70px;
    transform: translateX(-50%);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fdcb6e'%3E%3Cpath d='M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8z'/%3E%3C/svg%3E") center/contain no-repeat;
    animation: arrowBounceUp 0.8s ease-in-out infinite;
}

@keyframes arrowBounceLeft {
    0%, 100% { transform: translateY(-50%) translateX(0); }
    50% { transform: translateY(-50%) translateX(-12px); }
}

@keyframes arrowBounceRight {
    0%, 100% { transform: translateY(-50%) translateX(0); }
    50% { transform: translateY(-50%) translateX(12px); }
}

@keyframes arrowBounceUp {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50% { transform: translateX(-50%) translateY(-12px); }
}

/* ============ HAND GESTURE INDICATOR ============ */
.tutorial-hand {
    position: fixed;
    font-size: 4rem;
    opacity: 0;
    pointer-events: none;
    filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.4));
    transition: opacity 0.3s ease;
    z-index: 95;
}

.tutorial-hand.show {
    opacity: 1;
}

.tutorial-hand.left {
    left: 12%;
    bottom: 35%;
    animation: handTapLeft 1.2s ease-in-out infinite;
}

.tutorial-hand.right {
    right: 12%;
    bottom: 35%;
    animation: handTapRight 1.2s ease-in-out infinite;
}

.tutorial-hand.up {
    left: 50%;
    bottom: 30%;
    transform: translateX(-50%);
    animation: handTapUp 1.2s ease-in-out infinite;
}

@keyframes handTapLeft {
    0%, 100% { transform: scale(1); opacity: 0.9; }
    15% { transform: scale(0.85); opacity: 1; }
    30% { transform: scale(1) translateX(-20px); opacity: 0.9; }
    50% { transform: scale(1); opacity: 0.9; }
}

@keyframes handTapRight {
    0%, 100% { transform: scale(1); opacity: 0.9; }
    15% { transform: scale(0.85); opacity: 1; }
    30% { transform: scale(1) translateX(20px); opacity: 0.9; }
    50% { transform: scale(1); opacity: 0.9; }
}

@keyframes handTapUp {
    0%, 100% { transform: translateX(-50%) scale(1); opacity: 0.9; }
    15% { transform: translateX(-50%) scale(0.85); opacity: 1; }
    30% { transform: translateX(-50%) scale(1) translateY(-30px); opacity: 0.9; }
    50% { transform: translateX(-50%) scale(1); opacity: 0.9; }
}

/* ============ TUTORIAL PROGRESS ============ */
.tutorial-progress {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom) + 100px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 91;
}

.tutorial-progress-dots {
    display: flex;
    gap: 10px;
    padding: 8px 16px;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 20px;
    backdrop-filter: blur(8px);
}

.tutorial-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
    transition: all 0.3s ease;
}

.tutorial-dot.active {
    background: var(--gold);
    box-shadow: 0 0 8px var(--gold);
}

.tutorial-dot.current {
    background: var(--primary);
    box-shadow: 0 0 12px var(--primary);
    animation: dotPulse 1s ease-in-out infinite;
}

@keyframes dotPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.3); }
}

/* ============ TUTORIAL SPOTLIGHT ============ */
.tutorial-spotlight {
    position: fixed;
    width: 120px;
    height: 120px;
    border: 3px solid var(--gold);
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
    animation: spotlightPulse 1.5s ease-in-out infinite;
    box-shadow: 
        0 0 30px rgba(253, 203, 110, 0.3),
        inset 0 0 30px rgba(253, 203, 110, 0.1);
}

.tutorial-spotlight.show {
    opacity: 1;
}

@keyframes spotlightPulse {
    0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.8; }
    50% { transform: translate(-50%, -50%) scale(1.1); opacity: 1; }
}

/* ============ TUTORIAL VINYL GLOW ============ */
/* Applied via canvas rendering - these are reference values */
.tutorial-vinyl-glow {
    /* Gold glow ring around tutorial vinyls */
    /* Rendered in game-render.js with these colors */
    --glow-color: rgba(253, 203, 110, 0.6);
    --glow-size: 40px;
}

/* ============ SKIP TUTORIAL BUTTON ============ */
.tutorial-skip-btn {
    position: fixed;
    top: calc(env(safe-area-inset-top) + 60px);
    right: var(--pad);
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 20px;
    padding: 0.5rem 1rem;
    color: var(--text2);
    font: 500 0.75rem 'Space Grotesk', sans-serif;
    cursor: pointer;
    z-index: 92;
    backdrop-filter: blur(8px);
    transition: all 0.2s ease;
    opacity: 0;
    pointer-events: none;
}

.tutorial-overlay.active .tutorial-skip-btn {
    opacity: 1;
    pointer-events: auto;
}

.tutorial-skip-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
}

/* ============ LAYER UNLOCK CELEBRATION ============ */
/* Enhanced layer unlock styles */

.layer-unlock-flash {
    animation: layerFlash 0.4s ease-out;
}

@keyframes layerFlash {
    0% { filter: brightness(2) saturate(1.5); }
    100% { filter: brightness(1) saturate(1); }
}

.unlock-popup.enhanced {
    transform: translateX(-50%) translateY(0) scale(1);
    animation: unlockEnhanced 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes unlockEnhanced {
    0% { 
        transform: translateX(-50%) translateY(-50px) scale(0.5);
        opacity: 0;
    }
    50% {
        transform: translateX(-50%) translateY(10px) scale(1.1);
    }
    100% { 
        transform: translateX(-50%) translateY(0) scale(1);
        opacity: 1;
    }
}

/* Full-screen flash overlay for layer unlocks */
.layer-flash-overlay {
    position: fixed;
    inset: 0;
    background: radial-gradient(circle at center, rgba(253, 203, 110, 0.4), transparent 70%);
    pointer-events: none;
    opacity: 0;
    z-index: 80;
    transition: opacity 0.15s ease;
}

.layer-flash-overlay.active {
    opacity: 1;
    animation: flashFade 0.6s ease-out forwards;
}

@keyframes flashFade {
    0% { opacity: 1; }
    100% { opacity: 0; }
}

/* Victory unlock - extra dramatic */
.layer-flash-overlay.victory {
    background: radial-gradient(circle at center, rgba(253, 203, 110, 0.6), rgba(108, 92, 231, 0.3) 50%, transparent 70%);
    animation: victoryFlash 1s ease-out forwards;
}

@keyframes victoryFlash {
    0% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.8; }
    100% { opacity: 0; transform: scale(1.5); }
}

/* Slow-mo effect class */
.game-slowmo canvas {
    transition: filter 0.3s ease;
    filter: saturate(1.3) contrast(1.1);
}

/* Layer unlock text enhancements */
.unlock-popup .text {
    font: 700 1rem 'Space Grotesk', sans-serif;
    color: var(--gold);
    text-shadow: 0 0 20px rgba(253, 203, 110, 0.5);
}

.unlock-popup.show .text {
    animation: textGlow 0.8s ease-in-out;
}

@keyframes textGlow {
    0%, 100% { text-shadow: 0 0 20px rgba(253, 203, 110, 0.5); }
    50% { text-shadow: 0 0 40px rgba(253, 203, 110, 0.8), 0 0 60px rgba(253, 203, 110, 0.4); }
}

/* Music note particles for layer unlock */
.music-note-particle {
    position: fixed;
    font-size: 0.8rem;
    opacity: 0.65;
    pointer-events: none;
    z-index: 85;
    animation: noteFloat 1.4s ease-out forwards;
}

@keyframes noteFloat {
    0% {
        opacity: 1;
        transform: translateY(0) scale(1) rotate(0deg);
    }
    100% {
        opacity: 0;
        transform: translateY(-100px) scale(0.5) rotate(20deg);
    }
}

/* ============ RESPONSIVE ADJUSTMENTS ============ */
@media (max-width: 380px) {
    .tutorial-prompt {
        min-width: 220px;
        padding: 0.875rem 1.25rem;
    }
    
    .tutorial-text {
        font-size: 1.1rem;
    }
    
    .tutorial-hand {
        font-size: 3rem;
    }
    
    .tutorial-arrow {
        width: 50px;
        height: 50px;
    }
    
    .tutorial-arrow.left {
        left: -60px;
    }
    
    .tutorial-arrow.right {
        right: -60px;
    }
}

/* Landscape mode */
@media (orientation: landscape) and (max-height: 500px) {
    .tutorial-prompt {
        top: 30%;
        transform: translate(-50%, -50%);
    }
    
    .tutorial-progress {
        bottom: calc(env(safe-area-inset-bottom) + 20px);
    }
    
    .tutorial-hand {
        font-size: 2.5rem;
    }
    
    .tutorial-hand.left,
    .tutorial-hand.right {
        bottom: 25%;
    }
}

