#q-karaoke-lines {
    position: relative;
    scrollbar-width: none;
    mask-image: linear-gradient(to bottom, transparent, black 8%, black 88%, transparent);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 8%, black 88%, transparent);
    /* Hidden until karaoke.js finishes setting padding-top/bottom on
       #q-karaoke-track (needs frame.clientHeight) - without this, the
       first line briefly paints at scrollTop 0 then jumps down once the
       padding is applied. Revealed via .q-karaoke-ready. */
    opacity: 0;
}

#q-karaoke-lines.q-karaoke-ready {
    opacity: 1;
}

/* Same dim-while-loading treatment as mushaf.html's own #q-mushaf-slot
   (mushaf.css) - htmx toggles .htmx-request on #q-karaoke-lines itself
   via hx-indicator (surah_detail.html's prev/next/popover surah nav). */
#q-karaoke-lines.htmx-request #q-karaoke-track {
    opacity: 0.4;
}
@media (prefers-reduced-motion: no-preference) {
    #q-karaoke-track {
        transition: opacity 0.15s ease;
    }
}
/* Sibling of #q-karaoke-track, not a descendant, so the text dimming
   above doesn't dim this too - same reasoning as .q-mushaf-spinner. */
.q-surah-spinner {
    display: none;
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    color: var(--app-text);
}
#q-karaoke-lines.htmx-request .q-surah-spinner {
    display: flex;
}
@media (prefers-reduced-motion: no-preference) {
    .q-surah-spinner svg {
        animation: q-surah-spin 0.8s linear infinite;
    }
}
@keyframes q-surah-spin {
    to { transform: rotate(360deg); }
}

#q-karaoke-lines::-webkit-scrollbar {
    width: 0;
}

#q-karaoke-lines.q-scroll-active {
    scrollbar-width: thin;
}

#q-karaoke-lines.q-scroll-active::-webkit-scrollbar {
    width: 8px;
}

#q-karaoke-lines [data-q-ayah-number] {
    cursor: pointer;
    opacity: 1;
    filter: blur(0);
    /* Font-size stays fixed (text-3xl from the template) - the dim/
       active size change is a transform instead (below), so it never
       reflows the text (no rewrap = no line-count change) and never
       shifts the offsetTop of the lines after it, which the scroll
       math (reading-line position, last-line clamp) depends on. */
    transform: scale(1);
    transform-origin: right center;
    transition: opacity 0.5s ease, filter 0.5s ease, transform 0.5s ease, background-color 0.15s ease;
}

#q-karaoke-lines [data-q-ayah-number]:focus-visible {
    background-color: var(--q-karaoke-hover-bg, rgba(255, 255, 255, 0.06));
}

#q-karaoke-lines .q-karaoke-dim {
    opacity: 0.4;
    filter: blur(3px);
    transform: scale(0.8); /* 1.5rem / 1.875rem, same visual ratio as before */
}

@media (prefers-reduced-motion: reduce) {
    #q-karaoke-lines [data-q-ayah-number] {
        transition: none;
    }
}
