/* Shared audio player look (play/pause button, seek bar, time labels) -
   used by both the karaoke frame's floating overlay (#q-frame, see
   karaoke.css) and the plain inline player on ayah_detail.html
   (.q-player-inline, see _audio_player.html). Loaded on every page that
   embeds either one (see extra_head in surah_detail.html/ayah_detail.html)
   instead of living inside karaoke.css, which is surah-page-only. A page
   needing just the inline player (ayah_detail) has no reason to load
   karaoke.css at all. Reuses --app-bg/--app-text/--app-sub/--app-link
   etc, defined in staticsrc/input.css's :root and always loaded first
   via base.html.

   Focus-visible on both the button and the range already comes from the
   site-wide a/button/select/input rule in input.css, nothing extra
   needed here. */
.q-play-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 9999px;
    border: none;
    /* Theme-derived scrim (not a new arbitrary color) so it reads on
       both light and dark backgrounds the same way the rest of these
       tokens do. */
    background: color-mix(in srgb, var(--app-text) 20%, transparent);
    color: var(--app-text);
}
/* The `hidden` attribute (_ayah_card.html/_surah_card.html - a play
   button with no audio_url still renders, just hidden) needs this
   explicitly - the browser's own built-in `[hidden] { display: none }`
   rule has the *same* specificity as .q-play-btn's own `display:
   inline-flex` above, and this stylesheet loads after the browser
   default, so without this override the button stayed visible AND
   clickable (an empty data-audio-url) despite `hidden` being set. */
.q-play-btn[hidden] {
    display: none;
}
.q-play-btn:hover {
    background: color-mix(in srgb, var(--app-text) 28%, transparent);
}
.q-page-ayah .q-play-btn {
    border-radius: 0;
    background: none;
}
.q-page-ayah .q-play-btn:hover {
    background: none;
}
.q-icon {
    width: 1.75rem;
    height: 1.75rem;
    fill: currentColor;
}
/* Swapped via a class on the button itself (__qBindPlayer in player.js
   toggles .is-playing), not the [hidden] attribute on each icon - one
   class flip is simpler to reason about/debug than two independent
   hidden-property writes staying in sync. */
.q-play-btn .q-icon-pause {
    display: none;
}
.q-play-btn.is-playing .q-icon-play {
    display: none;
}
.q-play-btn.is-playing .q-icon-pause {
    display: block;
}
.q-time {
    font-variant-numeric: tabular-nums;
    color: var(--app-sub);
    font-size: 0.8rem;
    min-width: 2.25em;
}
.q-seek {
    flex: 1;
    accent-color: var(--app-link);
    cursor: pointer;
}
/* ayah_detail.html's plain inline player - sits in normal flex flow at
   its natural size, no absolute positioning (unlike #q-frame's
   overlaid version, karaoke.css). */
.q-player-inline {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}
.q-player-inline .q-play-btn {
    width: 2.5rem;
    height: 2.5rem;
}
/* DOM order is button-first (correct for an LTR UI - button leads at the
   left). Under an RTL UI (html[dir="rtl"], set from LANGUAGE_BIDI in
   base.html) flex would otherwise put that same first-DOM element at the
   right instead, so push it to the end of the row with `order` - lands
   back at the left, same physical side as LTR, matching how a reader's
   own muscle memory for "where's the play button" doesn't flip just
   because the UI language did. */
html[dir="rtl"] .q-player-inline .q-play-btn {
    order: 1;
}
.q-player-inline .q-icon {
    width: 1.1rem;
    height: 1.1rem;
}

/* Compact per-card play button (_ayah_card.html - concordance/similar/
   exact-match lists on the racine/lemme/mot/verset pages). Same look as
   the other players (.q-play-btn/.is-playing/.q-icon), just smaller to
   fit a card header instead of a full player bar. */
.q-card-play-btn {
    width: 2rem;
    height: 2rem;
}
.q-card-play-btn .q-icon {
    width: 1rem;
    height: 1rem;
}
/* Encore plus discret sur la ligne titre (_ayah_card.html, résultats
   style Google) - le titre doit dominer visuellement, pas les boutons.
   Double classe (spécificité 2) pour gagner sur .q-card-play-btn ci-dessus
   sans dépendre de l'ordre des règles. */
.q-card-play-btn.q-card-play-btn--sm {
    width: 1.5rem;
    height: 1.5rem;
}
.q-card-play-btn--sm .q-icon {
    width: 1.125rem;
    height: 1.125rem;
}
.q-card-play-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Loading state (reciter switch - see __qUpdateCardAudioUrl/
   htmx:beforeRequest in player.js): spinner in place of the play/pause
   icon, not just a disabled/dimmed button - a state change with no
   visible signal of what's happening would look broken rather than
   "wait a moment". prefers-reduced-motion is already handled globally
   (input.css forces every animation to ~0 duration for it), no extra
   rule needed here. */
.q-card-play-btn .q-icon-loading {
    display: none;
    width: 1rem;
    height: 1rem;
    border: 2px solid color-mix(in srgb, var(--app-text) 30%, transparent);
    border-top-color: var(--app-text);
    border-radius: 50%;
    animation: q-spin 0.7s linear infinite;
}
.q-card-play-btn.is-loading .q-icon-play,
.q-card-play-btn.is-loading .q-icon-pause {
    display: none;
}
.q-card-play-btn.is-loading .q-icon-loading {
    display: block;
}
@keyframes q-spin {
    to { transform: rotate(360deg); }
}

/* Library (favoris) toggle (_ayah_card.html) - same pill chrome as
   .q-card-play-btn, icon swap driven by aria-pressed (not a class) since
   quran-store.js's delegated handler already reads/writes that attribute
   for its own state - one source of truth instead of two. */
.q-lib-toggle-btn .q-icon-lib-on {
    display: none;
}
.q-lib-toggle-btn[aria-pressed="true"] .q-icon-lib-off {
    display: none;
}
.q-lib-toggle-btn[aria-pressed="true"] .q-icon-lib-on {
    display: block;
}
/* Text variant (_ayah_content.html's action row, unlike the icon-only
   card button) - same aria-pressed-driven swap, visible label included
   so the state isn't icon-color alone. */
.q-lib-toggle-btn .q-lib-label-remove {
    display: none;
}
.q-lib-toggle-btn[aria-pressed="true"] .q-lib-label-add {
    display: none;
}
.q-lib-toggle-btn[aria-pressed="true"] .q-lib-label-remove {
    display: inline;
}

/* Copy-link button (_ayah_content.html) - same icon-swap-for-state
   pattern as play/pause and the library toggle above, so "copied"
   feedback is visible to sighted readers too, not just the sr-only
   status span announcing it to screen readers. */
.copy-link-btn .q-icon-copied {
    display: none;
}
.copy-link-btn.is-copied .q-icon-copy {
    display: none;
}
.copy-link-btn.is-copied .q-icon-copied {
    display: block;
}

/* Ayah card's own "..." menu, "Écouter"/"Pause" item (_ayah_card.html,
   own report: "on va le faire pour les Ayah card... même famille de
   menu que /ar/s/") - same icon/label-swap technique as
   [data-q-surah-menu-play-toggle] (surah_list.html, page-scoped since
   that menu only ever lives there), generic name/global stylesheet here
   since this card renders on every page that loads player.css (search,
   ayah_detail, word_detail, lemma_detail, root_detail...). li:has()
   would need every one of those pages agreeing on the same ancestor
   shape - a JS-driven .is-playing class on this button directly
   (__qBindCardPlayer, player.js, real play/pause events) sidesteps that
   entirely, same reasoning as the surah menu's own comment. */
[data-q-card-menu-play-toggle] .q-icon-pause {
    display: none;
}
[data-q-card-menu-play-toggle].is-playing .q-icon-play {
    display: none;
}
[data-q-card-menu-play-toggle].is-playing .q-icon-pause {
    display: block;
}
/* Barre play/next du verset en cours (_ayah_transport_row.html,
   ayah-transport.js) - même toggle icône générique que
   [data-q-card-menu-play-toggle] ci-dessus. */
[data-q-transport-play] .q-icon-pause {
    display: none;
}
[data-q-transport-play].is-playing .q-icon-play {
    display: none;
}
[data-q-transport-play].is-playing .q-icon-pause {
    display: block;
}
[data-q-card-menu-play-toggle] .q-label-pause {
    display: none;
}
[data-q-card-menu-play-toggle].is-playing .q-label-play {
    display: none;
}
[data-q-card-menu-play-toggle].is-playing .q-label-pause {
    display: inline;
}

/* Ayah card: clic sur toute la carte = play/pause (own report: "quand je
   clique sur Ayah card ça doit play/pause"), fond "en cours de lecture"
   + hover, même traitement que la ligne sourate (/ar/s,
   .q-play-btn.is-playing/hover:bg-app-bg, surah_list.html) - le verset
   en cours n'a plus de "bouton" visible à teinter (data-slot="play-btn"
   est caché depuis le passage au menu "...", own report plus tôt), donc
   :has() sur la carte plutôt qu'une classe .is-playing/.q-play-btn
   directement visible ici. */
/* 0.75rem, pas 1rem (own bug trouvé: débordement horizontal mobile sur
   ayah_detail/root_detail/lemma_detail/word_detail/search - ces pages
   utilisent toutes px-3 (0.75rem) sur <main>, pas le px-4 (1rem) par
   défaut de base.html/home - un bleed de 1rem y dépassait le padding
   du conteneur de 4px de chaque côté, poussant la carte hors du
   viewport). 0.75rem reste sans danger même sur les pages en px-4 (le
   bleed est juste un peu moins "plein écran" là, jamais de débordement
   dans l'autre sens). */
[data-q-ayah-card] {
    margin-inline: -0.75rem;
    padding-inline: 0.75rem;
}
[data-q-ayah-card]:has([data-slot="play-btn"].is-playing) {
    background: color-mix(in srgb, var(--app-text) 6%, transparent);
    border-radius: 0.5rem;
}
[data-q-ayah-card][data-q-has-audio]:hover {
    cursor: pointer;
}

/* "En cours" icône égaliseur (own report: "ajoute le SVG que utilise la
   surah en cours de play... à côté du bouton data-q-card-menu-toggle") -
   même icône/animation que surah_list.html's own [data-slot="now-
   playing-icon"] (répétées, pas déménagées: cette page-là ne charge pas
   player.css, own commentaire là-bas), pour que les ayah cards en aient
   une copie sans dépendre de cette page. display:none par défaut, montré
   soit par .q-play-btn.is-playing (ligne sourate - l'icône y est nichée
   DANS le bouton play, structure que l'ayah card n'a pas) soit par
   :has() ci-dessous (l'ayah card ne peut pas nicher l'icône dans son
   propre bouton play, celui-là caché). */
[data-slot="now-playing-icon"] {
    display: none;
}
[data-q-ayah-card]:has([data-slot="play-btn"].is-playing) [data-slot="now-playing-icon"] {
    display: flex;
}
/* Barres façon égaliseur, décalées pour ne pas monter/descendre à
   l'unisson - transform (pas height) pour rester sur le compositeur
   GPU. Coupé sous prefers-reduced-motion (CLAUDE.md) : l'icône reste
   affichée immobile, le swap numéro/icône (ou le fond "en cours",
   ayah card) porte déjà le sens sans le mouvement. */
@media (prefers-reduced-motion: no-preference) {
    [data-slot="now-playing-icon"] svg path {
        transform-box: fill-box;
        transform-origin: center;
        animation: q-now-playing-bar 1s ease-in-out infinite;
    }
    [data-slot="now-playing-icon"] svg path:nth-child(1) { animation-delay: -0.9s; }
    [data-slot="now-playing-icon"] svg path:nth-child(2) { animation-delay: -0.6s; }
    [data-slot="now-playing-icon"] svg path:nth-child(3) { animation-delay: -0.2s; }
    [data-slot="now-playing-icon"] svg path:nth-child(4) { animation-delay: -0.8s; }
    [data-slot="now-playing-icon"] svg path:nth-child(5) { animation-delay: -0.4s; }
    [data-slot="now-playing-icon"] svg path:nth-child(6) { animation-delay: -0.1s; }
}
@keyframes q-now-playing-bar {
    0%, 100% { transform: scaleY(0.4); }
    50% { transform: scaleY(1); }
}
