﻿/* ========================================================================
   CONVENTION PARTAGÉE : tableaux en cartes empilées sur téléphone
   ========================================================================
   Un tableau de gestion — invités, prestataires, tâches — devient illisible
   sous 768 px : les colonnes se tassent et le texte se coupe. Plutôt que de
   le faire défiler horizontalement, on le retourne en une pile de cartes,
   une par ligne, chaque cellule montrant son libellé de colonne à gauche.

   Le libellé ne peut pas être deviné depuis le CSS : c'est la vue qui le
   porte, sur chaque <td>, via l'attribut data-libelle. Écrire donc :

       <table class="table cartes-mobile">
         <thead><tr><th>Nom</th><th>Table</th></tr></thead>
         <tbody>
           <tr>
             <td data-libelle="Nom">Vanessa</td>
             <td data-libelle="Table">2</td>
           </tr>
         </tbody>
       </table>

   Règles d'usage :
   - data-libelle est obligatoire sur chaque <td> ; un <td> sans attribut
     s'affiche sans libellé, ce qui reste correct pour une cellule d'actions.
   - une cellule qui n'a pas besoin de libellé (boutons, case à cocher) peut
     porter la classe .cellule-pleine : elle occupe alors toute la largeur.
   - au-dessus de 768 px, le tableau reste un tableau ordinaire : la classe
     n'a aucun effet, on peut donc l'ajouter sans rien casser.
   - ne pas combiner avec .table-responsive : les deux se font concurrence,
     il faut choisir cartes OU défilement horizontal.

   L'implémentation se trouve en bas de ce fichier, avec le reste du socle
   responsive, pour rester après les règles de composants qu'elle surcharge.
   ======================================================================== */

html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

html {
  position: relative;
  min-height: 100%;
}

body {
  margin-bottom: 60px;
}
/* ---- Plan de table ---- */

.plan-entete {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .5rem;
}

/* Le plan occupe tout ce qui reste sous la barre de navigation. */
.plan-espace {
    display: flex;
    gap: .75rem;
    height: calc(100vh - 11rem);
    min-height: 24rem;
}

.plan-panneau {
    display: flex;
    flex: 0 0 16rem;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    box-shadow: var(--ombre-douce);
}

.panneau-replie .plan-panneau {
    display: none;
}

/* Le carnet de bord du plan : nom, salle, note et avis, à droite de la scène. */
.plan-fiche {
    display: flex;
    flex: 0 0 19rem;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    box-shadow: var(--ombre-douce);
}

.fiche-repliee .plan-fiche {
    display: none;
}

.plan-fiche-corps {
    flex: 1;
    padding: .75rem;
    overflow-y: auto;
}

.plan-fiche-pied {
    padding: .75rem;
    border-top: 1px solid var(--lisere);
}

.plan-fiche-etat {
    min-height: 1.2rem;
    margin-bottom: .75rem;
}

.plan-fiche-titre {
    margin: 1rem 0 .35rem;
    color: var(--encre-douce);
    font-size: .7rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.plan-fiche-stats {
    display: grid;
    gap: .25rem .5rem;
    grid-template-columns: 1fr 1fr;
    margin: 0;
}

.plan-fiche-stats > div {
    padding: .35rem .5rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: #fff;
}

.plan-fiche-stats dt {
    color: var(--encre-douce);
    font-size: .7rem;
    font-weight: 400;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.plan-fiche-stats dd {
    margin: 0;
    font-size: 1.05rem;
}

/* Les étoiles de notation. Des boutons, pour rester au clavier. */
.plan-etoiles {
    display: flex;
    align-items: center;
    gap: .1rem;
}

.plan-etoile {
    padding: 0 .05rem;
    border: 0;
    background: none;
    color: #d3cabc;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.plan-etoile.pleine {
    color: #d9a441;
}

.plan-etoile:hover {
    color: #e0b566;
}

.plan-etoile-effacer {
    margin-left: .4rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--encre-douce);
    font-size: .7rem;
    text-decoration: underline;
    cursor: pointer;
}

.plan-comparatif {
    margin: 0;
    padding: 0;
    list-style: none;
}

.plan-comparatif li {
    padding: .35rem .5rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: #fff;
}

.plan-comparatif li + li {
    margin-top: .35rem;
}

.plan-comparatif li.courant {
    border-color: var(--encre-douce);
}

.plan-comparatif a {
    display: flex;
    justify-content: space-between;
    gap: .5rem;
    color: inherit;
    text-decoration: none;
}

.plan-comparatif-nom {
    font-weight: 500;
}

.plan-comparatif-note {
    color: #d9a441;
    white-space: nowrap;
}

.plan-comparatif-stats {
    display: block;
    color: var(--encre-douce);
    font-size: .75rem;
}

/* Le sélecteur de plan de l'en-tête. */
.plan-choix {
    max-width: 22rem;
}

.plan-choix .dropdown-item {
    white-space: normal;
}

.plan-choix-salle {
    color: var(--encre-douce);
    font-size: .75rem;
}

.plan-choix-salle::before {
    content: " — ";
}

.plan-choix-note {
    color: #d9a441;
    white-space: nowrap;
}

.plan-choix .active .plan-choix-note,
.plan-choix .active .plan-choix-salle,
.plan-choix .active .plan-choix-stats {
    color: inherit;
}

.plan-choix-stats {
    display: block;
    color: var(--encre-douce);
    font-size: .75rem;
}

.plan-panneau-liste {
    flex: 1;
    padding: .5rem;
    overflow-y: auto;
}

.plan-groupe + .plan-groupe {
    margin-top: .75rem;
}

.plan-groupe-titre {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin: 0 0 .25rem;
    color: var(--encre-douce);
    font-size: .7rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.plan-pastille {
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
}

.jeton-invite {
    display: block;
    margin-bottom: .15rem;
    padding: .2rem .4rem;
    border-left: 3px solid #6c757d;
    border-radius: .25rem;
    background: var(--sable);
    cursor: grab;
    font-size: .8rem;
}

.jeton-invite:active {
    cursor: grabbing;
}

.plan-scene {
    flex: 1;
    overflow: auto;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--sable);
}

.plan-monde {
    position: relative;
    width: 100%;
    /* La largeur est pilotée par le zoom ; la hauteur suit le ratio de l'image. */
    transform-origin: top left;
}

.plan-monde.quadrille {
    background-image:
        linear-gradient(to right, rgba(0, 0, 0, .06) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(0, 0, 0, .06) 1px, transparent 1px);
    background-size: 2.5% 2.5%;
}

.plan-fond {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: fill;
    user-select: none;
}

.table-plan {
    position: absolute;
    cursor: grab;
    touch-action: none;
    user-select: none;
}

.table-plan.deplacement {
    cursor: grabbing;
    opacity: .8;
}

.table-forme {
    width: 100%;
    height: 100%;
    border: 2px solid var(--sauge-sombre);
    background: rgba(255, 253, 249, .93);
}

.forme-ronde,
.forme-ovale {
    border-radius: 50%;
}

.forme-carree,
.forme-rectangulaire {
    border-radius: .25rem;
}

.table-plan.survol .table-forme {
    border-color: #0d6efd;
    box-shadow: 0 0 0 .2rem rgba(13, 110, 253, .3);
}

.table-plan.complete .table-forme {
    border-style: double;
    border-width: 4px;
}

.table-etiquette {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .1rem;
    overflow: hidden;
    padding: .1rem;
    font-size: .7rem;
    line-height: 1.1;
    text-align: center;
    pointer-events: none;
}

.table-nom {
    max-width: 100%;
    overflow: hidden;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.table-compte {
    color: var(--encre-douce);
    font-size: .65rem;
}

.table-chaises {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.chaise {
    position: absolute;
    display: flex;
    width: var(--taille-chaise);
    height: var(--taille-chaise);
    align-items: center;
    justify-content: center;
    border: 1px solid var(--lisere);
    border-radius: 50%;
    background: var(--creme);
    pointer-events: auto;
    transform: translate(-50%, -50%);
}

.chaise.occupee {
    border-color: rgba(61, 58, 52, .25);
    color: #fff;
    cursor: pointer;
}

.chaise.survol {
    border-color: #0d6efd;
    box-shadow: 0 0 0 .15rem rgba(13, 110, 253, .35);
}

.chaise-nom {
    max-width: 96%;
    overflow: hidden;
    color: inherit;
    font-size: calc(var(--taille-chaise) * .3);
    line-height: 1;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chaise:not(.occupee) .chaise-nom {
    color: var(--encre-douce);
    opacity: .6;
}

/* Partagé avec la liste des invités, qui signale ses déplacements de la même façon. */
.plan-bandeau {
    position: fixed;
    z-index: 1080;
    top: 1rem;
    left: 50%;
    padding: .5rem .9rem;
    border-radius: .375rem;
    background: var(--encre);
    color: var(--creme);
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .25);
    font-size: .875rem;
    transform: translateX(-50%);
}

/* Poignées de redimensionnement, discrètes tant qu'on ne survole pas la table. */
.poignee {
    position: absolute;
    z-index: 3;
    width: .6rem;
    height: .6rem;
    border: 1px solid var(--sauge, #7d8f69);
    border-radius: .15rem;
    background: var(--creme);
    opacity: 0;
    transition: opacity .12s ease-in-out;
}

.table-plan:hover .poignee,
.table-plan.redimensionne .poignee {
    opacity: 1;
}

.poignee-nw { top: 0; left: 0; cursor: nwse-resize; transform: translate(-50%, -50%); }
.poignee-ne { top: 0; right: 0; cursor: nesw-resize; transform: translate(50%, -50%); }
.poignee-se { right: 0; bottom: 0; cursor: nwse-resize; transform: translate(50%, 50%); }
.poignee-sw { bottom: 0; left: 0; cursor: nesw-resize; transform: translate(-50%, 50%); }

.table-plan.redimensionne .table-forme {
    border-color: var(--sauge, #7d8f69);
}

/* ---- Liste des invités groupée par foyer ---- */

/* L'en-tête d'un foyer se distingue des personnes qu'il contient sans faire un titre :
   la liste reste un tableau qu'on parcourt d'un bloc. */
.entete-foyer > td {
    background: var(--sable);
    border-top: 2px solid var(--lisere);
}

.entete-foyer .nom-foyer {
    max-width: 18rem;
    background: var(--creme);
    font-weight: 600;
}

/* La poignée n'apparaît qu'au survol de la ligne : montrée en permanence sur toute la
   liste, elle ferait un rideau de points sans rien apporter. */
.poignee-foyer {
    color: var(--encre-douce);
    cursor: grab;
    letter-spacing: -.15em;
    opacity: 0;
    user-select: none;
}

.ligne-personne:hover .poignee-foyer,
.ligne-personne:focus-within .poignee-foyer {
    opacity: .6;
}

.ligne-personne.en-deplacement {
    opacity: .4;
}

/* Le bloc survolé s'éclaire en entier : c'est le foyer qui accueille, pas une ligne. */
.bloc-foyer.survol > tr > td {
    background: var(--rose-poudre);
}

/* ---- Glisser-déposer, éléments communs à toutes les pages ---- */

/* Un refus se distingue d'une confirmation : même bandeau, autre couleur. */
.plan-bandeau.bandeau-erreur {
    background: #8c3a2b;
}

/* Un formulaire parti en Ajax s’estompe le temps de la réponse : on voit que ça travaille. */
.ajax-en-cours {
    opacity: .6;
    pointer-events: none;
    transition: opacity .15s;
}

/* Zone de dépôt de fichiers : le pointillé dit qu'on peut y lâcher quelque chose. */
.zone-depot {
    padding: 1rem;
    border: 2px dashed var(--lisere);
    border-radius: var(--rayon);
    color: var(--encre-douce);
    text-align: center;
    transition: background-color .12s, border-color .12s;
}

.zone-depot.survol {
    border-color: var(--sauge);
    background: var(--rose-poudre);
    color: var(--encre);
}

/* ---- Tableau des tâches à colonnes ---- */

/* Trois colonnes d'égale largeur sur grand écran ; empilées en dessous, où glisser n'a de
   toute façon guère de sens et où la liste reste la bonne vue. */
.tableau-taches {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}

@media (min-width: 992px) {
    .tableau-taches {
        grid-template-columns: repeat(3, 1fr);
    }
}

.colonne-taches {
    padding: .75rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    transition: background-color .12s, border-color .12s;
}

/* La colonne survolée s'éclaire en entier : c'est elle qui accueille, pas une carte. */
.colonne-taches.survol {
    border-color: var(--sauge);
    background: var(--rose-poudre);
}

.entete-colonne {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .6rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--lisere);
}

.compte-colonne {
    background: var(--sable);
    color: var(--encre-douce);
}

/* Une hauteur minimale même vide : sans elle, une colonne sans tâche n'offrirait presque
   aucune surface où lâcher la carte. */
.cartes-colonne {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    min-height: 4rem;
}

.carte-tache {
    padding: .5rem .6rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--ivoire);
    cursor: grab;
}

.carte-tache.en-deplacement {
    opacity: .4;
}

.titre-tache {
    display: flex;
    align-items: baseline;
    gap: .4rem;
}

/* Même discrétion que la poignée de la liste des invités : visible au besoin, pas avant. */
.poignee-tache {
    color: var(--encre-douce);
    letter-spacing: -.15em;
    opacity: 0;
    user-select: none;
}

.carte-tache:hover .poignee-tache,
.carte-tache:focus-within .poignee-tache {
    opacity: .6;
}

.carte-tache.faite .titre-tache a {
    color: var(--encre-douce);
    text-decoration: line-through;
}

.meta-tache {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: .25rem;
    color: var(--encre-douce);
    font-size: .75rem;
}

/* Une échéance dépassée se signale comme ailleurs dans l'application. */
.carte-tache.en-retard .echeance-tache {
    color: #9a7b2f;
    font-weight: 700;
    text-decoration: underline;
}

.colonne-vide {
    margin-top: .5rem;
    font-size: .8rem;
    font-style: italic;
}

/* ---- Tableau de démarchage des prestataires ---- */

/* Huit colonnes ne tiennent pas sur un écran. Plutôt que de les comprimer jusqu'à rendre
   les fiches illisibles, on leur donne une largeur confortable et on défile
   horizontalement : le parcours se lit de gauche à droite, c'est un sens naturel. */
.demarchage {
    display: flex;
    gap: .75rem;
    overflow-x: auto;
    padding-bottom: .75rem;
}

.colonne-demarchage {
    display: flex;
    flex: 0 0 15rem;
    flex-direction: column;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
}

.colonne-demarchage.survol {
    border-color: var(--sauge);
    background: var(--rose-poudre);
}

.colonne-demarchage .entete-colonne {
    padding: .5rem .75rem;
    border-bottom: 1px solid var(--lisere);
    background: var(--sable);
    border-radius: var(--rayon) var(--rayon) 0 0;
}

/* Une hauteur minimale même vide : sans elle, une colonne sans fiche se réduit à son
   en-tête et devient impossible à viser au moment où on veut y déposer la première. */
.colonne-demarchage .pile-cartes {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: .5rem;
    min-height: 6rem;
    padding: .5rem;
}

/* « Écarté » et « Indisponible » sont des fins de parcours : ils restent lisibles et
   accueillent toujours un dépôt, mais ne doivent pas retenir l'œil comme « Retenu ». */
.colonne-demarchage.colonne-close {
    background: var(--ivoire);
    opacity: .65;
}

.colonne-demarchage.colonne-close:hover,
.colonne-demarchage.colonne-close.survol {
    opacity: 1;
}

.carte-presta {
    padding: .5rem .625rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    box-shadow: var(--ombre-douce);
    cursor: grab;
}

.carte-presta.en-deplacement {
    opacity: .4;
}

/* Une relance dont la date est passée est la seule chose urgente du tableau. */
.carte-presta .relance-passee {
    color: var(--terracotta);
    font-weight: 600;
}

/* ---- Plan de couchage (page Hébergement) ---- */

/* Un lieu est une zone d'accueil : on doit voir qu'on peut y lâcher quelque chose même
   quand il est vide, d'où la hauteur minimale de la liste de cartes. */
.cartes-couchage {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    min-height: 4rem;
}

.lieu-couchage {
    transition: background-color .12s, border-color .12s;
}

.lieu-couchage.survol {
    border-color: var(--sauge);
    background: var(--rose-poudre);
}

/* Le bloc « À loger » reste affiché même vide : sans lui, plus moyen de sortir un foyer
   d'un lieu le jour où tout le monde est casé. Le pointillé dit qu'il est là pour ça. */
.bloc-a-loger {
    border-style: dashed;
}

.carte-foyer {
    padding: .4rem .6rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    cursor: grab;
}

.carte-foyer.en-deplacement {
    opacity: .4;
}

.poignee-couchage {
    color: var(--encre-douce);
    letter-spacing: -.15em;
    opacity: .5;
    user-select: none;
}

/* ---- Chantier « suivi de l'envoi des faire-part en colonnes » ---- */

/* Les quatre colonnes tiennent côte à côte sur un écran de bureau et se laissent
   faire défiler sur un portable : sur deux lignes, on ne verrait plus d'un coup d'œil
   ce qui reste à cachetter, qui est tout l'intérêt de cette vue. */
.suivi-colonnes {
    display: grid;
    grid-auto-columns: minmax(15rem, 1fr);
    grid-auto-flow: column;
    gap: .75rem;
    overflow-x: auto;
    padding-bottom: .5rem;
}

.suivi-colonne {
    display: flex;
    flex-direction: column;
    padding: .75rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
}

/* La colonne que le serveur remplit tout seul se démarque : rien ne s'y dépose. */
.suivi-colonne-auto {
    background: var(--ivoire);
    border-style: dashed;
}

.suivi-colonne.survol {
    border-color: var(--sauge);
    background: var(--rose-poudre);
}

.suivi-colonne-auto.survol {
    border-color: var(--terracotta);
    background: var(--ivoire);
}

.suivi-entete {
    display: flex;
    flex-direction: column;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--lisere);
}

.suivi-titre {
    font-weight: 600;
}

.suivi-compte {
    font-size: .85rem;
}

.suivi-note {
    margin: .5rem 0 0;
    color: var(--encre-douce);
    font-size: .8rem;
    font-style: italic;
}

/* La zone d'accueil garde une hauteur minimale : une colonne vidée doit rester une
   cible de dépôt, sinon on ne peut plus y ramener quoi que ce soit. */
.suivi-cartes {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    min-height: 4rem;
    margin-top: .5rem;
}

.suivi-carte {
    padding: .5rem .6rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    box-shadow: var(--ombre-douce);
    cursor: grab;
}

.suivi-colonne-auto .suivi-carte {
    background: var(--sable);
}

.suivi-carte.en-deplacement {
    opacity: .4;
}

.suivi-carte-nom {
    font-weight: 600;
}

.suivi-carte-detail {
    font-size: .85rem;
}

.suivi-carte-alerte {
    margin-top: .25rem;
    color: var(--terracotta);
    font-size: .8rem;
    font-weight: 600;
}

.suivi-carte-lien {
    display: inline-block;
    margin-top: .25rem;
    font-size: .8rem;
}

/* ---- Déposer un fichier plutôt que d'aller le chercher ---- */

/* Pendant l'envoi, la zone cesse d'inviter au dépôt et dit ce qui part. */
.zone-depot.depot-envoi {
    border-style: solid;
    border-color: var(--sauge);
    color: var(--encre);
}

.depot-nom {
    font-style: italic;
}

/* Le voile de dépôt du plan de table. Absent tant qu'aucun fichier n'est glissé : sans
   pointer-events: none, il intercepterait les invités qu'on place sur les tables. */
.plan-depot {
    position: absolute;
    inset: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    border: 3px dashed var(--sauge);
    border-radius: var(--rayon);
    background: rgba(255, 255, 255, .82);
    color: var(--encre);
    font-size: 1.05rem;
    text-align: center;
    transition: opacity .12s;
}

.plan-depot.actif,
.plan-depot.depot-envoi {
    opacity: 1;
    pointer-events: auto;
}

.plan-depot.survol {
    background: rgba(255, 255, 255, .94);
    border-color: var(--sauge-sombre);
}

/* ---- Tri des tableaux ---- */

/* Un en-tête triable se reconnaît au survol, pas avant : la flèche n'apparaît que sur la
   colonne qui commande l'ordre, pour ne pas faire un rang de chevrons au-dessus de chaque
   tableau. */
.table > thead th.triable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.table > thead th.triable:hover,
.table > thead th.triable:focus-visible {
    color: var(--encre);
    outline: none;
}

.table > thead th.triable::after {
    display: inline-block;
    width: .9em;
    margin-left: .25em;
    color: var(--sauge);
    content: "";
}

.table > thead th.tri-asc::after {
    content: "\2191";
}

.table > thead th.tri-desc::after {
    content: "\2193";
}

/* ---- Brief des enterrements de vie de garcon et de jeune fille ---- */

/* Quatre colonnes, de l'indispensable au refuse : la lecture de gauche a droite va de ce
   qu'il faut absolument a ce qu'il ne faut surtout pas. Empilees sur petit ecran. */
.tableau-brief {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .tableau-brief {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 1200px) {
    .tableau-brief {
        grid-template-columns: repeat(4, 1fr);
    }
}

.colonne-brief {
    display: flex;
    flex-direction: column;
    padding: .75rem;
    border: 1px solid var(--lisere);
    border-top-width: 3px;
    border-radius: var(--rayon);
    background: var(--creme);
    transition: background-color .12s, border-color .12s;
}

/* Le lisere du haut code la priorite, la meme couleur que la pastille de la page d'accueil. */
.colonne-brief[data-cible="Must"], .pastille-priorite[data-priorite="Must"] { --priorite: var(--sauge-sombre); }
.colonne-brief[data-cible="Should"], .pastille-priorite[data-priorite="Should"] { --priorite: var(--sauge); }
.colonne-brief[data-cible="Could"], .pastille-priorite[data-priorite="Could"] { --priorite: var(--sauge-clair); }
.colonne-brief[data-cible="Wont"], .pastille-priorite[data-priorite="Wont"] { --priorite: var(--terracotta); }

.colonne-brief {
    border-top-color: var(--priorite);
}

.pastille-priorite {
    display: inline-block;
    width: .6rem;
    height: .6rem;
    margin-right: .2rem;
    border-radius: 50%;
    background: var(--priorite);
    vertical-align: middle;
}

.colonne-brief.survol {
    border-color: var(--sauge);
    border-top-color: var(--priorite);
    background: var(--rose-poudre);
}

.colonne-brief .entete-colonne {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: .6rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--lisere);
}

.colonne-brief .sous-titre {
    display: block;
    margin-top: .1rem;
    color: var(--encre-douce);
    font-size: .8rem;
    font-weight: 400;
}

.cartes-brief {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: .5rem;
    min-height: 4rem;
    margin-bottom: .6rem;
}

.carte-brief {
    padding: .5rem .6rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--ivoire);
    cursor: grab;
}

.carte-brief.edition {
    cursor: default;
}

.carte-brief.en-deplacement {
    opacity: .4;
}

.carte-brief .titre-carte {
    display: flex;
    align-items: baseline;
    gap: .4rem;
}

.carte-brief .titre-carte > span:not(.poignee-brief) {
    flex: 1;
}

.carte-brief .detail-carte {
    margin: .25rem 0 0 1.1rem;
    color: var(--encre-douce);
    font-size: .85rem;
}

.poignee-brief {
    color: var(--encre-douce);
    letter-spacing: -.15em;
    opacity: 0;
    user-select: none;
}

.carte-brief:hover .poignee-brief,
.carte-brief:focus-within .poignee-brief {
    opacity: .6;
}

/* Les boutons d'une carte se montrent au survol, comme la poignee : la carte se lit d'abord. */
.carte-brief .actions-carte {
    display: flex;
    gap: .2rem;
    opacity: 0;
    white-space: nowrap;
}

.carte-brief:hover .actions-carte,
.carte-brief:focus-within .actions-carte {
    opacity: 1;
}

.colonne-brief .colonne-vide {
    margin-bottom: .6rem;
    font-size: .9rem;
}

/* Le resume de l'ambiance sur la page d'accueil se coupe apres trois lignes. */
.resume-ambiance {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

/* ========================================================================
   SOCLE RESPONSIVE TÉLÉPHONE
   ------------------------------------------------------------------------
   Tout ce bloc est en fin de fichier pour passer après les règles de
   composants qu'il surcharge. Il ne vise que les écrans sous 768 px, sauf
   les quelques règles ci-dessous qui valent à toutes les tailles.
   ======================================================================== */

/* Une image ne doit jamais forcer le défilement horizontal de la page. */
img,
svg,
video {
  max-width: 100%;
  height: auto;
}

/* Les encoches et la barre gestuelle : le viewport passe dessous
   (viewport-fit=cover dans les habillages), on rend donc la marge ici. */
body {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

.navbar > .container,
.sous-barre > .container {
  padding-left: max(.75rem, env(safe-area-inset-left));
  padding-right: max(.75rem, env(safe-area-inset-right));
}

/* Le liseré de feuillage est purement décoratif : il ne doit ni déborder,
   ni intercepter un appui destiné à ce qui se trouve dessous. */
.feuillage {
  overflow: hidden;
  max-width: 100%;
  pointer-events: none;
}

/* La sous-barre des pages d'une section défile horizontalement dès qu'elle
   ne tient plus : mieux vaut un ruban à faire glisser qu'un empilement qui
   repousse le contenu. La barre de défilement elle-même est masquée, et le
   lien actif est ramené à l'écran par site.js. */
.sous-barre ul {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}

.sous-barre ul::-webkit-scrollbar {
  display: none;
}

.sous-barre li {
  flex: 0 0 auto;
  scroll-snap-align: center;
}

@media (max-width: 767.98px) {
  /* ---- Navigation au doigt ---- */

  /* Une cible tactile confortable fait au moins 44 px de haut : les liens du
     menu, du menu déroulant du compte et de la sous-barre y passent tous. */
  .navbar-collapse .nav-link,
  .navbar .dropdown-item {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding-top: .5rem;
    padding-bottom: .5rem;
  }

  .navbar-toggler {
    min-width: 44px;
    min-height: 44px;
  }

  /* Le menu déroulant du compte est rendu à plat dans le menu replié : en
     position absolue il sortirait de l'écran par la droite. */
  .navbar .dropdown-menu {
    width: 100%;
    padding-left: .75rem;
    border: 0;
    background: transparent;
    box-shadow: none;
  }

  .navbar .dropdown-item {
    font-size: .95rem;
    white-space: normal;
  }

  /* Le menu déplié peut être plus haut que l'écran sur un petit téléphone. */
  .navbar-collapse {
    max-height: calc(100vh - 4.5rem);
    overflow-y: auto;
  }

  .sous-barre a {
    display: flex;
    align-items: center;
    min-height: 40px;
    white-space: nowrap;
  }

  .sous-barre ul {
    gap: 0 1.25rem;
  }

  /* ---- Rythme général de la page ---- */

  .container,
  .container-fluid {
    padding-left: .75rem;
    padding-right: .75rem;
  }

  .feuillage {
    height: 1.1rem;
    margin-bottom: .85rem;
  }

  /* Les titres en Cormorant sont dessinés pour un écran large : sur 360 px
     ils mangent deux lignes pour rien. */
  h1, .h1, .display-6 {
    font-size: 1.6rem;
  }

  h2, .h2 {
    font-size: 1.35rem;
  }

  h3, .h3 {
    font-size: 1.15rem;
  }

  /* ---- Tableaux ---- */

  /* Filet de sécurité : un tableau posé directement dans la page, sans
     enveloppe .table-responsive et sans .cartes-mobile, défile au lieu de
     déborder. La règle suivante rend son affichage normal à un tableau déjà
     enveloppé, pour ne pas superposer deux défilements. */
  main table.table:not(.cartes-mobile) {
    display: block;
    overflow-x: auto;
    width: 100%;
    -webkit-overflow-scrolling: touch;
  }

  .table-responsive > table.table:not(.cartes-mobile) {
    display: table;
    overflow-x: visible;
  }

  /* ---- Barres d'actions et formulaires ---- */

  /* Une rangée de boutons se replie au lieu de sortir de l'écran, et chaque
     bouton reste assez grand pour être visé au pouce. */
  .barre-actions,
  .btn-toolbar {
    flex-wrap: wrap;
  }

  .btn {
    min-height: 40px;
  }

  /* Les boutons d'un pied de formulaire prennent toute la largeur : c'est la
     seule mise en page qui reste lisible quand il y en a deux ou trois. */
  .actions-formulaire {
    display: flex;
    flex-direction: column;
    gap: .5rem;
  }

  .actions-formulaire .btn,
  .btn-pleine-largeur-mobile {
    width: 100%;
  }

  /* Rattrape les rangées de formulaire construites en flex à la main : les
     colonnes Bootstrap, elles, se replient déjà toutes seules. */
  form .d-flex:not(.flex-column):not(.align-items-center) {
    flex-wrap: wrap;
  }

  /* 16 px minimum sur les champs : en dessous, iOS zoome à la saisie. */
  .form-control,
  .form-select {
    font-size: 16px;
  }
}

/* Sous 576 px, toutes les modales passent en plein écran, comme le ferait
   .modal-fullscreen-sm-down, sans avoir à modifier chaque vue. */
@media (max-width: 575.98px) {
  .modal-dialog {
    width: auto;
    max-width: none;
    height: 100%;
    margin: 0;
  }

  .modal-content {
    height: 100%;
    border: 0;
    border-radius: 0;
  }

  .modal-header,
  .modal-footer {
    border-radius: 0;
  }

  .modal-body {
    overflow-y: auto;
  }

  /* La barre gestuelle du téléphone recouvrirait sinon les boutons du pied. */
  .modal-footer {
    padding-bottom: max(.75rem, env(safe-area-inset-bottom));
  }
}

/* ========================================================================
   .cartes-mobile — implémentation
   Convention documentée en tête de ce fichier :
   <table class="table cartes-mobile"> et <td data-libelle="Nom">.
   ======================================================================== */

@media (max-width: 767.98px) {
  .cartes-mobile,
  .cartes-mobile tbody,
  .cartes-mobile tr,
  .cartes-mobile td {
    display: block;
    width: auto;
  }

  /* Les en-têtes ne servent plus : le libellé est repris cellule par cellule. */
  .cartes-mobile thead {
    display: none;
  }

  /* Chaque ligne devient une carte, dans le même habillage que .card. */
  .cartes-mobile > tbody > tr {
    margin-bottom: .75rem;
    padding: .5rem .75rem;
    border: 1px solid var(--lisere);
    border-radius: var(--rayon);
    background: var(--creme);
    box-shadow: var(--ombre-douce);
  }

  /* Bootstrap colore les cellules, pas les lignes : on neutralise pour que
     la carte garde un fond uni et ses seuls filets internes. */
  .cartes-mobile > tbody > tr > td {
    padding: .4rem 0;
    border: 0;
    border-bottom: 1px solid #efe9df;
    background: transparent;
  }

  .cartes-mobile > tbody > tr > td:last-child {
    border-bottom: 0;
  }

  /* Le libellé de colonne, repris de l'attribut data-libelle posé par la vue. */
  .cartes-mobile > tbody > tr > td[data-libelle]::before {
    display: block;
    margin-bottom: .1rem;
    color: var(--encre-douce);
    content: attr(data-libelle);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
  }

  /* Une cellule d'actions ou de case à cocher n'a pas de libellé à montrer. */
  .cartes-mobile > tbody > tr > td.cellule-pleine::before {
    display: none;
  }

  /* Le message « aucune ligne » occupe déjà toute la carte : pas de centrage. */
  .cartes-mobile > tbody > tr > td[colspan] {
    text-align: left;
  }

  /* Le pied de tableau — les totaux — se lit en ligne, libellé puis montant. */
  .cartes-mobile > tfoot {
    display: block;
  }

  .cartes-mobile > tfoot > tr {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: space-between;
  }

  .cartes-mobile > tfoot td,
  .cartes-mobile > tfoot th {
    display: block;
    border: 0;
  }
}

/* QR code du lien de réponse (fiche foyer) : le SVG remplit sa boîte. */
.qr-code svg {
    display: block;
    width: 100%;
    height: auto;
}
