/* BAV — compléments au-dessus de Bootstrap 5 (le strict nécessaire). */

/* Pastille de couleur de tri (couleur du déposant, RG-27). */
.color-dot {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, 0.35);
    vertical-align: text-bottom;
}

/*
 * Frise des phases de l'événement (pilotage 1p).
 *
 * Trois marqueurs pour que la rangée se lise comme une progression et non
 * comme des boutons équivalents : un chevron de liaison entre les étapes, un
 * numéro d'ordre dans chaque pastille (« ✓ » une fois l'étape franchie), et
 * trois états visuellement distincts (franchie / en cours / à venir).
 *
 * Le chevron est un pseudo-élément du <li>, posé à côté de la pastille et non
 * dedans : le fond coloré est porté par `.phase-pill`, ce qui évite tout
 * positionnement absolu et laisse la frise passer à la ligne proprement.
 */
.phase-stepper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0;
    list-style: none;
    padding: 0;
    counter-reset: phase;
}

.phase-stepper li {
    display: flex;
    align-items: center;
    counter-increment: phase;
}

.phase-stepper li:not(:last-child)::after {
    content: "›";
    margin: 0 0.3rem;
    color: var(--bs-secondary-color);
    font-size: 1.15rem;
    line-height: 1;
    font-weight: 700;
}

.phase-stepper .phase-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    border: var(--bs-border-width) solid transparent;
    border-radius: var(--bs-border-radius);
    background: var(--bs-secondary-bg);
    font-size: 0.9rem;
}

/* Numéro d'ordre : dit « suite d'étapes » sans dépendre de la couleur. */
.phase-stepper .phase-pill::before {
    content: counter(phase);
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 50%;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    font-size: 0.75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Étape franchie : le numéro cède la place à une coche. */
.phase-stepper .is-done .phase-pill {
    background: var(--bs-success-bg-subtle);
    color: var(--bs-success-text-emphasis);
}

.phase-stepper .is-done .phase-pill::before {
    content: "✓";
    background: var(--bs-success);
    color: #fff;
}

.phase-stepper .is-done::after {
    color: var(--bs-success);
}

/* Étape en cours : la seule pleinement contrastée, et légèrement détachée. */
.phase-stepper .is-current .phase-pill {
    background: var(--bs-primary);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
}

.phase-stepper .is-current .phase-pill::before {
    background: rgba(255, 255, 255, 0.9);
    color: var(--bs-primary);
}

/* Étape à venir : contour pointillé et fond vide — rien n'y est acquis. */
.phase-stepper .is-todo .phase-pill {
    border-style: dashed;
    border-color: var(--bs-border-color);
    background: transparent;
    color: var(--bs-secondary-color);
}

.phase-stepper .is-todo .phase-pill::before {
    background: var(--bs-secondary-bg);
}

/*
 * Éclair de retour du scan (voir scan_feedback.js).
 *
 * L'opérateur regarde l'étiquette, pas l'écran : la couleur doit se voir du
 * coin de l'œil, donc elle prend tout le panneau et non un coin. Elle double
 * le signal sonore — un poste muet, ou un opérateur malentendant, garde
 * l'information.
 *
 * `prefers-reduced-motion` : on garde l'information (la couleur apparaît puis
 * disparaît) en supprimant la pulsation.
 */
.scan-flash-captured,
.scan-flash-success,
.scan-flash-error {
    animation: scan-flash 0.45s ease-out;
}

.scan-flash-captured {
    --scan-flash-color: rgba(13, 110, 253, 0.35);
}

.scan-flash-success {
    --scan-flash-color: rgba(25, 135, 84, 0.45);
}

.scan-flash-error {
    --scan-flash-color: rgba(220, 53, 69, 0.45);
}

@keyframes scan-flash {
    0% {
        box-shadow: 0 0 0 0 var(--scan-flash-color);
        background-color: var(--scan-flash-color);
    }
    100% {
        box-shadow: 0 0 0 0.75rem rgba(0, 0, 0, 0);
        background-color: transparent;
    }
}

@media (prefers-reduced-motion: reduce) {
    .scan-flash-captured,
    .scan-flash-success,
    .scan-flash-error {
        animation: scan-flash-static 0.45s steps(1, end);
    }

    @keyframes scan-flash-static {
        0%, 99% { background-color: var(--scan-flash-color); }
        100% { background-color: transparent; }
    }
}

/*
 * Viseur du scan par la caméra (RG-61).
 *
 * Largeur explicite, et ce n'est pas cosmétique : le viseur vit dans une
 * `.card`, que Bootstrap 5 rend `display:flex; flex-direction:column`. Un
 * `mx-auto` seul y transforme les marges automatiques en contrainte de
 * rétrécissement, et un div vide — ce qu'est le viseur avant l'ouverture de
 * la caméra — se retrouve large de 0 px. html5-qrcode mesure alors 0, insère
 * une vidéo de 0×0 et ne crée jamais son canvas d'analyse : la caméra
 * s'allume, on ne voit rien, et rien n'est jamais décodé.
 */
.scan-viewfinder {
    width: 100%;
    max-width: 320px;
    margin-inline: auto;
}

/*
 * Tooltip CSS pur (pas de JS Bootstrap) pour un bouton désactivé : un
 * <button disabled> a pointer-events:none, donc ni :hover ni title ne s'y
 * déclenchent — le hover est porté par le <span> englobant à la place.
 * Réutilise les variables --bs-tooltip-* (même rendu que .tooltip Bootstrap).
 */
.disabled-tooltip {
    position: relative;
    display: inline-block;
}

.disabled-tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translate(-50%, -0.3rem);
    width: max-content;
    max-width: var(--bs-tooltip-max-width, 200px);
    padding: var(--bs-tooltip-padding-y, 0.25rem) var(--bs-tooltip-padding-x, 0.5rem);
    background: var(--bs-tooltip-bg, #000);
    color: var(--bs-tooltip-color, #fff);
    border-radius: var(--bs-tooltip-border-radius, 0.375rem);
    font-size: var(--bs-tooltip-font-size, 0.765625rem);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease-out;
    z-index: 1080;
}

.disabled-tooltip:hover::after,
.disabled-tooltip:focus-within::after {
    opacity: 1;
}

/* Scan et encaissement : cibles tactiles généreuses sur mobile (wireframe 1j : ≥ 44 px). */
@media (max-width: 576px) {
    .touch-actions .btn,
    .touch-actions .form-control,
    .touch-actions .form-select {
        min-height: 44px;
    }
}

/*
 * Tables en cartes empilées sous 768 px (`.table-stack`).
 *
 * Une table large (9 colonnes pour les participations) ne tient pas sur un
 * téléphone : `.table-responsive` la rendait lisible au prix d'un défilement
 * horizontal, où l'on perd la ligne que l'on suit. Ici, chaque <tr> devient
 * une carte et chaque cellule affiche son intitulé, repris de `data-label`
 * (l'en-tête étant masqué).
 *
 * Le contenu des cellules reste dans le flux inline — le libellé est posé en
 * absolu, pas en flex : une cellule qui contient plusieurs éléments (un <br>,
 * un <small>, une pastille) garderait sinon un item par ligne.
 *
 * Le markup est le même aux deux tailles : ni duplication DOM, ni JS, et les
 * sélecteurs `data-test` de l'E2E restent uniques.
 */
@media (max-width: 767.98px) {
    /* Le zébrage n'a plus de sens une fois les lignes séparées en cartes. */
    .table-stack {
        --bs-table-striped-bg: transparent;
    }

    .table-stack thead {
        display: none;
    }

    .table-stack > tbody,
    .table-stack > tbody > tr > td {
        display: block;
        width: 100%;
    }

    /*
     * Deux colonnes : les valeurs courtes (`.cell-compact` — type, numéro,
     * couleur, décomptes, état) se rangent par paires, les autres occupent
     * toute la largeur. Sur 107 participations, la carte à une cellule par
     * ligne demandait un tiers de défilement en plus.
     */
    .table-stack > tbody > tr {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 1.25rem;
        margin-bottom: 0.75rem;
        padding: 0.25rem 0.75rem;
        border: var(--bs-border-width) solid var(--bs-border-color);
        border-radius: var(--bs-border-radius);
        background: var(--bs-body-bg);
    }

    .table-stack > tbody > tr > td {
        position: relative;
        grid-column: 1 / -1;
        padding: 0.45rem 0 0.45rem 40%;
        text-align: right;
    }

    .table-stack > tbody > tr > td.cell-compact {
        grid-column: auto;
    }

    .table-stack > tbody > tr > td::before {
        content: attr(data-label);
        position: absolute;
        top: 0.45rem;
        left: 0;
        width: 38%;
        text-align: left;
        font-weight: 600;
        color: var(--bs-secondary-color);
    }

    /* Première cellule : titre de la carte, sans intitulé ni retrait. */
    .table-stack > tbody > tr > td:first-child {
        padding-left: 0;
        text-align: left;
        font-size: 1.05rem;
        font-weight: 600;
    }

    /* Actions : boutons alignés à gauche, cibles tactiles ≥ 44 px. */
    .table-stack > tbody > tr > td.row-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        padding-left: 0;
        border-bottom: 0;
        text-align: left;
    }

    .table-stack > tbody > tr > td.row-actions .btn,
    .table-stack > tbody > tr > td.row-actions .form-select {
        min-height: 44px;
    }

    .table-stack > tbody > tr > td:first-child::before,
    .table-stack > tbody > tr > td.row-actions::before {
        content: none;
    }
}
