/* =====================================================================
 * Back-office v2 — refonte issue de la maquette
 * « Back-office interface refonte » (claude.ai/design).
 *
 * Feuille autonome : elle ne depend ni de Bootstrap ni du theme
 * Gentelella. Le back-office v1 n'est jamais charge en meme temps.
 * ================================================================== */

:root{
    --v2-fond:        #f6f5f2;   /* fond de page, sable clair */
    --v2-surface:     #ffffff;
    --v2-surface-alt: #f1efe9;
    --v2-bordure:     #d9d5cd;
    --v2-bordure-pale:#e7e4de;
    --v2-texte:       #23211c;
    --v2-texte-doux:  #4a463d;
    --v2-texte-pale:  #8b8578;
    --v2-accent:      #2b6a9e;
    --v2-accent-fonce:#245a87;
    --v2-accent-pale: #f4f8fb;
    --v2-danger:      #b3423a;
    --v2-nav:         #243240;
    --v2-nav-texte:   #c8d2da;
    --v2-nav-pale:    #8fa0ae;
    --v2-nav-titre:   #71828f;
    --v2-rayon:       8px;
}

*,*::before,*::after{ box-sizing: border-box; }

/* L'attribut hidden l'emporte sur les display: poses par le theme. */
[hidden]{ display: none !important; }

body.v2{
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: stretch;
    background: var(--v2-fond);
    color: var(--v2-texte);
    font-family: 'Source Sans 3', -apple-system, Segoe UI, Roboto, sans-serif;
    font-size: 14px;
    line-height: 1.5;
}

a{ color: var(--v2-accent); text-decoration: none; }
a:hover{ color: var(--v2-accent-fonce); text-decoration: underline; }

/* ------------------------------------------------------------------
 * Barre laterale
 * ---------------------------------------------------------------- */
.v2-nav{
    width: 232px;
    flex: none;
    display: flex;
    flex-direction: column;
    background: var(--v2-nav);
}

.v2-nav__compte{
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 20px 18px;
    border-bottom: 1px solid rgba(255,255,255,.08);
}
.v2-nav__avatar{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: 50%;
    background: rgba(255,255,255,.10);
    color: #cfe0ee;
    font-size: 14px;
    font-weight: 700;
}
.v2-nav__bienvenue{ font-size: 11px; color: var(--v2-nav-pale); }
.v2-nav__nom{ font-size: 14px; font-weight: 600; color: #fff; }

.v2-nav__titre{
    padding: 16px 20px 8px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .14em;
    color: var(--v2-nav-titre);
}

.v2-nav__liste{
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0 10px 20px;
    margin: 0;
    list-style: none;
    overflow-y: auto;
}

.v2-nav__groupe > .v2-nav__lien{
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--v2-rayon);
    background: transparent;
    color: var(--v2-nav-texte);
    font-family: inherit;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
}
.v2-nav__lien:hover,
.v2-nav__lien:focus{
    background: rgba(255,255,255,.06);
    color: #fff;
    text-decoration: none;
}
.v2-nav__groupe--ouvert > .v2-nav__lien{ color: #fff; font-weight: 600; }

.v2-nav__chevron{ color: var(--v2-nav-pale); font-size: 11px; }

.v2-nav__sous{
    display: none;
    flex-direction: column;
    gap: 2px;
    padding: 2px 0 6px;
    margin: 0;
    list-style: none;
}
.v2-nav__groupe--ouvert > .v2-nav__sous{ display: flex; }

.v2-nav__sous a{
    display: block;
    padding: 8px 12px 8px 26px;
    border-radius: var(--v2-rayon);
    color: var(--v2-nav-texte);
    font-size: 13px;
}
.v2-nav__sous a:hover{ background: rgba(255,255,255,.06); color: #fff; text-decoration: none; }
.v2-nav__sous a.est-actif{ background: rgba(255,255,255,.10); color: #fff; font-weight: 600; }

/* ------------------------------------------------------------------
 * Colonne principale
 * ---------------------------------------------------------------- */
.v2-principal{
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.v2-entete{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 26px;
    background: var(--v2-surface);
    border-bottom: 1px solid var(--v2-bordure-pale);
}
.v2-entete__date{ font-size: 13px; color: var(--v2-texte-pale); }
.v2-entete__compte{ display: flex; align-items: center; gap: 10px; font-size: 14px; }

.v2-contenu{ padding: 24px 26px 40px; }

.v2-fil{ font-size: 12px; color: var(--v2-texte-pale); margin-bottom: 4px; }
.v2-titre{
    margin: 0 0 18px;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--v2-texte);
}

/* ------------------------------------------------------------------
 * Messages
 * ---------------------------------------------------------------- */
.v2-message{
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    margin-bottom: 16px;
    border: 1px solid var(--v2-bordure);
    border-left: 3px solid var(--v2-accent);
    border-radius: var(--v2-rayon);
    background: var(--v2-accent-pale);
    color: var(--v2-texte-doux);
}

/* ------------------------------------------------------------------
 * Panneau et barre d'outils
 * ---------------------------------------------------------------- */
.v2-carte{
    border: 1px solid var(--v2-bordure);
    border-radius: 12px;
    background: var(--v2-surface);
    overflow: hidden;
}

.v2-outils{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 14px 16px;
    border-bottom: 1px solid var(--v2-bordure-pale);
    background: var(--v2-surface-alt);
}
.v2-outils__groupe{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.v2-recherche{
    min-width: 240px;
    height: 36px;
    padding: 6px 12px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    font-family: inherit;
    font-size: 14px;
    color: var(--v2-texte);
}
.v2-recherche:focus{ outline: 0; border-color: var(--v2-accent); }

/* ------------------------------------------------------------------
 * Boutons
 * ---------------------------------------------------------------- */
.v2-btn{
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 36px;
    padding: 0 14px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.v2-btn:hover,
.v2-btn:focus{ border-color: var(--v2-accent); background: var(--v2-accent-pale); color: var(--v2-accent-fonce); text-decoration: none; }

/* Anneau de focus sobre, qui prend la couleur du bouton : le trace noir
   du navigateur jurait sur le bouton d'action destructrice. */
.v2-btn:focus-visible{
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.v2-btn--primaire{ border-color: var(--v2-accent); background: var(--v2-accent); color: #fff; }
.v2-btn--primaire:hover,
.v2-btn--primaire:focus{ background: var(--v2-accent-fonce); border-color: var(--v2-accent-fonce); color: #fff; }

.v2-btn--danger{ border-color: #e3bdba; background: #fdf2f1; color: var(--v2-danger); }
.v2-btn--danger:hover,
.v2-btn--danger:focus{ border-color: var(--v2-danger); background: #f9e3e1; color: #8f342e; }

/* Actions de ligne : icone seule, dimensionnee, jamais inline. */
.v2-action{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--v2-bordure);
    border-radius: 6px;
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    cursor: pointer;
    line-height: 1;
}
.v2-action:hover,
.v2-action:focus{ border-color: var(--v2-accent); background: var(--v2-accent-pale); color: var(--v2-accent); text-decoration: none; }
.v2-action--danger:hover,
.v2-action--danger:focus{ border-color: var(--v2-danger); background: #fdf2f1; color: var(--v2-danger); }

/* ------------------------------------------------------------------
 * Listing
 * ---------------------------------------------------------------- */
.v2-tableau{ width: 100%; border-collapse: collapse; }

.v2-tableau th{
    padding: 11px 16px;
    border-bottom: 1px solid var(--v2-bordure);
    background: var(--v2-surface);
    color: var(--v2-texte-pale);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
}
.v2-tableau td{
    padding: 12px 16px;
    border-bottom: 1px solid var(--v2-bordure-pale);
    color: var(--v2-texte-doux);
    vertical-align: middle;
}
.v2-tableau tbody tr:last-child td{ border-bottom: 0; }
.v2-tableau tbody tr:hover{ background: var(--v2-accent-pale); }

.v2-tableau__id{
    font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    color: var(--v2-texte-pale);
}
.v2-tableau__nom{ font-weight: 600; color: var(--v2-texte); }

.v2-tableau__actions{ width: 1%; white-space: nowrap; text-align: right; }
.v2-tableau__actions .v2-action + .v2-action{ margin-left: 6px; }

.v2-pastille{
    display: inline-block;
    padding: 3px 10px;
    border: 1px solid var(--v2-bordure);
    border-radius: 999px;
    background: var(--v2-surface-alt);
    font-size: 12px;
    font-weight: 600;
    color: var(--v2-texte-doux);
    white-space: nowrap;
}

.v2-vide{
    padding: 40px 16px;
    text-align: center;
    color: var(--v2-texte-pale);
}

.v2-pied{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-top: 1px solid var(--v2-bordure-pale);
    background: var(--v2-surface-alt);
    font-size: 13px;
    color: var(--v2-texte-pale);
}

/* ------------------------------------------------------------------
 * Bandeau d'essai
 * ---------------------------------------------------------------- */
.v2-essai{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 8px 16px;
    background: #2f4256;
    color: #dbe6ef;
    font-size: 13px;
}
.v2-essai a{ color: #fff; font-weight: 600; text-decoration: underline; }

/* ------------------------------------------------------------------
 * Petits ecrans
 * ---------------------------------------------------------------- */
@media (max-width: 900px){
    body.v2{ flex-direction: column; }
    .v2-nav{ width: 100%; }
    .v2-nav__liste{ max-height: 320px; }
    .v2-contenu{ padding: 18px 14px 32px; }
    .v2-carte{ overflow-x: auto; }
    .v2-tableau{ min-width: 620px; }
}

/* ------------------------------------------------------------------
 * QR code et boite d'impression
 * ---------------------------------------------------------------- */
/* La vignette EST le declencheur : plus de second element sous le QR, ce
   qui rendait les lignes deux fois plus hautes que les autres. */
.v2-qr{
    display: inline-block;
    line-height: 0;
    padding: 3px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 6px;
    background: #fff;
    cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.v2-qr:hover,
.v2-qr:focus-visible{
    border-color: var(--v2-accent);
    box-shadow: 0 0 0 3px rgba(43,106,158,.15);
    outline: none;
}
.v2-qr img,
.v2-qr canvas{ display: block; }

.v2-boite{
    padding: 0;
    border: 1px solid var(--v2-bordure);
    border-radius: 12px;
    background: var(--v2-surface);
    color: var(--v2-texte);
    box-shadow: 0 18px 50px rgba(0,0,0,.25);
}
.v2-boite::backdrop{ background: rgba(16,20,26,.55); }

.v2-boite__contenu{ padding: 24px 28px 18px; text-align: center; }
.v2-boite__titre{ margin: 0 0 4px; font-size: 18px; font-weight: 700; }
.v2-boite__soustitre{ margin: 0 0 16px; color: var(--v2-texte-doux); }
.v2-boite__qr{ display: flex; justify-content: center; }
.v2-boite__qr img,
.v2-boite__qr canvas{ display: block; }
.v2-boite__lien{
    margin: 14px 0 0;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 11px;
    color: var(--v2-texte-pale);
    word-break: break-all;
}

.v2-boite__pied{
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--v2-bordure-pale);
    background: var(--v2-surface-alt);
}


/* ==================================================================
 * Formulaires
 * ============================================================== */
.v2-form{ max-width: 900px; margin: 0 auto; }

.v2-form__intro{
    margin: 0 0 24px;
    font-size: 14px;
    color: var(--v2-texte-doux);
}
.v2-obligatoire{ color: var(--v2-danger); }

.v2-section{
    padding: 22px 24px;
    margin-bottom: 16px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 12px;
    background: var(--v2-surface);
}
.v2-section__titre{ margin: 0 0 16px; font-size: 15px; font-weight: 700; }
.v2-section__aide{ margin: -10px 0 16px; font-size: 13px; color: var(--v2-texte-doux); }
/* Intertitre : une section qui reunit plusieurs reglages d'un meme
   objet — l'image de la carte puis ses couleurs — les separe sans se
   scinder en deux cartes. */
.v2-section__soustitre{ margin: 22px 0 14px; font-size: 13px; font-weight: 700; color: var(--v2-texte-doux); }

.v2-grille{ display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 18px; }
.v2-grille--3{ grid-template-columns: repeat(3, minmax(0,1fr)); }
.v2-grille--1{ grid-template-columns: minmax(0,1fr); }
/* Un texte pleine largeur, son nuancier a cote : la colonne de droite
   ne prend que la place d'une pastille et de son code. */
.v2-grille--texte{ grid-template-columns: minmax(0,1fr) 150px; align-items: start; margin-bottom: 14px; }
.v2-case--couleur{ margin: 0 0 6px; font-size: 12px; font-weight: 400; }
/* Un nuancier desactive doit se lire comme tel. */
.v2-champ input[type=color]:disabled{ opacity: .45; cursor: not-allowed; }
@media (max-width: 700px){
    .v2-grille,
    .v2-grille--3{ grid-template-columns: minmax(0,1fr); }
}

.v2-champ{
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-texte-doux);
}

.v2-champ input[type="text"],
.v2-champ input[type="email"],
.v2-champ input[type="password"],
.v2-champ input[type="number"],
.v2-champ input[type="date"],
.v2-champ input[type="time"],
.v2-champ input[type="datetime-local"],
.v2-champ select,
.v2-champ textarea{
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    color: var(--v2-texte);
    font-family: inherit;
    font-size: 14px;
    font-weight: 400;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.v2-champ input:hover,
.v2-champ select:hover,
.v2-champ textarea:hover{ border-color: var(--v2-texte-pale); }
.v2-champ input:focus,
.v2-champ select:focus,
.v2-champ textarea:focus{
    border-color: var(--v2-accent);
    box-shadow: 0 0 0 3px rgba(43,106,158,.15);
    outline: none;
}
.v2-champ textarea{
    min-height: 125px;   /* 5 lignes pleines : 5 x 21 + 2 x 9 + 2 x 1 */
    line-height: 21px;
    resize: vertical;
}

.v2-champ__note{ font-weight: 400; color: var(--v2-texte-pale); }
/* Code couleur ecrit sous un nuancier : petit, en chiffres, et sans
   retour a la ligne pour ne pas decaler la grille. */
.v2-champ__note[data-v2-couleur]{
    display: block;
    margin-top: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px;
    /* La mention « remplace rgba(...) » est longue : elle passe a la ligne
       plutot que de deborder de sa colonne. */
    overflow-wrap: anywhere;
}
.v2-champ__erreur{ font-weight: 400; color: var(--v2-danger); }

/* Selecteur de couleur : une pastille, pas un champ.
   Etale sur toute la colonne, il pesait autant qu'un champ de saisie alors
   qu'il ne porte qu'une valeur. */
.v2-champ input[type="color"]{
    width: 76px;
    height: 38px;
    padding: 3px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.v2-champ input[type="color"]:hover{ border-color: var(--v2-texte-pale); }
.v2-champ input[type="color"]:focus-visible{
    border-color: var(--v2-accent);
    box-shadow: 0 0 0 3px rgba(43,106,158,.15);
    outline: none;
}

/* Le rendu natif laisse une marge autour de la couleur : on la supprime
   pour que la pastille soit pleine. */
.v2-champ input[type="color"]::-webkit-color-swatch-wrapper{ padding: 0; }
.v2-champ input[type="color"]::-webkit-color-swatch{
    border: 0;
    border-radius: 5px;
}
.v2-champ input[type="color"]::-moz-color-swatch{
    border: 0;
    border-radius: 5px;
}

/* Case a cocher alignee sur son libelle. */
.v2-case{
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-texte-doux);
    cursor: pointer;
}

/* Interrupteur.
 *
 * Dessine sur la case elle-meme (appearance:none) : le balisage reste un
 * <label><input type="checkbox"> Texte</label>, donc rien a changer dans
 * les vues et la case garde son comportement natif — clic sur le libelle,
 * barre d'espace, navigation au clavier, lecteurs d'ecran.
 *
 * Le bouton est un fond en degre radial plutot qu'un ::before : les
 * pseudo-elements sur un <input> ne sont pas garantis par la specification.
 */
.v2-case input[type="checkbox"]{
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    width: 34px;
    height: 20px;
    margin: 0;
    border: 0;
    border-radius: 999px;
    background-color: var(--v2-bordure);
    background-image: radial-gradient(circle 8px at 10px 10px, #fff 98%, transparent 100%);
    background-repeat: no-repeat;
    background-position: 0 0;
    cursor: pointer;
    transition: background-color .16s ease, background-position .16s ease;
}
.v2-case input[type="checkbox"]:checked{
    background-color: var(--v2-accent);
    background-position: 14px 0;
}
.v2-case input[type="checkbox"]:focus-visible{
    outline: none;
    box-shadow: 0 0 0 3px rgba(43,106,158,.22);
}
.v2-case:hover input[type="checkbox"]:not(:disabled){ background-color: var(--v2-texte-pale); }
.v2-case:hover input[type="checkbox"]:checked{ background-color: var(--v2-accent-fonce); }

.v2-case input[type="checkbox"]:disabled{
    background-color: var(--v2-bordure-pale);
    cursor: default;
}
.v2-case:has(input:disabled){ color: var(--v2-texte-pale); cursor: default; }

/* Repli : sans appearance:none, la case native reste affichee et reste
   utilisable — seul l'aspect interrupteur est perdu. */
@supports not (appearance: none){
    .v2-case input[type="checkbox"]{ width: auto; height: auto; background-image: none; }
}

/* Les groupes de choix multiples (jours de la semaine) et les cases en
   tableau gardent l'aspect natif : un interrupteur par jour serait large
   et se lirait comme sept reglages independants. */
.v2-case--simple input[type="checkbox"]{
    appearance: auto;
    -webkit-appearance: auto;
    width: auto;
    height: auto;
    background-image: none;
    background-color: transparent;
}
.v2-case input{ width: 16px; height: 16px; margin: 0; accent-color: var(--v2-accent); }

/* Depot d'image : apercu, puis zone de glisser-deposer. */
.v2-image{ display: flex; flex-direction: column; gap: 10px; }
.v2-image__libelle{ font-size: 13px; font-weight: 600; color: var(--v2-texte-doux); }
.v2-image__apercu{
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 9;
    border: 1px solid #e2ded6;
    border-radius: var(--v2-rayon);
    background: repeating-linear-gradient(45deg,#eceae6 0 10px,#f4f2ee 10px 20px);
    overflow: hidden;
}
.v2-image__apercu img{ max-width: 100%; max-height: 100%; object-fit: contain; }

/* Champs a plusieurs images — roulette, grattage, logos du Click'n'win.
   Les visuels s'alignent en ligne et passent a la suivante quand ils sont
   nombreux : le cadre 16/9 des champs a une seule image les ecrasait. */
.v2-image__apercu--multiple{
    aspect-ratio: auto;
    min-height: 104px;
    align-items: flex-start;
    align-content: flex-start;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px;
}
.v2-image__apercu--multiple .v2-image__vide{ align-self: center; margin: auto; }

.v2-vignette{
    position: relative;
    flex: 0 0 auto;
    width: 84px;
    height: 84px;
    margin: 0;
    border: 1px solid #e2ded6;
    border-radius: 8px;
    background: #ffffff;
    overflow: hidden;
}
.v2-vignette img{
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Vignette en attente d'envoi : elle n'est pas encore en base, on la
   distingue de celles qui y sont. */
.v2-vignette--nouvelle{ border-color: var(--v2-accent); border-style: dashed; }

.v2-vignette__suppr{
    position: absolute;
    top: 3px;
    right: 3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(20, 22, 26, .72);
    color: #ffffff;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}
.v2-vignette__suppr:hover,
.v2-vignette__suppr:focus{ background: var(--v2-danger); }
/* Bouton de suppression, pose dans l'angle de l'apercu.
   Selecteur a deux classes : le bouton porte data-tip pour son infobulle,
   et [data-tip]{position:relative} est declare plus bas — a specificite
   egale, c'est la derniere regle qui gagne. */
.v2-image__apercu{ position: relative; }

.v2-image__apercu .v2-image__suppr{
    position: absolute;
    top: 8px;
    right: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(24, 30, 38, .72);
    color: #fff;
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease, transform .15s ease;
}
.v2-image__apercu .v2-image__suppr:hover{ background: var(--v2-danger); transform: scale(1.06); }
.v2-image__apercu .v2-image__suppr:focus-visible{ outline: 2px solid #fff; outline-offset: 2px; }
.v2-image__apercu .v2-image__suppr:disabled{ opacity: .5; cursor: default; }

.v2-image__vide{
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 11px;
    color: var(--v2-texte-pale);
}
.v2-image__depot{
    padding: 12px;
    border: 1.5px dashed #cfcabf;
    border-radius: 10px;
    text-align: center;
    font-size: 13px;
    color: var(--v2-texte-doux);
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.v2-image__depot:hover,
.v2-image__depot.est-survole{ border-color: var(--v2-accent); background: var(--v2-accent-pale); }
.v2-image__depot input[type="file"]{ display: none; }
.v2-image__nom{ font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 11px; color: var(--v2-texte-pale); }

/* Barre d'actions collee en bas. */
.v2-actions{
    position: sticky;
    bottom: 0;
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 0 4px;
    background: linear-gradient(to top, var(--v2-fond) 70%, rgba(246,245,242,0));
}

/* ==================================================================
 * Infobulles
 *
 * Purement CSS, sur l'attribut data-tip. L'attribut title natif n'est pas
 * employe : il apparait apres une seconde, ne se met pas en forme, et
 * ferait doublon. L'accessibilite passe par aria-label.
 * ============================================================== */
[data-tip]{ position: relative; }

[data-tip]::after,
[data-tip]::before{
    position: absolute;
    left: 50%;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease, transform .12s ease;
    z-index: 60;
}

/* ⚠ La bulle n'est REMPLIE qu'au survol, et volontairement.
   En position: absolute avec opacity: 0 elle restait invisible, mais elle
   restait aussi dans la surface defilable du document : chaque pastille « ? »
   poussait la page de sa propre largeur (jusqu'a 260 px), et les fiches de
   jeu defilaient lateralement de 36 px a 390 et de 51 px a 768. Une bulle
   vide ne mesure plus que son rembourrage. Ni visibility: hidden ni
   display: none ne conviennent ici : le premier laisse la boite dans le
   flux de debordement, le second empeche la transition d'opacite. */
[data-tip]::after{
    content: "";
    bottom: calc(100% + 8px);
    transform: translate(-50%, 4px);
    max-width: 260px;
    width: max-content;
    padding: 6px 9px;
    border-radius: 6px;
    background: #23211c;
    color: #fff;
    font-family: 'Source Sans 3', sans-serif;
    font-size: 12px;
    font-weight: 400;
    line-height: 1.35;
    text-align: center;
    text-transform: none;
    letter-spacing: 0;
    white-space: normal;
    box-shadow: 0 6px 18px rgba(0,0,0,.22);
}

/* Petite fleche sous la bulle. */
[data-tip]::before{
    content: "";
    bottom: calc(100% + 3px);
    transform: translate(-50%, 4px);
    border: 5px solid transparent;
    border-top-color: #23211c;
}

[data-tip]:hover::after,
[data-tip]:focus-visible::after{ content: attr(data-tip); }

[data-tip]:hover::after,
[data-tip]:hover::before,
[data-tip]:focus-visible::after,
[data-tip]:focus-visible::before{
    opacity: 1;
    transform: translate(-50%, 0);
}

/* Sur les dernieres colonnes, la bulle deborderait a droite. */
.v2-tableau__actions [data-tip]::after{ left: auto; right: 0; transform: translate(0, 4px); }
/* L'apercu est en overflow:hidden et le bouton se tient dans son angle
   haut : l'infobulle, qui s'affiche normalement au-dessus de son element,
   sortait du cadre et se retrouvait rognee. On la bascule sous le bouton,
   alignee a droite, et la fleche est retiree — elle pointerait a l'envers. */
.v2-image__apercu [data-tip]::after{
    left: auto;
    right: 0;
    bottom: auto;
    top: calc(100% + 6px);
    transform: translate(0, -4px);
}
.v2-image__apercu [data-tip]:hover::after,
.v2-image__apercu [data-tip]:focus-visible::after{ transform: translate(0, 0); }
.v2-image__apercu [data-tip]::before{ display: none; }
.v2-tableau__actions [data-tip]::before{ left: auto; right: 12px; transform: translate(0, 4px); }
.v2-tableau__actions [data-tip]:hover::after,
.v2-tableau__actions [data-tip]:focus-visible::after{ transform: translate(0, 0); }
.v2-tableau__actions [data-tip]:hover::before,
.v2-tableau__actions [data-tip]:focus-visible::before{ transform: translate(0, 0); }

/* Barre d'outils d'un listing : elle est le PREMIER enfant de .v2-carte,
   qui est en overflow:hidden. Une bulle posee au-dessus du bouton tombe
   donc hors de la carte et se fait rogner — invisible, sans rien signaler.
   Elle s'ouvre ici vers le bas, la fleche retournee avec elle. */
.v2-outils [data-tip]::after{
    bottom: auto;
    top: calc(100% + 8px);
    transform: translate(-50%, -4px);
}
.v2-outils [data-tip]::before{
    bottom: auto;
    top: calc(100% + 3px);
    border-top-color: transparent;
    border-bottom-color: #23211c;
    transform: translate(-50%, -4px);
}
.v2-outils [data-tip]:hover::after,
.v2-outils [data-tip]:focus-visible::after,
.v2-outils [data-tip]:hover::before,
.v2-outils [data-tip]:focus-visible::before{ transform: translate(-50%, 0); }

/* Les boutons du groupe de droite touchent le bord de la carte : une bulle
   centree y deborderait, et serait rognee par le meme overflow. Elle se
   cale donc sur leur bord droit ; la fleche, elle, reste sur le bouton. */
.v2-outils__groupe:last-child [data-tip]::after{
    left: auto;
    right: 0;
    transform: translate(0, -4px);
}
.v2-outils__groupe:last-child [data-tip]:hover::after,
.v2-outils__groupe:last-child [data-tip]:focus-visible::after{ transform: translate(0, 0); }

/* Marqueur d'aide accole au libelle d'un champ. */
.v2-aide{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    margin-left: 5px;
    border: 1px solid var(--v2-bordure);
    border-radius: 50%;
    background: var(--v2-surface-alt);
    color: var(--v2-texte-pale);
    font-size: 10px;
    font-weight: 700;
    cursor: help;
    vertical-align: middle;
}
.v2-aide:hover{ border-color: var(--v2-accent); color: var(--v2-accent); }

@media print{ [data-tip]::after, [data-tip]::before{ display: none; } }

/* ------------------------------------------------------------------
 * Icones
 * ---------------------------------------------------------------- */
.v2-sprite{ position: absolute; width: 0; height: 0; overflow: hidden; }

.v2-icone{
    width: 16px;
    height: 16px;
    display: block;
    flex: none;
    fill: none;
    stroke: currentColor;
}
.v2-action .v2-icone{ width: 15px; height: 15px; }

/* ------------------------------------------------------------------
 * Filtres par etat
 * ---------------------------------------------------------------- */
.v2-filtres{ display: flex; gap: 4px; flex-wrap: wrap; }

.v2-filtre{
    height: 30px;
    padding: 0 12px;
    border: 1px solid var(--v2-bordure);
    border-radius: 999px;
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.v2-filtre:hover{ border-color: var(--v2-accent); color: var(--v2-accent); }
.v2-filtre.est-actif{
    border-color: var(--v2-accent);
    background: var(--v2-accent);
    color: #fff;
}

/* Tableau dense : beaucoup de colonnes sur cet ecran. */
.v2-tableau--dense th,
.v2-tableau--dense td{ padding: 8px 10px; font-size: 13px; }

.v2-pastille--gagnant{
    border-color: #b9d8bd;
    background: #eef7ef;
    color: #2f6b39;
}
.v2-pastille--oui{
    border-color: #bcd2e6;
    background: var(--v2-accent-pale);
    color: var(--v2-accent-fonce);
}

/* ------------------------------------------------------------------
 * Pagination
 * ---------------------------------------------------------------- */
.v2-pied__gauche{ display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.v2-pied__taille{
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--v2-texte-pale);
}
.v2-par-page{
    height: 30px;
    padding: 0 8px;
    border: 1px solid var(--v2-bordure);
    border-radius: 6px;
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 13px;
}
.v2-par-page:focus{ outline: 0; border-color: var(--v2-accent); }

.v2-pagination{ display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

.v2-page{
    min-width: 32px;
    height: 32px;
    padding: 0 9px;
    border: 1px solid var(--v2-bordure);
    border-radius: 6px;
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.v2-page:hover:not(:disabled){ border-color: var(--v2-accent); background: var(--v2-accent-pale); color: var(--v2-accent); }
.v2-page.est-actif{ border-color: var(--v2-accent); background: var(--v2-accent); color: #fff; }
.v2-page:disabled{ opacity: .4; cursor: default; }

.v2-page-saut{ padding: 0 2px; color: var(--v2-texte-pale); }

@media print{
    .v2-pagination, .v2-pied__taille{ display: none; }
}

/* ------------------------------------------------------------------
 * Editeur de texte enrichi
 * ---------------------------------------------------------------- */
/* Pas d'overflow:hidden ici : il rognait les infobulles de la barre
   d'outils, qui s'affichent au-dessus des boutons. Les coins sont arrondis
   sur les enfants a la place. */
.v2-editeur{
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
}
.v2-editeur:focus-within{
    border-color: var(--v2-accent);
    box-shadow: 0 0 0 3px rgba(43,106,158,.15);
}

.v2-editeur__barre{
    border-top-left-radius: var(--v2-rayon);
    border-top-right-radius: var(--v2-rayon);
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 6px 8px;
    border-bottom: 1px solid var(--v2-bordure-pale);
    background: var(--v2-surface-alt);
    flex-wrap: wrap;
}
.v2-editeur__barre button{
    min-width: 28px;
    height: 28px;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: 5px;
    background: transparent;
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}
.v2-editeur__barre button:hover{
    border-color: var(--v2-bordure);
    background: var(--v2-surface);
    color: var(--v2-accent);
}
.v2-editeur__separateur{
    width: 1px;
    height: 18px;
    margin: 0 4px;
    background: var(--v2-bordure);
}

.v2-editeur__zone{
    border-bottom-left-radius: var(--v2-rayon);
    border-bottom-right-radius: var(--v2-rayon);
    min-height: 130px;
    max-height: 340px;
    padding: 12px 14px;
    overflow-y: auto;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.55;
    color: var(--v2-texte);
}
.v2-editeur__zone:focus{ outline: none; }
.v2-editeur__zone p{ margin: 0 0 8px; }
.v2-editeur__zone p:last-child{ margin-bottom: 0; }
.v2-editeur__zone img{ max-width: 100%; height: auto; }

.v2-editeur__barre select{
    height: 28px;
    max-width: 116px;
    padding: 0 4px;
    border: 1px solid var(--v2-bordure);
    border-radius: 5px;
    background: var(--v2-surface);
    color: var(--v2-texte-doux);
    font-family: inherit;
    font-size: 12px;
}
.v2-editeur__barre input[type="color"]{
    width: 28px;
    height: 28px;
    padding: 2px;
    border: 1px solid var(--v2-bordure);
    border-radius: 5px;
    background: var(--v2-surface);
    cursor: pointer;
}
.v2-editeur__barre label{
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    font-weight: 400;
    color: var(--v2-texte-pale);
}

.v2-editeur__code{
    display: block;
    width: 100%;
    min-height: 160px;
    padding: 12px 14px;
    border: 0;
    border-bottom-left-radius: var(--v2-rayon);
    border-bottom-right-radius: var(--v2-rayon);
    background: #fbfaf8;
    color: var(--v2-texte);
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 12.5px;
    line-height: 1.5;
    resize: vertical;
}
.v2-editeur__code:focus{ outline: none; }
.v2-editeur__zone h1{ font-size: 22px; margin: 0 0 8px; }
.v2-editeur__zone h2{ font-size: 18px; margin: 0 0 8px; }
.v2-editeur__zone h3{ font-size: 16px; margin: 0 0 8px; }
.v2-editeur__zone blockquote{
    margin: 0 0 8px;
    padding-left: 12px;
    border-left: 3px solid var(--v2-bordure);
    color: var(--v2-texte-doux);
}

/* L'attribut hidden doit l'emporter sur le display:block ci-dessus : sans
   cette regle, la zone de code HTML restait visible sous l'editeur. */
.v2-editeur__code[hidden]{ display: none; }

/* Icones dessinees de la barre d'outils : centrees dans leur bouton. */
.v2-editeur__barre button{
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.v2-editeur__barre button svg{ display: block; }
.v2-editeur__barre button sup,
.v2-editeur__barre button sub{ font-size: 9px; }

/* Le bouton actif reflete l'etat du curseur (gras, centre, liste...). */
.v2-editeur__barre button.est-actif{
    border-color: var(--v2-bordure);
    background: var(--v2-surface);
    color: var(--v2-accent);
}

.v2-pastille--danger{
    border-color: #e3bdba;
    background: #fdf2f1;
    color: var(--v2-danger);
    cursor: help;
}

/* ------------------------------------------------------------------
 * Tuiles du tableau de bord
 * ---------------------------------------------------------------- */
.v2-tuiles{
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
}

.v2-tuile{
    padding: 18px 20px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 12px;
    background: var(--v2-surface);
}
.v2-tuile__valeur{
    font-size: 28px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--v2-texte);
}
.v2-tuile__libelle{
    margin-top: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-texte-doux);
}
.v2-tuile__note{
    margin-top: 2px;
    font-size: 12px;
    color: var(--v2-texte-pale);
}



/* ------------------------------------------------------------------
 * Ecrans d'authentification (connexion, code 2FA, renouvellement)
 *
 * Ils s'affichent avant toute session : pas de menu lateral, pas
 * d'en-tete de compte. Une carte centree, la meme grammaire de champs
 * et de boutons que le reste de la v2.
 * ---------------------------------------------------------------- */
body.v2--auth{
    display: block;
    min-height: 100vh;
    padding: 40px 20px;
    background: var(--v2-fond);
}

.v2-auth{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - 80px);
}

.v2-auth__carte{
    width: 100%;
    max-width: 440px;
    padding: 30px 32px 32px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 14px;
    background: var(--v2-surface);
    box-shadow: 0 12px 36px rgba(24, 30, 38, .07);
}

.v2-auth__marque{
    margin-bottom: 22px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--v2-bordure-pale);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .14em;
    text-align: center;
    color: var(--v2-texte);
}

.v2-auth__titre{
    margin: 0 0 4px;
    font-size: 20px;
    font-weight: 700;
    color: var(--v2-texte);
}
.v2-auth__intro{
    margin: 0 0 20px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--v2-texte-doux);
}
.v2-auth__aide{
    margin: 16px 0 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--v2-texte-pale);
}

/* Les champs s'empilent : la carte est trop etroite pour deux colonnes. */
.v2-auth__carte .v2-champ{ margin-bottom: 16px; }

.v2-auth__actions{
    display: flex;
    gap: 8px;
    margin-top: 22px;
}
.v2-auth__actions .v2-btn{ flex: 1; justify-content: center; }

.v2-auth__essai{
    margin: 22px 0 0;
    font-size: 12.5px;
    color: var(--v2-texte-pale);
}
.v2-auth__essai a{ color: var(--v2-accent); }

/* Erreur et confirmation, dans la carte comme dans les pages internes. */
.v2-auth__alerte{
    margin-bottom: 18px;
    padding: 10px 12px;
    border: 1px solid #e3bdba;
    border-radius: 8px;
    background: #fdf2f1;
    font-size: 13px;
    line-height: 1.45;
    color: var(--v2-danger);
}
.v2-auth__alerte--ok{
    border-color: #bcd7c4;
    background: #f2f8f4;
    color: #2f6b45;
}

/* ------------------------------------------------------------------
 * Page d'erreur
 *
 * Rendue hors gabarit, sur la meme coquille centree que la connexion.
 * Plus large : la pile d'appels a besoin de place.
 * ---------------------------------------------------------------- */
.v2-erreur{
    width: 100%;
    max-width: 680px;
    padding: 26px 28px 28px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 14px;
    background: var(--v2-surface);
    box-shadow: 0 12px 36px rgba(24, 30, 38, .07);
}

.v2-erreur__entete{
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--v2-bordure-pale);
}
.v2-erreur__icone{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: #fdf2f1;
    color: var(--v2-danger);
}
.v2-erreur__titre{
    margin: 0;
    font-size: 20px;
    font-weight: 700;
    color: var(--v2-texte);
}
.v2-erreur__sous{
    margin: 3px 0 0;
    font-size: 13px;
    color: var(--v2-texte-doux);
}

.v2-erreur__message{
    margin: 20px 0 0;
    padding: 12px 14px;
    border: 1px solid #e3bdba;
    border-left-width: 3px;
    border-radius: 8px;
    background: #fdf2f1;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--v2-danger);
    overflow-wrap: anywhere;
}
.v2-erreur__message--sobre{
    border-color: var(--v2-bordure-pale);
    border-left-color: var(--v2-bordure);
    background: var(--v2-surface-alt);
    color: var(--v2-texte-doux);
}

.v2-erreur__reperes{
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 16px;
    margin: 18px 0 0;
    font-size: 13px;
}
.v2-erreur__reperes dt{
    font-weight: 600;
    color: var(--v2-texte-pale);
}
.v2-erreur__reperes dd{
    margin: 0;
    min-width: 0;
}
.v2-erreur__reperes code,
.v2-erreur__trace pre{
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 12.5px;
    color: var(--v2-texte);
}
.v2-erreur__reperes code{ overflow-wrap: anywhere; }

/* La pile est repliee : on ne la deroule que si on la cherche. */
.v2-erreur__trace{
    margin-top: 18px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 8px;
    background: var(--v2-surface-alt);
}
.v2-erreur__trace summary{
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-texte-doux);
    cursor: pointer;
}
.v2-erreur__trace summary:hover{ color: var(--v2-accent); }
.v2-erreur__trace pre{
    margin: 0;
    padding: 0 14px 14px;
    max-height: 260px;
    overflow: auto;
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.v2-erreur__actions{
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 24px;
}

/* ------------------------------------------------------------------
 * Reseaux de partage (formulaires de jeu)
 * ---------------------------------------------------------------- */
.v2-reseaux{
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.v2-reseau{
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 7px 14px 7px 10px;
    border: 1px solid var(--v2-bordure);
    border-radius: 999px;
    background: var(--v2-surface);
    font-size: 13px;
    font-weight: 600;
    color: var(--v2-texte-doux);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.v2-reseau:hover{ border-color: var(--v2-accent); }

/* La case elle-meme est masquee : la pastille et le liseré disent l'etat. */
.v2-reseau input{
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.v2-reseau__pastille{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    opacity: .35;
    transition: opacity .15s ease;
}
.v2-reseau__pastille svg{
    display: block;
    width: 12px;
    height: 12px;
    fill: #fff;
}

.v2-reseau:has(input:checked){
    border-color: var(--v2-accent);
    background: var(--v2-accent-pale);
    color: var(--v2-texte);
}
.v2-reseau:has(input:checked) .v2-reseau__pastille{ opacity: 1; }
.v2-reseau:has(input:focus-visible){ box-shadow: 0 0 0 3px rgba(43,106,158,.18); }

/* Repli pour les navigateurs sans :has() : la case native reapparait,
   sans quoi rien ne distinguerait un reseau coche d'un reseau decoche. */
@supports not (selector(:has(*))){
    .v2-reseau input{
        position: static;
        width: auto;
        height: auto;
        opacity: 1;
        pointer-events: auto;
    }
    .v2-reseau__pastille{ opacity: 1; }
}

/* ------------------------------------------------------------------
 * Tri des colonnes
 *
 * L'en-tete devient un bouton : cliquable a la souris comme au clavier,
 * et annonce par aria-sort sur la cellule.
 * ---------------------------------------------------------------- */
.v2-tableau th .v2-tri{
    display: inline-flex;
    align-items: center;
    gap: 5px;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: inherit;
    cursor: pointer;
}
.v2-tableau th .v2-tri:hover{ color: var(--v2-accent); }
.v2-tableau th .v2-tri:focus-visible{
    outline: 2px solid var(--v2-accent);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Fleche : discrete au repos, franche sur la colonne triee. */
.v2-tri__fleche{
    flex: 0 0 auto;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 5px solid currentColor;
    opacity: 0;
    transition: opacity .12s ease, transform .12s ease;
}
.v2-tableau th:hover .v2-tri__fleche{ opacity: .35; }
.v2-tri[data-v2-sens="asc"] .v2-tri__fleche{ opacity: 1; }
.v2-tri[data-v2-sens="desc"] .v2-tri__fleche{ opacity: 1; transform: rotate(180deg); }
.v2-tableau th.est-triee{ color: var(--v2-accent); }

/* ------------------------------------------------------------------
 * Colonnes des selecteurs de couleur
 *
 * Une pastille de 76 pixels dans une colonne de grille en occupait la
 * largeur entiere : les deux tiers restants tombaient dans le vide. Les
 * colonnes qui ne portent qu'une couleur se ramenent donc a leur contenu,
 * et le champ de saisie voisin recupere la place.
 *
 * Ecrit en :has() plutot qu'avec une classe posee dans les vues : aucune
 * vue a modifier, et les navigateurs sans :has() gardent la grille
 * reguliere, qui reste lisible.
 * ---------------------------------------------------------------- */

/* Deux colonnes, la seconde est une couleur : Titre | Couleur du titre. */
.v2-grille:has(> .v2-champ:nth-child(2) input[type="color"]){
    grid-template-columns: minmax(0, 1fr) auto;
}

/* Trois colonnes dont les deux dernieres sont des couleurs :
   Texte du bouton | Couleur du texte | Couleur du fond. */
.v2-grille--3:has(> .v2-champ:nth-child(2) input[type="color"]):has(> .v2-champ:nth-child(3) input[type="color"]){
    grid-template-columns: minmax(0, 1fr) auto auto;
}

/* Grille entierement composee de couleurs : elles se suivent, serrees a
   gauche, et repassent a la ligne quand la place manque. */
.v2-grille--3:has(> .v2-champ:first-child input[type="color"]){
    display: flex;
    flex-wrap: wrap;
    gap: 18px 26px;
}
.v2-grille--3:has(> .v2-champ:first-child input[type="color"]) > .v2-champ{
    flex: 0 0 auto;
}

@media (max-width: 700px){
    .v2-grille:has(> .v2-champ:nth-child(2) input[type="color"]),
    .v2-grille--3:has(> .v2-champ:nth-child(2) input[type="color"]):has(> .v2-champ:nth-child(3) input[type="color"]){
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ------------------------------------------------------------------
 * Boites de dialogue
 *
 * <dialog> natif : le fond assombri, le piege a focus, la fermeture par
 * Echap et le retour du focus sont fournis par le navigateur.
 * ---------------------------------------------------------------- */
.v2-modale{
    width: min(440px, calc(100vw - 32px));
    padding: 0;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 14px;
    background: var(--v2-surface);
    color: var(--v2-texte);
    box-shadow: 0 18px 50px rgba(24, 30, 38, .18);
}
.v2-modale::backdrop{
    background: rgba(24, 30, 38, .45);
    backdrop-filter: blur(2px);
}

.v2-modale__cadre{
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 24px 26px 22px;
}

.v2-modale__titre{
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--v2-texte);
}
.v2-modale__texte{
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--v2-texte-doux);
}
.v2-modale__champ{ margin: 4px 0 0; }

.v2-modale__actions{
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 6px;
}

@media (prefers-reduced-motion: no-preference){
    .v2-modale[open]{ animation: v2-modale-entree .16s ease-out; }
    @keyframes v2-modale-entree{
        from{ opacity: 0; transform: translateY(-6px) scale(.98); }
        to  { opacity: 1; transform: none; }
    }
}

/* ------------------------------------------------------------------
 * En-tete de formulaire : titre a gauche, action a droite
 * ---------------------------------------------------------------- */
.v2-form__entete{
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.v2-form__entete .v2-btn{ flex: 0 0 auto; }

@media (max-width: 640px){
    .v2-form__entete{ flex-direction: column; align-items: stretch; }
    .v2-form__entete .v2-btn{ justify-content: center; }
}

/* ==================================================================
 * Apercu de la carte de participation (formulaire de jeu)
 *
 * Maquette posee a cote des reglages : les fonds y sont pleins, la page de
 * jeu les servant en semi-transparent. Elle suit la saisie, sans bouton.
 * ================================================================== */
/* ⚠ Nom distinct de .v2-carte, qui est le conteneur de toutes les cartes
   du theme — listes comprises : la premiere version de cette regle les a
   toutes transformees en grille a deux colonnes, et les tableaux se sont
   retrouves ecrases dans la colonne de droite. */
.v2-carte-jeu{ display: grid; grid-template-columns: minmax(0,1fr) 240px; gap: 28px; align-items: start; }
/* La zone d'envoi de l'image de carte n'a pas a s'etaler sur toute la
   largeur des reglages : au-dela, elle n'apporte rien et ecrase le reste
   de la section. Les couleurs, elles, coulent deja d'elles-memes. */
.v2-carte-jeu__reglages .v2-image{ max-width: 420px; }
.v2-carte-jeu__reglages .v2-image__apercu{ aspect-ratio: 16 / 9; }
.v2-carte-jeu__reglages{ min-width: 0; }

/* L'apercu est un panneau a lui : sans cadre, il flottait dans la section
   et l'on ne savait plus ou finissaient les reglages. */
.v2-ap{
    position: sticky;
    top: 16px;
    padding: 14px;
    border: 1px solid var(--v2-bordure-pale);
    border-radius: 12px;
    background: var(--v2-surface-alt);
}
.v2-ap__libelle{
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 700;
    color: var(--v2-texte-pale);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.v2-ap__cadre{ padding: 12px; border-radius: 10px; background: #ffffff; }
/* Le cadre porte la couleur « Fond autour de la carte » : sur un fond
   blanc, il faut un trait pour le distinguer du panneau. */
.v2-ap__cadre{ box-shadow: inset 0 0 0 1px rgba(35, 33, 28, .08); }
.v2-ap__carte{
    display: flex;
    flex-direction: column;
    gap: 8px;
    /* L'image de fond de la carte passe ici, derriere les blocs, qui sont
       servis translucides comme sur la carte reelle. */
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
}
.v2-ap__bloc{ display: flex; flex-direction: column; }

.v2-ap__entete{ padding: 8px 6px; font-size: 13px; font-weight: 800; text-align: center; }
.v2-ap__qr{ padding: 10px 6px; text-align: center; }
.v2-ap__pied,
.v2-ap__corps{ padding: 6px; font-size: 11px; text-align: center; }

.v2-ap__texte{ margin: 0 0 6px; font-size: 11px; }
.v2-ap__logo{ display: block; max-width: 70%; max-height: 46px; margin: 0 auto 6px; }
.v2-ap__code{ width: 74px; margin: 0 auto; }
.v2-ap__code svg{ display: block; width: 100%; height: auto; }

/* Sous 1100 px, l'apercu passe sous les reglages plutot que de les etrangler. */
@media (max-width: 1100px){
    .v2-carte-jeu{ grid-template-columns: minmax(0,1fr); }
    .v2-ap{ position: static; max-width: 260px; }
}

/* ==================================================================
 * Selection multiple dans une liste
 * ================================================================== */
.v2-tableau__select{ width: 36px; text-align: center; }
.v2-tableau__select input{ margin: 0; cursor: pointer; }

/* Barre d'action groupee : elle n'apparait qu'une fois une ligne cochee,
   a la place qu'elle occupera — les boutons d'export ne bougent pas. */
.v2-selection{ display: flex; align-items: center; gap: 10px; }
.v2-selection__compte{ font-size: 13px; font-weight: 700; color: var(--v2-texte-doux); }

/* Apercu de la carte v2 : un seul bloc arrondi, comme la carte servie aux
   jeux dont la loading page est en modele 4 ou 5. */
.v2-ap__carte--v2{ border-radius: 12px; overflow: hidden; }
.v2-ap__v2{ padding: 12px 10px 14px; text-align: center; }
.v2-ap__v2-titre{ margin: 0 0 8px; font-size: 13px; font-weight: 800; }
.v2-ap__v2-bouton{
    display: block;
    margin: 8px 0;
    padding: 7px 10px;
    border-radius: 999px;
    background: #2b2bd8;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
}
.v2-ap__v2-encart{ margin-top: 10px; padding: 8px; border-radius: 10px; }
.v2-ap__v2-encart-titre{ margin: 0 0 4px; font-size: 12px; font-weight: 800; }

/* ==================================================================
 * Barre de l'image selectionnee dans l'editeur
 *
 * Une image inseree ne se reglait plus : ni taille, ni remplacement, ni
 * retrait. La barre flotte au-dessus de l'image cliquee.
 * ================================================================== */
.v2-editeur{ position: relative; }
.v2-editeur__image{
    position: absolute;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--v2-bordure);
    border-radius: 999px;
    background: var(--v2-surface);
    box-shadow: 0 6px 18px rgba(35, 33, 28, .16);
}
.v2-editeur__image button{
    padding: 5px 10px;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--v2-texte-doux);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.v2-editeur__image button:hover{ background: var(--v2-surface-alt); color: var(--v2-texte); }
.v2-editeur__image-sep{ width: 1px; height: 18px; background: var(--v2-bordure-pale); }
.v2-editeur__image-suppr{ color: var(--v2-danger); }
.v2-editeur__image-suppr:hover{ background: #fdf2f1; color: var(--v2-danger); }

/* Une image de contenu ne deborde jamais de la zone de saisie. */
.v2-editeur__zone img{ max-width: 100%; height: auto; }

/* ==================================================================
 * Liste partagee avec un commercant
 *
 * Le theme du back-office, sans son menu ni sa barre de compte : le
 * destinataire n'a pas de session, et n'a rien d'autre a atteindre que la
 * liste de son jeu. La coquille se limite donc a un bandeau, la carte de
 * liste, et une mention de confidentialite.
 * ============================================================== */
body.v2--partage{
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--v2-fond);
}
.v2-partage__entete{
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 14px 24px;
    border-bottom: 1px solid var(--v2-bordure);
    background: var(--v2-surface);
}
.v2-partage__marque{
    font-size: 18px;
    font-weight: 700;
    letter-spacing: .06em;
}
.v2-partage__mention{
    margin: 0;
    color: var(--v2-texte-pale);
    font-size: 13px;
}
.v2-partage__corps{
    flex: 1;
    width: 100%;
    max-width: 1400px;
    margin: 0 auto;
    padding: 24px;
}
.v2-partage__pied{
    padding: 16px 24px 24px;
    color: var(--v2-texte-pale);
    font-size: 12px;
    text-align: center;
}
/* Lien expire, revoque ou inconnu : un bloc sobre, sans rien dire de plus. */
.v2-partage__vide{
    max-width: 560px;
    margin: 48px auto;
    padding: 28px;
    text-align: center;
}
.v2-partage__vide .v2-titre{ margin-top: 0; }

@media (max-width: 640px){
    .v2-partage__corps{ padding: 16px 12px; }
    .v2-partage__entete{ padding: 12px 16px; }
}

/* ==================================================================
 * Panneau de partage d'une liste
 *
 * Replie sous la liste : il ne concerne pas la consultation courante, et
 * ne s'ouvre qu'a la demande.
 * ============================================================== */
.v2-partages{ margin-top: 18px; padding: 20px 22px 22px; }
.v2-partages__titre{ margin: 0 0 6px; font-size: 17px; font-weight: 700; }
.v2-partages__intro{
    margin: 0 0 16px;
    max-width: 70ch;
    color: var(--v2-texte-pale);
    font-size: 14px;
    line-height: 1.55;
}
.v2-partages__form{
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}
.v2-partages__form .v2-champ{ min-width: 240px; }
.v2-partages__form .v2-champ:nth-child(2){ min-width: 150px; }

/* Retour d'action : le lien y figure en clair, il doit pouvoir etre copie
   d'un glissement, et se couper proprement s'il est long. */
.v2-partages__retour{
    margin: 0 0 16px;
    padding: 10px 12px;
    border-radius: var(--v2-rayon);
    font-size: 14px;
    line-height: 1.5;
    overflow-wrap: anywhere;
    user-select: all;
}
.v2-partages__retour.est-ok{
    border: 1px solid rgba(28, 132, 76, .35);
    background: rgba(28, 132, 76, .08);
}
.v2-partages__retour.est-erreur{
    border: 1px solid rgba(178, 48, 48, .35);
    background: rgba(178, 48, 48, .07);
}
.v2-partages__vide{ margin: 0; color: var(--v2-texte-pale); font-size: 14px; }

/* Partage expire ou retire : la ligne reste, en retrait. */
.v2-partages .v2-tableau tr.est-inactif{ opacity: .55; }

/* ==================================================================
 * Fenetre de la preuve d'achat
 *
 * Le lien menait a l'image seule, dans un onglet nu : on perdait la liste,
 * et il fallait revenir en arriere. La fenetre la montre sur place, avec de
 * quoi la telecharger.
 * ============================================================== */
.v2-preuve-fenetre{
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(20, 18, 16, .62);
}
.v2-preuve-fenetre__boite{
    display: flex;
    flex-direction: column;
    width: min(760px, 100%);
    max-height: 100%;
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
}
.v2-preuve-fenetre__entete{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--v2-bordure-pale);
}
.v2-preuve-fenetre__titre{ margin: 0; font-size: 16px; font-weight: 700; }
.v2-preuve-fenetre__fermer{
    border: 0;
    background: none;
    color: var(--v2-texte-pale);
    font-size: 26px;
    line-height: 1;
    cursor: pointer;
}
.v2-preuve-fenetre__fermer:hover{ color: var(--v2-texte); }

/* Le corps defile : une photo de ticket est souvent tres haute. */
.v2-preuve-fenetre__corps{
    overflow: auto;
    padding: 16px 18px;
    text-align: center;
}
.v2-preuve-fenetre__corps img{
    max-width: 100%;
    height: auto;
    border-radius: 8px;
}
.v2-preuve-fenetre__pied{
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 18px;
    border-top: 1px solid var(--v2-bordure-pale);
}

/* Le lien tout juste cree : lisible, selectionnable, et copiable. */
.v2-partages__lien{
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 16px;
    padding: 10px 12px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface-alt);
}
.v2-partages__lien code{
    flex: 1;
    min-width: 260px;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 12.5px;
    overflow-wrap: anywhere;
    user-select: all;
}

@media (max-width: 640px){
    .v2-preuve-fenetre{ padding: 12px; }
    .v2-preuve-fenetre__pied{ flex-direction: column-reverse; }
    .v2-preuve-fenetre__pied .v2-btn{ width: 100%; }
}

/* Bouton compact, pour une cellule de tableau. */
.v2-btn--mini{ padding: 4px 10px; font-size: 12.5px; }

/* ==================================================================
 * Sélecteur d'émojis
 *
 * Le formulaire d'origine en avait un, porte par une bibliotheque qui exige
 * jQuery. La v2 n'en charge pas : celui-ci est ecrit en JavaScript natif
 * (cf. v2/partials/_emoji.phtml).
 * ============================================================== */
.v2-champ--emoji{ position: relative; }
.v2-emoji{
    position: absolute;
    right: 8px;
    /* Cale sur le champ, dont le libelle occupe le haut de la cellule. */
    bottom: 9px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--v2-texte-pale);
    cursor: pointer;
}
.v2-emoji:hover,
.v2-emoji:focus-visible{ background: var(--v2-surface-alt); color: var(--v2-texte); }
/* Le champ laisse la place au bouton, sinon le texte passe dessous.
   Les zones multilignes aussi : le bouton s'y cale en bas a droite. */
.v2-champ--emoji input[type="text"],
.v2-champ--emoji textarea{ padding-right: 38px; }

.v2-emoji-panneau{
    position: absolute;
    z-index: 120;
    width: 300px;
    max-height: 320px;
    overflow-y: auto;
    padding: 10px 12px 12px;
    border: 1px solid var(--v2-bordure);
    border-radius: var(--v2-rayon);
    background: var(--v2-surface);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
}
.v2-emoji-panneau__titre{
    margin: 8px 0 4px;
    color: var(--v2-texte-pale);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
}
.v2-emoji-panneau__titre:first-child{ margin-top: 0; }
.v2-emoji-panneau__grille{
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}
.v2-emoji-panneau__choix{
    padding: 4px 0;
    border: 0;
    border-radius: 6px;
    background: none;
    font-size: 19px;
    line-height: 1.2;
    cursor: pointer;
}
.v2-emoji-panneau__choix:hover,
.v2-emoji-panneau__choix:focus-visible{ background: var(--v2-surface-alt); }
