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

html {
    height: 100%;
    min-height: 100%;
    background: #2c5282;
    background-attachment: fixed;
    overflow-x: hidden;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    line-height: 1.6;
    color: #cbd5e0;
    background: linear-gradient(180deg, #2c5282 0%, #1a365d 50%, #1a202c 100%);
    background-attachment: fixed;
    min-height: 100vh;
    min-height: 100%;
    position: relative;
    margin: 0;
    padding: 0;
    overflow-x: hidden;
    touch-action: manipulation;
}

/* iOS Safari overscroll background fix */
body::before {
    content: '';
    position: fixed;
    top: -50vh;
    left: 0;
    right: 0;
    height: 150vh;
    background: #2c5282;
    z-index: -2;
}

.container {
    max-width: 900px;
    margin: 0 auto;
    padding: 20px;
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
    padding-top: max(20px, env(safe-area-inset-top));
    padding-bottom: max(200px, env(safe-area-inset-bottom));
    min-height: 100vh;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    background: transparent;
}

/* Header */
header {
    text-align: center;
    background: transparent;
    margin-bottom: 0;
    padding: 0.6em 0.6em;
    border-radius: 0;
}

header h1 {
    color: white;
    font-size: 1.8rem;
    margin-bottom: 15px;
    font-weight: 700;
    letter-spacing: -0.5px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.home-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    padding: 8px 16px;
    border-radius: 4px;
    text-decoration: none;
    font-weight: 500;
    font-size: 14px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    transition: all 0.2s ease;
}

.home-button:hover {
    background: rgba(255, 255, 255, 0.2);
    border-color: rgba(255, 255, 255, 0.3);
}

.home-button svg {
    width: 18px;
    height: 18px;
    vertical-align: middle;
    stroke: white;
    transition: transform 0.2s ease;
}

.home-button:hover svg {
    transform: scale(1.05);
}

/* SVG Icons - Professional Outline Style */
svg {
    shape-rendering: geometricPrecision;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.inline-icon {
    width: 24px;
    height: 24px;
    vertical-align: middle;
    margin-left: 8px;
    display: inline-block;
    transition: all 0.2s ease;
    stroke: #667eea;
}

.artwork-placeholder svg {
    width: 80px;
    height: 80px;
    opacity: 0.9;
    stroke: white;
}

/* Main Content */
main {
    flex: 1;
    /* display: flex; */
    align-items: center;
    justify-content: center;
}

/* Auth Container */
.auth-container, .payment-container, .player-container {
    background: rgba(30, 40, 70, 0.9);
    padding: 40px 36px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    max-width: 540px;
    width: 100%;
    text-align: left;
    margin: 0 auto;
    backdrop-filter: blur(10px);
}

.payment-container, .player-container {
    max-width: 680px;
}

.context-poster {
    width: 200px;
    height: 200px;
    margin: 0 auto 30px;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}

.context-poster img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: rgba(0, 0, 0, 0.3);
}

.auth-container h2, .payment-container h2, .player-container h2, .header-nav h2 {
    color: white;
    margin-bottom: 12px;
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.5px;
    display: flex;
    align-items: center;
    justify-content: flex-start;
}

.auth-container p, .payment-container p {
    color: #cbd5e0;
    margin-bottom: 32px;
    font-size: 15px;
    line-height: 1.5;
}

/* Forms */
.auth-form {
    text-align: left;
}

.form-group {
    margin-bottom: 20px;
    width: 100%;
}

.form-group label {
    display: block;
    margin-bottom: 6px;
    font-weight: 500;
    color: #94a3b8;
    text-align: left;
    font-size: 13px;
    letter-spacing: 0.3px;
}

.form-group input {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    font-size: 16px;
    transition: border-color 0.3s ease;
    background: rgba(255, 255, 255, 0.05);
    color: white;
}

.form-group input:focus {
    outline: none;
    border-color: #667eea;
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}

/* Phone Digit Inputs */
.phone-inputs {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    margin: 20px 0;
    width: 100%;
    flex-wrap: nowrap;
}

.digit-input {
    width: 54px !important;
    height: 54px !important;
    min-width: 54px;
    padding: 0 !important;
    text-align: center;
    font-size: 28px;
    font-weight: 600;
    border: 2px solid rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    transition: all 0.2s ease;
    line-height: 54px;
    flex-shrink: 0;
    color: white;
    background: rgba(255, 255, 255, 0.05);
}

.digit-input:focus {
    outline: none;
    border-color: #667eea;
    background: rgba(255, 255, 255, 0.1);
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
    transform: translateY(-1px);
}

/* Phone Single Input Field */
.phone-input-field {
    width: 100%;
    padding: 16px 20px !important;
    text-align: center;
    font-size: 24px !important;
    font-weight: 600;
    letter-spacing: 2px;
    border: 2px solid rgba(255, 255, 255, 0.2) !important;
    border-radius: 12px !important;
    transition: all 0.2s ease;
    color: white !important;
    background: rgba(255, 255, 255, 0.05) !important;
}

.phone-input-field::placeholder {
    color: rgba(255, 255, 255, 0.3);
    letter-spacing: 1px;
}

.phone-input-field:focus {
    outline: none;
    border-color: #667eea !important;
    background: rgba(255, 255, 255, 0.1) !important;
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2) !important;
    transform: translateY(-1px);
}

/* Responsive digit inputs */
@media (max-width: 768px) {
    .auth-container, .payment-container, .player-container {
        padding: 30px 20px;
        margin: 0 auto;
    }

    .digit-input {
        width: 50px !important;
        height: 56px !important;
        min-width: 50px;
        font-size: 26px;
        line-height: 56px;
    }

    .phone-inputs {
        gap: 8px;
        margin: 15px 0;
    }

    .phone-input-field {
        font-size: 20px !important;
        padding: 14px 16px !important;
        letter-spacing: 1px;
    }

    .form-group label {
        font-size: 14px;
    }

    .payment-info {
        font-size: 14px;
        padding: 15px;
        margin-bottom: 20px;
    }

    .payment-info h3 {
        font-size: 1rem;
    }

    .order-item, .order-total {
        font-size: 0.9rem;
    }
}

@media (max-width: 380px) {
    .digit-input {
        width: 44px !important;
        height: 50px !important;
        min-width: 44px;
        font-size: 24px;
        line-height: 50px;
    }

    .phone-inputs {
        gap: 6px;
    }

    .phone-input-field {
        font-size: 18px !important;
        padding: 12px 14px !important;
    }
}

/* Buttons */
.btn {
    display: inline-block;
    padding: 14px 28px;
    border: none;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
    transition: all 0.2s ease;
    width: 100%;
}

.btn-primary {
    background: #667eea;
    color: white;
    box-shadow: 0 2px 8px rgba(102, 126, 234, 0.25);
}

.btn-primary:hover {
    background: #5568d3;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.35);
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none !important;
}

/* ── Button working state ──
   While a request is in flight the label is replaced by a spinner. The button
   keeps its own size (no width jump) because .btn-label is hidden with
   visibility, not display — it still occupies its space — and the spinner is
   centred over the top of it. */
.btn .btn-spinner { display: none; }
.btn.is-working {
    position: relative;
    /* It is disabled for the duration, but must not read as greyed-out: this is
       the button doing its job, so it beats .btn:disabled's 0.5. */
    opacity: 1 !important;
    cursor: progress;
}
.btn.is-working .btn-label { visibility: hidden; }
.btn.is-working .btn-spinner {
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 18px;
    height: 18px;
    margin: -9px 0 0 -9px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btn-spin 0.7s linear infinite;
}
@keyframes btn-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    /* Still show progress, just without the spin. */
    .btn.is-working .btn-spinner { animation-duration: 2.4s; }
}

.btn-large {
    padding: 16px 32px;
    font-size: 16px;
    font-weight: 700;
}

.payment-actions {
    margin-top: 30px;
    text-align: center;
}

/* Messages */
.error-message {
    background: rgba(239, 68, 68, 0.1);
    color: #fca5a5;
    padding: 12px 16px;
    border-radius: 8px;
    margin-top: 15px;
    border: 1px solid rgba(239, 68, 68, 0.3);
}

.loading {
    background: rgba(102, 126, 234, 0.1);
    color: #93c5fd;
    padding: 12px 16px;
    border-radius: 8px;
    margin-top: 15px;
    border: 1px solid rgba(102, 126, 234, 0.3);
}

.sms-consent {
    margin-top: 32px !important;
    margin-bottom: 0 !important;
    font-size: 11.5px !important;
    line-height: 1.5 !important;
    color: #8a94a8 !important;
    text-align: center;
}

.sms-consent a {
    color: #a8b3c8;
    text-decoration: underline;
}

.sms-consent a:hover {
    color: #cbd5e0;
}

.sms-consent-wrap {
    margin-bottom: 16px;
}

.sms-consent-label {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    cursor: pointer;
    font-size: 11.5px;
    line-height: 1.5;
    color: #8a94a8;
    text-align: left;
}

.sms-consent-check {
    flex-shrink: 0;
    margin-top: 2px;
    width: 16px;
    height: 16px;
    accent-color: #667eea;
    cursor: pointer;
}

.sms-consent-text {
    flex: 1;
}

.sms-consent-links {
    margin: 8px 0 0 26px;
    font-size: 11.5px;
    color: #8a94a8;
    text-align: left;
}

.sms-consent-links a {
    color: #a8b3c8;
    text-decoration: underline;
}

.sms-consent-links a:hover {
    color: #cbd5e0;
}

.sms-consent-links-sep {
    margin: 0 6px;
    color: #64748b;
}

/* Help Text */
.help-text {
    margin-top: 20px;
    text-align: center;
}

.help-text p {
    color: #94a3b8;
    font-size: 14px;
}

.link {
    color: #667eea;
    text-decoration: none;
}

.link:hover {
    text-decoration: underline;
}

/* Payment Styles */
.payment-info {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 30px;
    text-align: left;
    width: 100%;
    box-sizing: border-box;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.payment-info h3 {
    color: white;
    margin-bottom: 15px;
    font-size: 1.2rem;
}

.order-item {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    flex-wrap: wrap;
    gap: 10px;
    color: #cbd5e0;
}

.order-total {
    margin-top: 15px;
    font-size: 1.2rem;
    display: flex;
    justify-content: space-between;
    color: white;
}

.price {
    color: #4ade80;
    font-weight: 600;
    white-space: nowrap;
}

/* Player Styles */
.track-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 30px;
    text-align: center;
    /* padding: 40px 20px 30px; */
}

body.player-page .track-info {
    background: transparent;
    /* padding: 50px 20px 30px; */
}

.track-artwork {
    margin-bottom: 20px;
}

.artwork-image {
    width: 300px;
    height: 300px;
    object-fit: cover;
    box-shadow: 0 12px 30px rgba(0,0,0,0.4);
    border: 2px solid rgba(255,255,255,0.15);
    background: rgba(0,0,0,0.3);
}

.artwork-placeholder {
    width: 300px;
    height: 300px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    /* border-radius: 12px; */
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
    color: white;
    box-shadow: 0 12px 30px rgba(0,0,0,0.4);
    border: 2px solid rgba(255,255,255,0.15);
}

.track-details {
    width: 100%;
}

.btn-gallery {
    margin-top: 15px;
    padding: 10px 20px;
    background: rgba(102, 126, 234, 0.2);
    border: 1px solid rgba(102, 126, 234, 0.4);
    border-radius: 8px;
    color: #667eea;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.btn-gallery svg {
    width: 18px;
    height: 18px;
}

.btn-gallery:hover {
    background: rgba(102, 126, 234, 0.3);
    border-color: rgba(102, 126, 234, 0.6);
    transform: translateY(-1px);
}

/* Gallery Modal */
@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

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

.gallery-modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.95);
    z-index: 10000;
    justify-content: center;
    align-items: center;
    animation: fadeIn 0.2s ease-out;
}

.gallery-modal.closing {
    animation: fadeOut 0.2s ease-out;
}

.gallery-container {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 60px 20px 20px;
}

.gallery-close {
    position: absolute;
    top: 10px;
    right: 10px;
    font-size: 50px;
    color: white;
    background: rgba(0, 0, 0, 0.5);
    border: none;
    cursor: pointer;
    z-index: 10001;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
    border-radius: 50%;
    line-height: 1;
}

.gallery-close:hover {
    background: rgba(102, 126, 234, 0.8);
    transform: rotate(90deg);
}

.gallery-swiper {
    width: 100%;
    height: 100%;
    max-width: 1400px;
}

.gallery-swiper .swiper-slide {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
}

.gallery-swiper .swiper-slide img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.gallery-swiper .swiper-zoom-container {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Swiper navigation buttons */
.gallery-swiper .swiper-button-next,
.gallery-swiper .swiper-button-prev {
    color: white;
    background: rgba(0, 0, 0, 0.5);
    width: 50px;
    height: 50px;
    border-radius: 50%;
    transition: all 0.3s ease;
}

.gallery-swiper .swiper-button-next:after,
.gallery-swiper .swiper-button-prev:after {
    font-size: 20px;
}

.gallery-swiper .swiper-button-next:hover,
.gallery-swiper .swiper-button-prev:hover {
    background: rgba(102, 126, 234, 0.8);
}

/* Swiper pagination */
.gallery-swiper .swiper-pagination {
    bottom: 20px;
}

.gallery-swiper .swiper-pagination-fraction {
    color: white;
    font-size: 18px;
    font-weight: 600;
    background: rgba(0, 0, 0, 0.5);
    padding: 8px 16px;
    border-radius: 20px;
    width: auto;
    left: 50%;
    transform: translateX(-50%);
}

/* Thumbnail Gallery */
.gallery-thumbs {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    height: 100px;
    width: 90%;
    max-width: 800px;
    padding: 0 10px;
}

.gallery-thumbs .swiper-slide {
    width: 100px;
    height: 100px;
    opacity: 0.4;
    cursor: pointer;
    transition: opacity 0.3s ease;
    border-radius: 8px;
    overflow: hidden;
}

.gallery-thumbs .swiper-slide-thumb-active {
    opacity: 1;
    border: 2px solid #667eea;
}

.gallery-thumbs .swiper-slide:hover {
    opacity: 0.7;
}

.gallery-thumbs .swiper-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 768px) {
    .gallery-container {
        padding: 50px 10px 10px;
    }

    .gallery-close {
        top: 5px;
        right: 5px;
        font-size: 40px;
        width: 45px;
        height: 45px;
    }

    .gallery-swiper .swiper-button-next,
    .gallery-swiper .swiper-button-prev {
        width: 40px;
        height: 40px;
    }

    .gallery-swiper .swiper-button-next:after,
    .gallery-swiper .swiper-button-prev:after {
        font-size: 16px;
    }

    .gallery-swiper .swiper-pagination-fraction {
        font-size: 16px;
        padding: 6px 12px;
    }

    .gallery-thumbs {
        height: 70px;
        bottom: 10px;
        width: 95%;
    }

    .gallery-thumbs .swiper-slide {
        width: 70px;
        height: 70px;
    }
}

.track-details h3 {
    color: #4a5568;
    margin-bottom: 8px;
    font-size: 1.5rem;
}

body.player-page .track-details h3 {
    color: white;
    font-size: 1.6rem;
    font-weight: 700;
}

.track-details p {
    color: #718096;
    margin-bottom: 4px;
}

body.player-page .track-details p {
    color: #a0aec0;
}

.track-details .track-summary {
    color: #94a3b8;
    font-size: 0.85rem;
    margin-top: 6px;
}

/* Custom Audio Player */
.audio-player {
    margin-bottom: 30px;
}

.audio-player audio {
    display: none;
}

/* Track List */
.song-list {
    margin: 0;
    padding-bottom: 30px;
    background: transparent;
    border-radius: 0;
}

.song-list h3 {
    margin: 0 0 15px 0;
    color: white;
    font-size: 1.2rem;
}

#track-list {
    padding-left: 0;
    list-style: none;
    counter-reset: track-counter;
}

.track-item {
    padding: 18px 15px;
    margin: 0;
    background: rgba(30, 40, 70, 0.8);
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    counter-increment: track-counter;
    border: none;
    margin-bottom: 8px;
    color: #e2e8f0;
    position: relative;
}

.track-item .track-name {
    flex: 1;
    text-align: left;
}

.track-item .track-duration {
    flex: none;
    margin-left: 12px;
    color: #94a3b8;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.track-item::before {
    content: counter(track-counter);
    color: #94a3b8;
    font-weight: 600;
    min-width: 32px;
    width: 32px;
    font-size: 16px;
    text-align: center;
    flex-shrink: 0;
}

.track-item:hover {
    background: rgba(30, 40, 70, 0.95);
    transform: translateX(2px);
}

.track-item.active {
    /* Background and border removed - playing indicator is sufficient */
}

.track-item.active::before {
    color: #667eea;
}

.track-item.playing::before {
    visibility: hidden;
}

/* Playing indicator - animated bars */
.playing-indicator {
    display: none;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    height: 16px;
    width: 32px;
    min-width: 32px;
    flex-shrink: 0;
    position: absolute;
}
.playing-indicator-left {
    left: 15px;
}

.playing-indicator-right {
    right: 15px;
}


.track-item.playing .playing-indicator {
    display: flex;
}

.playing-indicator span {
    width: 3px;
    background: #667eea;
    border-radius: 2px;
    animation: sound-wave 1s ease-in-out infinite;
}

.playing-indicator span:nth-child(1) {
    height: 60%;
    animation-delay: 0s;
}

.playing-indicator span:nth-child(2) {
    height: 100%;
    animation-delay: 0.2s;
}

.playing-indicator span:nth-child(3) {
    height: 80%;
    animation-delay: 0.4s;
}

@keyframes sound-wave {
    0%, 100% {
        height: 30%;
    }
    50% {
        height: 100%;
    }
}

/* Credits Section */
.credits-section {
    margin-top: 30px;
    padding: 18px 15px;
    background: rgba(30, 40, 70, 0.6);
    border-radius: 4px;
}

.credits-section h3 {
    color: #cbd5e0;
    font-size: 1.1rem;
    margin: 0 0 15px 20px;
    padding: 0;
    font-weight: 600;
    
}

.credits-text {
    color: #94a3b8;
    font-size: 0.9rem;
    line-height: 1.6;
    white-space: pre-wrap;
    word-wrap: break-word;
    word-break: break-word;
    overflow-wrap: break-word;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    margin: 0;
    margin-left: 20px;
    padding: 0;
    background: transparent;
    border: none;
    max-width: calc(100% - 20px);
}

/* Purchase Success Banner */
.purchase-success-banner {
    background: rgba(5, 150, 105, 0.5);
    color: rgb(16, 185, 129);
    padding: 12px 20px;
    text-align: center;
    font-weight: 600;
    font-size: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 30px 40px;
    border-radius: 4px;
    border: 1px solid rgb(16, 185, 129);
    box-shadow: 0 4px 12px rgba(5, 150, 105, 0.3);
}

/* Fixed Bottom Player */
.fixed-player {
    position: fixed;
    bottom: 20px;
    left: 20px;
    right: 20px;
    background: rgba(40, 50, 80, 0.5);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    border-radius: 20px;
    padding: 20px 25px;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.fixed-player audio {
    display: none;
}

.player-info {
    text-align: center;
    color: white;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.player-controls-bottom {
    display: flex;
    align-items: center;
    justify-content: space-around;
    width: 100%;
    max-width: 400px;
    margin: 0 auto;
}

.control-btn-bottom {
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    color: #cbd5e0;
}

@media (hover: hover) and (pointer: fine) {
    .control-btn-bottom:hover:not(:disabled) {
        background: rgba(255, 255, 255, 0.1);
        color: white;
    }
}

.control-btn-bottom:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.control-btn-bottom:focus {
    outline: none;
    background: transparent;
}

.control-btn-bottom:active {
    background: rgba(255, 255, 255, 0.15);
}

.control-btn-bottom svg {
    width: 26px;
    height: 26px;
}

.play-pause-btn-bottom {
    background: #667eea;
    border: none;
    border-radius: 50%;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    color: white;
    box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
}

.play-pause-btn-bottom:hover {
    background: #5568d3;
    transform: scale(1.05);
}

.play-pause-btn-bottom svg {
    width: 32px;
    height: 32px;
}

.player-progress-bottom {
    display: flex;
    align-items: center;
    gap: 10px;
}

.player-progress-bottom span {
    color: #cbd5e0;
    font-size: 12px;
    min-width: 40px;
    text-align: center;
}

.progress-bar-bottom {
    flex: 1;
    height: 6px;
    background: rgba(255, 255, 255, 0.25);
    border-radius: 10px;
    cursor: pointer;
    position: relative;
    /* The bar is dragged, so the browser must not claim the gesture for scrolling. */
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
}

/* A 6px-tall bar is a poor target for a finger; this widens the grabbable band to 28px
   without changing how the bar looks. */
.progress-bar-bottom::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -11px;
    bottom: -11px;
}

.progress-bar-bottom:hover {
    height: 8px;
}

.progress-fill-bottom {
    height: 100%;
    background: #667eea;
    border-radius: 10px;
    width: 0%;
    transition: width 0.1s linear;
    position: relative;
}

/* Knob at the play head, so the bar reads as draggable rather than merely tappable. */
.progress-fill-bottom::after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    transform: translate(50%, -50%);
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
    transition: width 0.12s ease, height 0.12s ease;
}

/* While dragging: a bigger knob, and no width easing — the fill has to track the finger
   exactly, and a 0.1s transition reads as lag. */
.progress-bar-bottom.scrubbing .progress-fill-bottom { transition: none; }
.progress-bar-bottom.scrubbing .progress-fill-bottom::after {
    width: 17px;
    height: 17px;
}

/* Footer */
footer {
    text-align: center;
    margin-top: 40px;
    color: #94a3b8;
    padding: 30px 0 20px;
    font-size: 14px;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.footer-links {
    margin-top: 8px;
    font-size: 12px;
}

.footer-links a {
    color: #94a3b8;
    text-decoration: none;
    border-bottom: 1px solid rgba(148, 163, 184, 0.3);
}

.footer-links a:hover {
    color: #cbd5e0;
    border-bottom-color: #cbd5e0;
}

.footer-links-sep {
    margin: 0 8px;
    color: #64748b;
}

/* Responsive Design */
@media (max-width: 768px) {
    .container {
        padding: 10px;
    }

    header h1 {
        font-size: 1.5rem;
    }

    .auth-container, .payment-container, .player-container {
        padding: 20px 15px;
        margin: 0 auto;
        border-radius: 8px;
    }

    .payment-container h2, .player-container h2 {
        font-size: 1.5rem;
    }

    .payment-container p {
        font-size: 14px;
    }
    
    .track-info {
        flex-direction: column;
        text-align: center;
    }
    
    .track-artwork {
        margin-right: 0;
        margin-bottom: 15px;
    }
}

/* Library Styles */
.library-container {
    background: rgba(30, 40, 70, 0.9);
    padding: 20px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
}

.library-container h2 {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
    color: white;
    font-weight: 700;
}

.library-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    margin-top: 30px;
}

.library-item {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 24px;
    background: rgba(30, 40, 70, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    transition: all 0.2s ease;
}

.library-item:hover {
    background: rgba(30, 40, 70, 0.9);
    transform: translateY(-1px);
    border-color: rgba(255, 255, 255, 0.2);
}

.library-item-icon {
    flex-shrink: 0;
}

.library-item-icon svg {
    width: 60px;
    height: 60px;
    color: #667eea;
}

.library-item-image {
    flex-shrink: 0;
    width: 60px;
    height: 60px;
    overflow: hidden;
    border-radius: 8px;
    background: rgba(0,0,0,0.3);
}

.library-item-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.library-item-details {
    flex: 1;
    min-width: 0;
}

.library-item h3 {
    margin: 0 0 8px 0;
    color: white;
    font-size: 1.2rem;
}

.library-item .description {
    color: #cbd5e0;
    margin: 4px 0;
    font-size: 0.95rem;
}

.library-item .meta {
    color: #94a3b8;
    font-size: 14px;
    margin: 8px 0 0 0;
}

.library-button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    text-decoration: none;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 500;
    transition: all 0.2s ease;
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.library-button:hover {
    background: rgba(255, 255, 255, 0.2);
    border-color: #cbd5e0;
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

.library-button svg {
    width: 18px;
    height: 18px;
}

.header-nav {
    display: flex;
    justify-content: left;
    gap: 10px;
    flex-wrap: wrap;
        text-align: center;

}

/* Utility Classes */
.hidden {
    display: none;
}

.text-muted {
    color: #94a3b8;
}

.text-muted-dark {
    color: #64748b;
}

.text-small {
    font-size: 14px;
}

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

.icon-sm {
    width: 16px;
    height: 16px;
}

.icon-md {
    width: 20px;
    height: 20px;
}

.icon-lg {
    width: 60px;
    height: 60px;
}

.icon-xl {
    width: 80px;
    height: 80px;
}

.spacing-top-sm {
    margin-top: 10px;
}

.spacing-top-md {
    margin-top: 20px;
}

.spacing-top-lg {
    margin-top: 30px;
}

.spacing-top-xl {
    margin-top: 40px;
}

.spacing-bottom-lg {
    margin-bottom: 30px;
}

/* Component Classes */
.error-page-container {
    text-align: center;
    padding: 60px 20px;
    background: rgba(15, 15, 30, 0.9);
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    margin-bottom: 30px;
}

.error-icon {
    width: 80px;
    height: 80px;
    margin: 0 auto 30px;
    color: #ef4444;
}

.error-page-container h2 {
    margin-bottom: 20px;
    color: white;
}

.error-page-container p {
    font-size: 18px;
    color: #cbd5e0;
    margin-bottom: 30px;
}

.warning-box {
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.3);
    border-radius: 8px;
    padding: 20px;
    margin: 30px 0;
    text-align: left;
}

.warning-box-title {
    margin-top: 0;
    color: #fbbf24;
    display: flex;
    align-items: center;
}

.warning-box-title svg {
    width: 20px;
    height: 20px;
    vertical-align: middle;
    margin-right: 8px;
}

.warning-box-text {
    margin: 10px 0 0;
    color: #fcd34d;
}

.empty-state {
    text-align: center;
    padding: 60px 20px;
    color: #999;
}

.empty-state-icon {
    width: 60px;
    height: 60px;
    margin: 0 auto 20px;
}

@media (max-width: 768px) {
    .library-item {
        flex-direction: column;
        text-align: center;
    }

    .library-item-icon svg {
        width: 50px;
        height: 50px;
    }

    .library-container {
        /* padding: 20px; */
    }
}
/* ── QR-landing intro screen (index.html step 1, before the phone ask) ── */
/* No entrance animation on the intro→phone swap: .auth-container carries a
   backdrop-filter, and animating content inside a blurred panel jitters on iOS
   (see docs/ios_animation_compositing.md). The swap is an instant class toggle. */
.intro-title {
    justify-content: center !important;
    text-align: center;
    font-family: 'Outfit', 'Rubik', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 2rem !important;
    font-weight: 800 !important;
    line-height: 1.15;
    letter-spacing: -0.3px;
    /* Tight to the subtitle below it — the two read as one block. */
    margin-bottom: 8px;
}

/* The one-line promise under the intro title. Replaces the message that used
   to sit under the CTA, so the pitch is made before the fan reaches the
   button rather than after it. */
.intro-subtitle {
    text-align: center;
    color: #cbd5e0;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.45;
    margin-bottom: 20px !important;
}

.intro-photos {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0 0 20px;
    scrollbar-width: none;
}

.intro-photos::-webkit-scrollbar {
    display: none;
}

.intro-photos img {
    width: 84px;
    height: 84px;
    object-fit: cover;
    border-radius: 8px;
    flex-shrink: 0;
    background: rgba(0, 0, 0, 0.3);
}

/* Pill CTA, sized to its label (plus comfortable padding) and centered —
   mirrors the id.music "Log in" button rather than a full-width bar. */
.intro-cta {
    display: block;
    width: fit-content;
    min-width: 200px;
    max-width: 100%;
    margin: 0 auto;
    padding-left: 56px;
    padding-right: 56px;
    border-radius: 999px;
}

/* ── index.html step 2 (#phone-screen): the event, restated ──
   The poster leads, so the fan can see what they are giving a number for. 66%
   of the card's content width, centred, square corners to match the mockup's
   artwork. */
.phone-screen-poster {
    display: block;
    width: 66%;
    max-width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    margin: 0 auto 18px;
    border: 1.5px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.phone-screen-title {
    justify-content: center !important;
    text-align: center;
    font-size: 1.5rem !important;
    line-height: 1.2;
    margin-bottom: 8px !important;
}
.phone-screen-description {
    text-align: center;
    color: #cbd5e0;
    font-size: 15px;
    line-height: 1.45;
    margin-bottom: 24px !important;
}

/* verify page: "A verification code has just been sent", centred above the
   digit boxes. Replaces the old explainer pair, which no template uses now. */
.verify-sent-note {
    text-align: center;
    color: #cbd5e0;
    font-size: 15px;
    line-height: 1.5;
    margin-top: 0;
    margin-bottom: 20px !important;
}

/* ── Phone-mockup preview player (partials/phone_preview.html) ──
   A scoped copy of the admin context_info live preview. Kept separate on
   purpose: the admin markup is wired to its live-preview JS and must not
   change underneath it. All rules are namespaced under .phone-preview-wrap. */
.phone-preview-wrap {
    display: flex;
    justify-content: center;
    margin: 0 auto 22px;
}
/* Viewport fit: index.js measures the intro screen and sets an inline height on
   .phone-preview-wrap plus an inline scale on .phone-frame, so the whole intro
   (title → phone → CTA → message) fits without scrolling. */
#intro-screen .phone-preview-wrap {
    align-items: flex-start;
    overflow: visible;
}
/* 0.3s entrance on page load. Animated on the wrapper (its transform is free —
   the fit-to-viewport scale lives on .phone-frame's inline style, and nested
   transforms compose). Skipped for reduced-motion users. */
@media (prefers-reduced-motion: no-preference) {
    #intro-screen .phone-preview-wrap {
        animation: phone-preview-in 0.3s ease-out;
        will-change: transform, opacity;
    }
}
@keyframes phone-preview-in {
    from { opacity: 0; transform: scale(0.92); }
    to   { opacity: 1; transform: none; }
}
/* index.js adds this while the entrance runs: animating inside a
   backdrop-filter panel jitters on iOS (docs/ios_animation_compositing.md),
   so the card's blur is off for the animation's duration. */
.auth-container.blur-off,
.player-container.blur-off,
.fixed-player.blur-off {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.phone-preview-wrap .phone-frame {
    position: relative;
    transform-origin: top center;
    flex-shrink: 0;
    width: 220px;
    height: 476px;
    background: #1a1a1e;
    border-radius: 34px;
    border: 1px solid #3a3a3c;
    /* The last three layers are the halo: a bright bloom radiating evenly on all
       four sides (0 offset, large blur) that lifts the card behind the phone,
       tinted with the #667eea accent. Brightest tight against the frame, fading
       outward. The 22px drop shadow underneath keeps the phone's downward
       weight so it reads as lit, not merely suspended. */
    box-shadow:
        0 0 0 2px #111,
        0 0 0 3px #3a3a3c,
        0 22px 48px rgba(0, 0, 0, 0.55),
        0 0 40px 4px rgba(150, 170, 255, 0.30),
        0 0 90px 20px rgba(122, 143, 240, 0.22),
        0 0 170px 55px rgba(102, 126, 234, 0.16),
        inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.phone-preview-wrap .phone-btn {
    position: absolute;
    background: #2c2c2e;
    border: 1px solid #444;
}
.phone-preview-wrap .phone-btn-vol-up   { left: -4px; top: 82px;  width: 4px; height: 26px; border-radius: 3px 0 0 3px; }
.phone-preview-wrap .phone-btn-vol-down { left: -4px; top: 116px; width: 4px; height: 26px; border-radius: 3px 0 0 3px; }
.phone-preview-wrap .phone-btn-silent   { left: -4px; top: 53px;  width: 4px; height: 19px; border-radius: 3px 0 0 3px; }
.phone-preview-wrap .phone-btn-power    { right: -4px; top: 100px; width: 4px; height: 46px; border-radius: 0 3px 3px 0; }
.phone-preview-wrap .phone-screen {
    position: absolute;
    inset: 6px;
    border-radius: 28px;
    background: #1c2340;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
/* One-shot shine: a soft diagonal highlight sweeping across the screen. It does
   NOT run on load — index.js adds .shine-once on the fan's first touch or
   scroll, and never again for the life of the page. Drawn as a pseudo-element
   on .phone-screen (which already clips at the 28px radius) and animated with
   its own transform — .phone-frame's transform is spoken for by index.js's
   fit-to-viewport scale, so the sweep must not live there.
   pointer-events: none keeps it off the mockup's hit area. */
.phone-preview-wrap .phone-screen::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 5;
    pointer-events: none;
    background: linear-gradient(
        105deg,
        transparent 38%,
        rgba(255, 255, 255, 0.06) 45%,
        rgba(255, 255, 255, 0.13) 50%,
        rgba(255, 255, 255, 0.06) 55%,
        transparent 62%
    );
    /* Wider than the screen so the band is fully offstage at both ends. */
    transform: translateX(-140%);
    opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
    /* Gated on the class, so the sweep starts when JS adds it — not on load. */
    #intro-screen .phone-preview-wrap.shine-once .phone-screen::after {
        animation: phone-shine 1.1s cubic-bezier(0.33, 0, 0.5, 1) both;
        will-change: transform;
    }
}
@keyframes phone-shine {
    from { transform: translateX(-140%); opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    to   { transform: translateX(140%); opacity: 0; }
}
/* ── Tap-to-expand the poster/title/subtitle ──
   The artwork group is clipped twice over (.phone-content and .phone-screen are
   both overflow:hidden), so it cannot grow out of the mockup in place. Instead
   index.js clones the group into this overlay, positioned over the card, and
   FLIPs it from the group's on-screen rect to a target 80% of the card's width.
   The original is hidden meanwhile so the two never both show.

   The overlay also carries .phone-preview-wrap, because every rule for the
   artwork/title/subtitle is scoped under that class and a clone without it
   would lose its sizing entirely — so this must undo that class's own layout:
   the margin, the flex centring, and the load-in animation all belong to the
   in-page mockup, not to the clone. */
.phone-expand-overlay {
    position: absolute;
    z-index: 40;
    /* Clickable: tapping the grown poster is what shrinks it again. */
    pointer-events: auto;
    cursor: pointer;
    transform-origin: top left;
    transition: transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: transform;
    display: block;
    margin: 0;
    animation: none;
}
/* Dim the card behind the expanded art so it reads as lifted off the page. */
.phone-expand-scrim {
    position: absolute;
    inset: 0;
    z-index: 39;
    /* Catches taps beside the grown poster, which also dismiss it. */
    pointer-events: auto;
    background: rgba(10, 14, 30, 0.55);
    opacity: 0;
    transition: opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.phone-expand-scrim.visible { opacity: 1; }
/* The source group, hidden for the duration of the expansion. */
.phone-preview-wrap .phone-artwork-group.expanding { visibility: hidden; }
/* The clone's own text scales with the group, so it needs no size overrides —
   only the artwork's shadow is deepened to match its new size. */
.phone-expand-overlay .phone-artwork { box-shadow: 0 18px 50px rgba(0, 0, 0, 0.6); }
/* The mockup advertises that it is tappable. */
#intro-screen .phone-preview-wrap .phone-artwork-group { cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
    .phone-expand-overlay, .phone-expand-scrim { transition-duration: 1ms; }
}
.phone-preview-wrap .phone-island {
    position: absolute;
    top: 9px;
    left: 50%;
    transform: translateX(-50%);
    width: 76px;
    height: 22px;
    background: #000;
    border-radius: 11px;
    z-index: 10;
}
.phone-preview-wrap .phone-statusbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 15px 2px;
    font-size: 9px;
    font-weight: 700;
    color: #fff;
    flex-shrink: 0;
    letter-spacing: 0.3px;
    position: relative;
    z-index: 5;
}
/* The status-bar colon blinks the way a clock's does: a hard on/off every
   1000ms, no fade. Opacity rather than visibility or content, so the digits
   either side never move. */
.phone-preview-wrap .phone-colon {
    /* 1000ms intervals: a 2s cycle, lit for one second and dark for the next. */
    animation: phoneColonBlink 2s linear infinite;
}
@keyframes phoneColonBlink {
    0%,     49.99% { opacity: 1; }
    50%,    100%   { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .phone-preview-wrap .phone-colon { animation: none; }
}

.phone-preview-wrap .phone-statusbar-icons { display: flex; align-items: center; gap: 3px; }
.phone-preview-wrap .phone-content {
    flex: 1;
    /* Frame of reference for the level meter, which is placed against the bottom
       of this box. Without it the meter anchors to .phone-screen and stands over
       the player bar instead of the song list. */
    position: relative;
    /* Static mock: clip rather than scroll, so the padded song list fills the
       screen edge-to-edge and stray touches can't scroll inside the mockup. */
    overflow: hidden;
    padding: 9px 14px 6px;
    scrollbar-width: none;
}
.phone-preview-wrap .phone-content::-webkit-scrollbar { display: none; }
.phone-preview-wrap .phone-artwork {
    width: 146px;
    height: 146px;
    margin: 0 auto 10px;
    /* Square corners on purpose — the poster reads as album art, not a chip. */
    overflow: hidden;
    border: 1.5px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.phone-preview-wrap .phone-artwork img { width: 100%; height: 100%; object-fit: cover; display: block; }
.phone-preview-wrap .phone-artwork-placeholder { color: rgba(255, 255, 255, 0.18); }
.phone-preview-wrap .phone-artwork-placeholder svg { width: 40px; height: 40px; }
.phone-preview-wrap .phone-title {
    color: #ffffff;
    font-size: 15px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 4px;
    line-height: 1.3;
}
.phone-preview-wrap .phone-subtitle {
    color: #a0aec0;
    font-size: 13px;
    text-align: center;
    margin-bottom: 10px;
    line-height: 1.4;
}
.phone-preview-wrap .phone-songs { margin-bottom: 9px; }
.phone-preview-wrap .phone-song-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 7px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.04);
    margin-bottom: 3px;
}
.phone-preview-wrap .phone-song-num { font-size: 7px; color: rgba(255, 255, 255, 0.25); width: 11px; text-align: center; }
/* Running time, right-aligned after the name (which flexes to fill). */
.phone-preview-wrap .phone-song-time {
    font-size: 7px;
    color: rgba(255, 255, 255, 0.3);
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}
.phone-preview-wrap .phone-song-bar { flex: 1; height: 4px; background: rgba(255, 255, 255, 0.07); border-radius: 2px; }
.phone-preview-wrap .phone-song-name {
    flex: 1;
    font-size: 9.5px;
    color: rgba(255, 255, 255, 0.75);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
}
.phone-preview-wrap .phone-song-bar.short { max-width: 55%; }
.phone-preview-wrap .phone-song-bar.med   { max-width: 75%; }
.phone-preview-wrap .phone-player {
    background: rgba(20, 28, 60, 0.97);
    border-top: 1px solid rgba(255, 255, 255, 0.05);
    padding: 5px 12px 2px;
    flex-shrink: 0;
}
/* Artist name, centered above the timeline. Replaces the old thumbnail +
   song-title row — at this mockup scale the artwork read as clutter and the
   artist is the thing worth naming. */
.phone-preview-wrap .phone-player-artist {
    font-size: 8px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
    text-align: center;
    margin-bottom: 5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.phone-preview-wrap .phone-player-progress {
    height: 2px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 1px;
    margin-bottom: 5px;
    overflow: hidden;
}
/* Rest position is 32%. Scroll-scrubbing (index.js) drives --scrub, a multiplier
   on that width, via scaleX rather than animating `width` — a transform stays
   off the layout path, so a scroll frame costs nothing. transform-origin:left
   keeps the bar growing from its start, like a playhead. */
.phone-preview-wrap .phone-player-progress-fill {
    width: 32%;
    height: 100%;
    background: #667eea;
    border-radius: 1px;
    transform-origin: left center;
    transform: scaleX(var(--scrub, 1));
}
/* Added by index.js once scrubbing stops: the glide back to the rest position.
   Absent while dragging so the bar tracks the scroll 1:1 with no lag. */
.phone-preview-wrap .phone-player-progress-fill.gliding {
    transition: transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.phone-preview-wrap .phone-player-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding-bottom: 2px;
}
.phone-preview-wrap .phone-ctrl { color: rgba(255, 255, 255, 0.5); display: flex; }
.phone-preview-wrap .phone-ctrl svg { display: block; }
/* The disc and glyph are drawn inside the SVG itself, so this only needs to
   size it and keep it from being stretched by the flex row. */
.phone-preview-wrap .phone-play-btn {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    display: block;
}

/* ── Mockup playback state ────────────────────────────────────────────────
   Both glyphs are in the SVG; which one shows is decided here, so the toggle
   is a single class on the wrapper and nothing has to rewrite markup. */
.phone-preview-wrap .phone-play-btn { cursor: pointer; }
/* The button is focusable (role=button, tabindex) so it can be used from a
   keyboard — but a tap must not leave a square ring around a round button.
   Suppress the ring for pointer focus and keep it for keyboard focus only. */
.phone-preview-wrap .phone-play-btn:focus { outline: none; }
.phone-preview-wrap .phone-play-btn:focus-visible {
    outline: 2px solid #667eea;
    outline-offset: 2px;
    border-radius: 50%;
}
.phone-preview-wrap .phone-glyph-pause { display: none; }
.phone-preview-wrap.playing .phone-glyph-play { display: none; }
.phone-preview-wrap.playing .phone-glyph-pause { display: block; }

/* ── The level meter ──────────────────────────────────────────────────────
   Five bars standing over the song list, only while playing. Absolutely placed
   so covering the rows costs nothing in layout and hiding it costs nothing
   either. The 68px is measured on this layout: it is the distance from the
   bottom of the content box up to the top of the FOURTH row, so a bar at full
   stretch reaches exactly there. Re-measure it if the player bar's height
   changes — the content box is flex:1, so it absorbs the difference.
   (Rows are 24.2px apart, so each row up or down is one row's pitch.) */
.phone-preview-wrap .phone-meter {
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 0;
    height: 68px;
    align-items: flex-end;
    justify-content: center;
    gap: 10px;
    pointer-events: none;      /* the rows underneath stay tappable */
    /* Plainly shown or not shown. A fade would need visibility to lag opacity,
       which makes "is it hidden?" a question with a different answer depending
       on when you ask — not worth it for an overlay that has no layout to
       protect. */
    display: none;
}
.phone-preview-wrap.playing .phone-meter { display: flex; }
.phone-preview-wrap .phone-meter span {
    flex: 1 1 0;
    max-width: 26px;
    height: 100%;
    border-radius: 4px 4px 2px 2px;
    background: linear-gradient(180deg, rgba(138, 155, 255, 0.55) 0%, rgba(102, 126, 234, 0.38) 100%);
    transform: scaleY(0.12);
    transform-origin: center bottom;
    box-shadow: 0 0 10px rgba(102, 126, 234, 0.18);
}
/* Staggered durations and delays, as on the sell sheet: bars sharing one clock
   read as a row of bars, not as audio. */
.phone-preview-wrap.playing .phone-meter span {
    animation: phoneMeterBar ease-in-out infinite alternate;
}
/* The outer pair is held shorter — full stretch reaches the FIFTH row rather
   than the fourth (43.4px of the box's 68), so the group reads as a meter with
   a peak in the middle instead of a flat wall. */
.phone-preview-wrap .phone-meter span:nth-child(1),
.phone-preview-wrap .phone-meter span:nth-child(5) { height: 64%; }

.phone-preview-wrap.playing .phone-meter span:nth-child(1) { animation-duration: 0.52s; animation-delay: 0.10s; }
.phone-preview-wrap.playing .phone-meter span:nth-child(2) { animation-duration: 0.43s; animation-delay: 0.34s; }
.phone-preview-wrap.playing .phone-meter span:nth-child(3) { animation-duration: 0.61s; animation-delay: 0.02s; }
.phone-preview-wrap.playing .phone-meter span:nth-child(4) { animation-duration: 0.47s; animation-delay: 0.26s; }
.phone-preview-wrap.playing .phone-meter span:nth-child(5) { animation-duration: 0.56s; animation-delay: 0.16s; }

@keyframes phoneMeterBar {
    0%   { transform: scaleY(0.12); opacity: 0.55; }
    50%  { opacity: 0.85; }
    100% { transform: scaleY(1);    opacity: 0.70; }
}

@media (prefers-reduced-motion: reduce) {
    .phone-preview-wrap.playing .phone-meter span { animation: none; transform: scaleY(0.55); }
}

.phone-preview-wrap .phone-home {
    display: flex;
    justify-content: center;
    padding: 4px 0 6px;
    flex-shrink: 0;
}
.phone-preview-wrap .phone-home-bar {
    width: 66px;
    height: 4px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 2px;
}

/* ── Offer page (post-PIN pre-purchase pitch, offer.html) ── */
.offer-price {
    text-align: center;
    color: white;
    font-family: 'Outfit', 'Rubik', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 22px;
    font-weight: 800;
    line-height: 1.2;
    margin-bottom: 4px !important;
}
/* "No Subscription" — green, because it is the reassurance on this page, not
   another grey caption. Light enough to clear contrast on the dark card.
   Selector is doubled up: plain `.offer-price-note` loses to `.auth-container p`
   (0,1,1 beats 0,1,0), which paints every paragraph in the card grey. */
.auth-container .offer-price-note,
.offer-price-note {
    text-align: center;
    color: #68d391;
    font-size: 14px;
    font-weight: 400;
    margin-bottom: 22px !important;
}

/* ── Release pages (release_celebrate.html / release_offer.html) ── */
.celebrate-sub {
    text-align: center;
    color: #cbd5e0;
    font-size: 16px;
    line-height: 1.5;
    margin-bottom: 24px !important;
}
/* Full-viewport confetti overlay, above the card, never intercepting taps.
   confetti.js removes it when the burst ends. */
.confetti-canvas {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    /* Above the player's transport bar (.fixed-player, z-index 1000): pieces
       falling past it must stay visible to the bottom of the screen — sinking
       behind its frosted glass reads as the confetti fading out. Still under
       toasts/modals (10000+). */
    z-index: 1100;
}
