/**
 * XoXo Cards - Styles des cartes
 * 
 * Styles pour l'affichage des cartes en grille.
 * 
 * @package XoXo_Cards
 * @since 2.0.0
 * @updated 3.0.0 - Ajout checkbox échangeable, suppression vue liste
 */

/* ============================
   Grille de cartes (4 colonnes)
   ============================ */
.xoxo-cards-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
}

/* v6.0.0 [TACHE 7] BUG-T7 fix : asymetrie 4e colonne dans 'Mes cartes'.
   Classique piege CSS Grid : `1fr` est equivalent a `minmax(auto, 1fr)`.
   Si une cellule contient un element dont la min-content width depasse la
   largeur calculee de `1fr` (image non-constrainted, texte long sans
   word-break, badge/span avec white-space:nowrap, data-testid attribute
   content, nom createur long en header puzzle, etc.), cette cellule
   s'elargit au-dela de 1fr -> les 3 autres colonnes sont compressees a
   proportion, creant l'impression que la "4e colonne est plus grande".
   Le fix universel est `minmax(0, 1fr)` qui force un min-content de 0,
   garantissant des colonnes strictement equivalentes. Applique uniquement
   a `.xoxo-my-cards-grid` (scope tache 7) pour eviter d'impacter les
   autres grilles (Ma Collection, Album, Packs, etc.) par precaution. */
.xoxo-my-cards-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
.xoxo-my-cards-grid > .xoxo-card-item {
    /* v6.0.0 [TACHE 7] : min-width:0 defense au niveau des children pour
       garantir que leur contenu ne force pas la cellule a s'etendre
       au-dela de la largeur du track grid. Complementaire a minmax(0,1fr). */
    min-width: 0;
}
.xoxo-my-cards-grid > .xoxo-card-item > * {
    /* v6.0.0 [TACHE 7] : propager min-width:0 a un niveau supplementaire
       (xoxo-card-image, xoxo-card-info) pour stopper toute propagation
       de contenu debordant (images, noms longs, badges actions-mini). */
    min-width: 0;
}

/* ============================
   Carte individuelle
   ============================ */
.xoxo-card-item {
    background: var(--xoxo-bg);
    border-radius: var(--xoxo-border-radius);
    overflow: hidden;
    /* v8.1.3 [TACHE 187 BUG 4] FIX SACCADE SCROLL ONGLET "TOUTES"
       AVANT v8.1.3 : `transition: all var(--xoxo-transition)` -> anti-pattern
       interdit par les guidelines design (NEVER `transition: all`). Sur l'onglet
       "Toutes" qui contient TOUTES les cartes du plugin (potentiellement 100+),
       le navigateur recompose tous les elements au scroll quand IL CHANGE QUOI
       QUE CE SOIT (border, background, transform, box-shadow, etc.) -> jank
       visible. Les onglets filtres (Bronze/Argent/Or/Diamant/etc.) affichent
       moins de cartes donc l'effet ne se manifestait pas la-bas.
       FIX : transitions ciblees uniquement sur les proprietes effectivement
       animees au :hover (transform + box-shadow + border-color), conformes
       aux guidelines design tokens. Performances : seul le compositing est
       affecte (transform + opacity sont GPU-accelerated), zero jank au scroll. */
    transition: transform var(--xoxo-transition), box-shadow var(--xoxo-transition), border-color var(--xoxo-transition);
    cursor: pointer;
    position: relative;
    box-shadow: var(--xoxo-shadow);
    border: 1px solid var(--xoxo-border);
}

.xoxo-card-item:hover {
    transform: translateY(-4px);
    box-shadow: var(--xoxo-shadow-hover);
}

.xoxo-card-item .xoxo-card-image {
    position: relative;
    width: 100%;
    padding-top: 140%;
    overflow: hidden;
    background: #f5f5f5;
}

.xoxo-card-item .xoxo-card-image img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Badge de niveau */
/* v5.8.6 [TACHE 119] : la couleur du texte est desormais fournie INLINE par le
   rendu (style="color:..."), valeur tiree de xoxo_cards_levels.color_secondary
   (configurable via Reglages > Cartes > "Badges des types de cartes").
   Le fallback `color: #fff` est conserve pour la legacy (rendus tres anciens
   sans color inline) afin d'eviter un texte blanc-sur-blanc cote anciennes vues. */
.xoxo-card-level {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
    color: #fff; /* fallback - override par style inline `color:` */
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* v5.8.6 [TACHE 119] : icone Font Awesome optionnelle prefixant le libelle du badge.
   Espacement faible pour ne pas alourdir le pill. */
.xoxo-card-level > i.fa,
.xoxo-card-level > i.fas,
.xoxo-card-level > i.far,
.xoxo-card-level > i.fab,
.xoxo-card-level > i[class*="fa-"] {
    margin-right: 4px;
    font-size: 0.95em;
    line-height: 1;
}

/* Infos de la carte */
.xoxo-card-info {
    padding: 12px;
}

.xoxo-card-name {
    font-size: 14px;
    font-weight: 600;
    margin: 6px 0 4px;
    color: var(--xoxo-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xoxo-card-stats-mini {
    display: flex;
    gap: 12px;
    font-size: 11px;
    color: var(--xoxo-text-muted);
}

/* Badge quantite */
.xoxo-card-quantity {
    position: absolute;
    top: 8px;
    right: 8px;
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 700;
}

/* Badge double */
.xoxo-card-duplicate {
    position: absolute;
    top: 8px;
    left: 8px;
    background: var(--xoxo-warning);
    color: #000;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
}

/* ============================
   Checkbox échangeable
   ============================ */
.xoxo-card-exchange-toggle {
    position: absolute;
    bottom: 8px;
    right: 8px;
    z-index: 10;
}

.xoxo-card-exchange-checkbox {
    display: none;
}

.xoxo-card-exchange-label {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: rgba(255, 255, 255, 0.95);
    border: 2px solid var(--xoxo-border);
    border-radius: 6px;
    cursor: pointer;
    /* v8.1.5 [TACHE 189 BUG 3] FIX SACCADE SCROLL ONGLET "TOUTES" (suite v8.1.3 BUG 4)
       AVANT v8.1.5 : `transition: all var(--xoxo-transition)` -> meme anti-pattern
       que celui corrige sur .xoxo-card-item en v8.1.3 [TACHE 187 BUG 4] mais oublie
       sur ce selecteur enfant. .xoxo-card-exchange-label est rendu DANS chaque
       .xoxo-card-item (label trade <-> rose). Sur l'onglet "Toutes" (~100+ cartes
       affichees simultanement), 100+ instances de ce label avec `transition: all`
       declenchent du jank au scroll des que le browser recompose un sous-element
       (focus, hover bubbling, reflow declenche par lazy-load img, etc.).
       FIX : transitions ciblees uniquement sur les proprietes effectivement
       animees au :hover (background-color, border-color, transform). */
    transition: background-color var(--xoxo-transition), border-color var(--xoxo-transition), transform var(--xoxo-transition);
    font-size: 14px;
}

/* ============================
   Carte - Badge de statut
   ============================ */
/* v5.3.1 : Badge de statut centre horizontalement et verticalement.
   Robustesse anti-debordement : nowrap force + max-width + overflow ellipsis en filet de securite.
   Visuel harmonise avec l'esthetique du plugin (shadow + border-radius + uppercase). */
.xoxo-card-status-badge {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    z-index: 5;
    white-space: nowrap;
    max-width: calc(100% - 20px);
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center;
    box-shadow: 0 3px 10px rgba(0,0,0,0.25);
    line-height: 1.3;
}

.xoxo-status-pending {
    background: linear-gradient(135deg, rgba(255, 193, 7, 0.98) 0%, rgba(245, 158, 11, 0.98) 100%);
    color: #000;
    border: 1px solid rgba(180, 130, 0, 0.4);
}

.xoxo-status-approved {
    background: linear-gradient(135deg, rgba(34, 197, 94, 0.98) 0%, rgba(22, 163, 74, 0.98) 100%);
    color: #fff;
}

.xoxo-status-rejected {
    background: linear-gradient(135deg, rgba(220, 53, 69, 0.98) 0%, rgba(185, 28, 28, 0.98) 100%);
    color: #fff;
}

/* Actions mini sur les cartes */
.xoxo-card-actions-mini {
    display: flex;
    gap: 6px;
    margin-top: 8px;
    justify-content: center;
}

/* v5.3.2 : Boutons Modifier / Supprimer sous la vignette — couleurs explicites
   pour eviter l'heritage du theme parent (SocialV force color:#fff sur certains containers).
   v5.3.3+ : Icone SVG UNIQUEMENT (pas de label texte) conforme demande utilisateur.
   Format compact 34x34px, identification visuelle via SVG + title/aria-label. */
.xoxo-card-actions-mini .xoxo-btn-icon {
    width: 34px !important;
    height: 34px !important;
    padding: 0 !important;
    border: 1px solid #d1d5db !important;
    background: #ffffff !important;
    border-radius: 6px !important;
    cursor: pointer;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 14px !important;
    color: #4b5563 !important;
    line-height: 1 !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
    /* v8.1.5 [TACHE 189 BUG 3] FIX SACCADE SCROLL ONGLET "TOUTES" (suite v8.1.3 BUG 4)
       Meme correction que .xoxo-card-item / .xoxo-card-exchange-label : transition:all
       interdit dans les selecteurs enfants des cartes a forte densite. */
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
    text-decoration: none !important;
}

.xoxo-card-actions-mini .xoxo-btn-icon i,
.xoxo-card-actions-mini .xoxo-btn-icon svg {
    color: inherit !important;
    stroke: currentColor !important;
    font-size: 14px;
    display: inline-block;
}

.xoxo-card-actions-mini .xoxo-edit-card:hover {
    background: #FF00AA !important;
    border-color: #FF00AA !important;
    color: #ffffff !important;
    box-shadow: 0 2px 8px rgba(255, 0, 170, 0.35);
    transform: translateY(-1px);
}

.xoxo-card-actions-mini .xoxo-delete-card {
    color: #dc3545 !important;
    border-color: #f5c6cb !important;
}

.xoxo-card-actions-mini .xoxo-delete-card:hover {
    background: #dc3545 !important;
    border-color: #dc3545 !important;
    color: #ffffff !important;
    box-shadow: 0 2px 8px rgba(220, 53, 69, 0.35);
    transform: translateY(-1px);
}

.xoxo-btn-icon {
    width: 28px;
    height: 28px;
    border: 1px solid var(--xoxo-border);
    background: var(--xoxo-bg);
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: var(--xoxo-text);
    transition: all var(--xoxo-transition);
}

.xoxo-btn-icon:hover {
    border-color: var(--xoxo-primary);
    color: var(--xoxo-primary);
    background: var(--xoxo-primary-light);
}

.xoxo-btn-icon-danger {
    color: #dc3545;
    border-color: #f5c6cb;
}

.xoxo-btn-icon-danger:hover {
    color: #fff;
    background: #dc3545;
    border-color: #dc3545;
}

/* Modal générateur large */
.xoxo-generator-modal {
    max-width: 800px;
}

.xoxo-card-exchange-label:hover {
    border-color: var(--xoxo-primary);
    background: var(--xoxo-primary-light);
}

.xoxo-card-exchange-checkbox:checked + .xoxo-card-exchange-label,
/* v8.1.3 [TACHE 187 BUG 1] FALLBACK DEFENSIF : si la classe .xoxo-card-exchangeable
   est presente sur la carte (etat sauvegarde cote serveur), forcer le visuel rose
   du label MEME si la checkbox a perdu son etat :checked au reload (resilience aux
   ecrasements de cache navigateur ou problemes de serialisation API). Belt-and-suspenders
   ensemble avec le fix B (PHP cast explicite int sur is_available_for_exchange). */
.xoxo-card-item.xoxo-card-exchangeable .xoxo-card-exchange-label {
    background: var(--xoxo-primary);
    border-color: var(--xoxo-primary);
    color: #fff;
    box-shadow: var(--xoxo-primary-glow);
}

.xoxo-card-exchange-label::after {
    content: '↔';
}

/* v5.2.0 : Indicateur ↔ rose pour les autres membres (lecture seule) */
.xoxo-card-exchange-indicator {
    position: absolute;
    bottom: 8px;
    right: 8px;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: #FF00AA;
    border: 2px solid #FF00AA;
    border-radius: 6px;
    color: #fff;
    font-size: 14px;
    box-shadow: 0 0 12px rgba(255, 0, 170, 0.4);
    pointer-events: none;
}

.xoxo-card-exchange-indicator::after {
    content: '↔';
}

/* Étiquette "Disponible à l'échange" */
.xoxo-card-available-badge {
    position: absolute;
    bottom: 60px;
    left: 0;
    right: 0;
    background: linear-gradient(90deg, var(--xoxo-primary), #FF66CC);
    color: #fff;
    padding: 6px 10px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    text-align: center;
    letter-spacing: 0.5px;
    box-shadow: 0 2px 8px rgba(255, 0, 170, 0.3);
}

/* v5.2.4/5 : Badge serie X/Y — strictement identique a .xoxo-card-level et .xoxo-card-badge
   Inline-block pur, sans icone, memes padding/radius/font pour hauteur uniforme. */
.xoxo-card-series-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    line-height: 1.3;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    background: #6b7280;
    color: #fff;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: baseline;
}

.xoxo-card-series-badge.xoxo-series-complete {
    background: #22c55e;
    color: #fff;
}

.xoxo-card-item.xoxo-card-exchangeable {
    border-color: var(--xoxo-primary);
}

.xoxo-card-item.xoxo-card-exchangeable:hover {
    box-shadow: var(--xoxo-primary-glow), var(--xoxo-shadow-hover);
}

/* ============================
   Carte non possedee (album) - Floutage
   ============================ */
.xoxo-card-item.xoxo-card-missing {
    opacity: 0.85;
}

/* v7.0.11 [TACHE 162] REFONTE - Regle de floutage UNIFIEE pour TOUTES les cartes
   non possedees du FO (uniques, series, puzzle), quel que soit le contexte
   (Ma collection / Album autre membre / Modal echanges / Wishlist / Popup
   detail / Modal d'ajout). Avant v7.0.11 : les regles divergaient :
     - Liste/grille : blur(8px) grayscale(0.5)  -> 50% couleur encore visible !
     - Popup detail : grayscale(1) blur(6px) (cards.css) ou
                      grayscale(100%) blur(6px) (card-detail.css, duplique)
     - Pieces puzzle : grayscale(100%) blur(3px)
   Apres v7.0.11 : regle UNIFIEE et stricte
     - filter: grayscale(100%) blur(8px) partout
     - opacity: 0.9 (legere transparence pour signaler l'etat verrouille)
     - + overlay logo XoXo Cards centre absolu (cf .xoxo-card-image::after
       ci-dessous) pour renforcer le masquage commercial.
   CIBLE UNIQUEMENT l'image principale via selector direct-child `>` -> protege
   automatiquement les images enfants indirects (notamment l'avatar du createur
   dans .xoxo-card-avatar-zone) qui doit RESTER NET pour la reconnaissance
   sociale (regle produit confirmee TACHE 90). */
.xoxo-card-item.xoxo-card-missing .xoxo-card-image > img {
    filter: grayscale(100%) blur(8px);
    -webkit-filter: grayscale(100%) blur(8px);
    will-change: filter;
}

/* Garde-fou explicite : l'avatar du createur ne doit JAMAIS etre floute. La regle
   ci-dessus l'exclue deja via `> img`, mais on renforce en explicite pour etre
   defensif contre d'eventuelles surcharges de theme (SocialV, BuddyPress) qui
   pourraient re-cibler les img descendantes. */
.xoxo-card-item.xoxo-card-missing .xoxo-card-avatar-zone,
.xoxo-card-item.xoxo-card-missing .xoxo-card-avatar-zone img {
    filter: none !important;
    -webkit-filter: none !important;
    opacity: 1 !important;
}

.xoxo-card-item.xoxo-card-missing .xoxo-card-image {
    overflow: hidden;
    border-radius: var(--xoxo-border-radius);
    position: relative; /* v7.0.11 : indispensable pour le positionnement absolu de l'overlay logo */
}

/* v7.0.11 [TACHE 162] OVERLAY LOGO - Logo XoXo Cards superpose en centrage
   absolu sur les cartes non possedees pour renforcer le masquage commercial
   (au-dela du seul grayscale + blur). Logo blanc (visible sur fond gris flou),
   ~50% de la largeur de la zone image (decision Q3.B), centre vertical et
   horizontal absolu. Le logo est asset embarque dans le plugin
   (public/assets/images/logo-overlay.png) - aucune dependance externe.
   pointer-events: none pour ne pas bloquer le clic sur la carte (qui ouvre
   la popup detail). */
.xoxo-card-item.xoxo-card-missing .xoxo-card-image::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 50%;
    height: 50%;
    background-image: url('../images/logo-overlay.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
    z-index: 5;
    opacity: 0.95;
    /* v7.0.11 : drop-shadow leger pour detacher le logo du fond gris flou */
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));
    -webkit-filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));
}

/* v5.2.4 : Retrait du point d'interrogation "?" au centre des cartes non possedees.
   Le floutage (filter: blur + grayscale) reste actif via .xoxo-card-image img ci-dessus. */

/* ============================
   Carte épuisée (stock = 0)
   ============================ */
.xoxo-card-item.xoxo-card-exhausted {
    opacity: 0.6;
}

/* v5.5.4 [TACHE 90 BUG 1] Meme principe anti-avatar-ecrasement que .xoxo-card-missing :
   le grayscale s'applique UNIQUEMENT a l'image principale via `> img`, l'avatar
   dans `.xoxo-card-avatar-zone > img` reste en couleur. */
.xoxo-card-item.xoxo-card-exhausted .xoxo-card-image > img {
    filter: grayscale(100%);
}

/* v5.5.7 [TACHE 93 BUG E] Protection avatar dans la POPUP detail carte (pas la vignette).
   La popup utilise le wrapper `.xoxo-detail-card-wrapper` qui applique `xoxo-detail-grayscale`
   sur le container pour les cartes non-possedees. Precedemment le filtre etait applique via
   l'ancien systeme (peut-etre via theme heritance) qui floutait aussi l'avatar present dans
   `.xoxo-card-avatar-zone > img`. Fix dedie : on cible l'image principale ET on exempte
   explicitement l'avatar, coherent avec les vignettes de Ma Collection (regles produit d
   confirmees en TACHE 90). */
/* v7.0.11 [TACHE 162] REFONTE - Popup detail carte (alignement strict avec la
   regle unifiee du FO : grayscale(100%) blur(8px) au lieu de l'ancien
   grayscale(1) blur(6px) qui creait une incoherence visuelle entre la vignette
   de la grille et la popup detail). Le wrapper .xoxo-detail-card-wrapper
   applique la classe xoxo-detail-grayscale conditionnellement quand la carte
   n'est pas possedee par le viewer courant. */
.xoxo-detail-card-wrapper.xoxo-detail-grayscale img {
    filter: grayscale(100%) blur(8px);
    -webkit-filter: grayscale(100%) blur(8px);
    opacity: 0.9;
    transition: filter 0.3s ease;
}

/* v7.0.11 [TACHE 162] OVERLAY LOGO - Meme principe que la vignette grille :
   logo XoXo Cards centre absolu sur la popup detail des cartes non possedees.
   ~50% de la largeur de la zone image (decision Q3.B). Le wrapper doit etre
   en position relative pour le centrage absolu de ::after. */
.xoxo-detail-card-wrapper.xoxo-detail-grayscale {
    position: relative;
}
.xoxo-detail-card-wrapper.xoxo-detail-grayscale::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 50%;
    height: 50%;
    background-image: url('../images/logo-overlay.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
    z-index: 5;
    opacity: 0.95;
    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.5));
    -webkit-filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.5));
}
.xoxo-detail-card-wrapper .xoxo-card-avatar-zone,
.xoxo-detail-card-wrapper .xoxo-card-avatar-zone img,
.xoxo-detail-card-wrapper.xoxo-detail-grayscale .xoxo-card-avatar-zone,
.xoxo-detail-card-wrapper.xoxo-detail-grayscale .xoxo-card-avatar-zone img {
    filter: none !important;
    opacity: 1 !important;
    -webkit-filter: none !important;
}

.xoxo-card-exhausted-badge {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-15deg);
    background: linear-gradient(135deg, #dc3545, #c82333);
    color: #fff;
    padding: 8px 16px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    box-shadow: 0 2px 8px rgba(220, 53, 69, 0.4);
    z-index: 5;
    white-space: nowrap;
}

/* ============================
   Carte specifique par niveau
   ============================ */
.xoxo-card-coquine {
    border: 2px solid transparent;
}

.xoxo-card-coquine:hover {
    border-color: var(--xoxo-coquine);
}

.xoxo-card-sexy {
    border: 2px solid transparent;
}

.xoxo-card-sexy:hover {
    border-color: var(--xoxo-sexy);
}

.xoxo-card-xoxo {
    border: 2px solid transparent;
}

.xoxo-card-xoxo:hover {
    border-color: var(--xoxo-xoxo);
}

.xoxo-card-club {
    border: 2px solid transparent;
}

.xoxo-card-club:hover {
    border-color: var(--xoxo-club);
}

.xoxo-card-rares,
.xoxo-card-rarissime {
    border: 2px solid var(--xoxo-rares);
    background: linear-gradient(135deg, #1a1a2e, #16213e);
}

.xoxo-card-rares .xoxo-card-info,
.xoxo-card-rarissime .xoxo-card-info {
    color: #fff;
}

.xoxo-card-rares .xoxo-card-name,
.xoxo-card-rarissime .xoxo-card-name {
    color: var(--xoxo-rares);
}

.xoxo-card-partenaire {
    border: 2px solid var(--xoxo-partenaire);
}

.xoxo-card-evenement {
    border: 2px solid var(--xoxo-evenement);
}

/* ============================
   Echanges - Liste
   ============================ */
.xoxo-exchanges-list .xoxo-exchange-item {
    display: flex;
    align-items: center;
    padding: 16px;
    border: 1px solid var(--xoxo-border);
    border-radius: var(--xoxo-border-radius);
    margin-bottom: 12px;
    transition: all var(--xoxo-transition);
}

.xoxo-exchange-item:hover {
    border-color: var(--xoxo-primary);
}

.xoxo-exchange-info {
    flex: 1;
}

.xoxo-exchange-users {
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 4px;
}

.xoxo-exchange-cards-summary {
    font-size: 13px;
    color: var(--xoxo-text-light);
}

.xoxo-exchange-status {
    padding: 4px 12px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
}

.xoxo-exchange-status.pending {
    background: var(--xoxo-warning);
    color: #000;
}

.xoxo-exchange-status.accepted,
.xoxo-exchange-status.completed {
    background: var(--xoxo-success);
    color: #fff;
}

.xoxo-exchange-status.rejected,
.xoxo-exchange-status.cancelled {
    background: var(--xoxo-danger);
    color: #fff;
}

.xoxo-exchange-status.expired {
    background: var(--xoxo-text-muted);
    color: #fff;
}

.xoxo-exchange-actions {
    display: flex;
    gap: 8px;
    margin-left: 16px;
}

/* ===========================================================
   v8.1.5 [TACHE 189 BUG 2] REFONTE UX ECHANGES RECUS
   Layout 3 colonnes (info | resume cartes | actions empilees) +
   boutons outlined uniformes avec icones FA + responsive < 540px.
   Reference visuelle : page /membres (annuaire BuddyPress).

   v8.1.6 [TACHE 190 BUG STATUS-STRETCHED] HOTFIX :
   - align-items: stretch -> flex-start pour eviter le stretch absurde
     du badge .xoxo-exchange-status (le badge est maintenant integre
     DANS .xoxo-exchange-info via le wrapper .xoxo-exchange-badges).
   - Les 3 colonnes gardent leur hauteur naturelle ; les boutons
     empiles dictent indirectement la hauteur du conteneur via leur
     contenu mais aucune autre colonne n'est etiree de force.
   =========================================================== */
.xoxo-exchanges-list .xoxo-exchange-item {
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 16px;
}
.xoxo-exchanges-list .xoxo-exchange-info {
    /* Premiere colonne : avatar/pseudo/date/statut/badges */
    flex: 0 0 auto;
    min-width: 220px;
    max-width: 280px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 6px;
}
.xoxo-exchanges-list .xoxo-exchange-cards-summary {
    /* Deuxieme colonne : resume cartes proposees avec mini-thumbnails */
    flex: 1 1 280px;
    min-width: 0;
    align-self: flex-start;
    margin: 0;
    padding: 0 8px;
    border-left: 1px dashed #e5e7eb;
    border-right: 1px dashed #e5e7eb;
}
.xoxo-exchanges-list .xoxo-exchange-actions {
    /* Troisieme colonne : boutons EMPILES verticalement */
    flex: 0 0 auto;
    margin-left: 0;
    width: 200px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}

/* Boutons outlined uniformes (Q2=c) avec icones FA core en prefixe.
   Hierarchie visuelle preservee : Accepter en rose plein (action principale). */
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn {
    width: 100%;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    text-align: left;
    line-height: 1.2;
    /* Transitions ciblees (anti-pattern transition:all evite, cf BUG 3) */
    transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, transform 0.12s ease;
}
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn i {
    font-size: 13px;
    width: 14px;
    text-align: center;
    flex-shrink: 0;
}
/* Style outlined par defaut (Refuser / Contre-proposer / Voir / Bloquer) */
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-outline {
    background: #ffffff;
    color: #374151;
    border: 1px solid #d1d5db;
}
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-outline:hover {
    background: #f9fafb;
    border-color: #FF00AA;
    color: #FF00AA;
}
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-block-user:hover {
    background: #fef2f2;
    border-color: #dc2626;
    color: #dc2626;
}
/* Bouton Accepter : rose plein (action principale) */
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-accept {
    background: #FF00AA;
    color: #ffffff !important;
    border: 1px solid #FF00AA;
}
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-accept:hover:not(:disabled):not(.xoxo-btn-disabled) {
    background: #d6008d;
    border-color: #d6008d;
}
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-accept.xoxo-btn-disabled,
.xoxo-exchanges-list .xoxo-exchange-actions .xoxo-btn-accept:disabled {
    background: #fbcfe8;
    border-color: #fbcfe8;
    cursor: not-allowed;
    opacity: 0.7;
}

/* Resume cartes : labels + chips inline */
.xoxo-exchanges-list .xoxo-exchange-summary-row {
    display: block;
}
.xoxo-exchanges-list .xoxo-exchange-summary-label {
    line-height: 1;
}
.xoxo-exchanges-list .xoxo-exchange-summary-list {
    line-height: 1.2;
}
.xoxo-exchanges-list .xoxo-exchange-thumb {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

/* Responsive < 540px : empilage vertical complet (Q5=a) */
@media (max-width: 540px) {
    .xoxo-exchanges-list .xoxo-exchange-item {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    .xoxo-exchanges-list .xoxo-exchange-info,
    .xoxo-exchanges-list .xoxo-exchange-cards-summary,
    .xoxo-exchanges-list .xoxo-exchange-actions {
        max-width: 100%;
        min-width: 0;
        width: 100%;
        margin-left: 0;
        padding: 0;
        border: none;
    }
    .xoxo-exchanges-list .xoxo-exchange-cards-summary {
        padding-top: 8px;
        padding-bottom: 8px;
        border-top: 1px dashed #e5e7eb;
        border-bottom: 1px dashed #e5e7eb;
    }
}
@media (min-width: 541px) and (max-width: 820px) {
    /* Tablette : info + actions sur 2 colonnes, resume sur ligne complete */
    .xoxo-exchanges-list .xoxo-exchange-cards-summary {
        flex: 1 1 100%;
        order: 3;
        border-left: none;
        border-right: none;
        border-top: 1px dashed #e5e7eb;
        padding: 8px 0 0;
    }
}
/* === FIN [TACHE 189 BUG 2] === */

/* ============================
   Puzzles
   ============================ */
.xoxo-puzzles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
}

.xoxo-puzzle-card {
    background: var(--xoxo-bg);
    border: 2px solid var(--xoxo-border);
    border-radius: 16px;
    padding: 24px;
    transition: all var(--xoxo-transition);
}

.xoxo-puzzle-card:hover {
    border-color: var(--xoxo-rares);
    box-shadow: var(--xoxo-shadow-hover);
}

.xoxo-puzzle-card.complete {
    border-color: var(--xoxo-success);
    background: linear-gradient(135deg, #f0fff0, #e8f5e9);
}

.xoxo-puzzle-name {
    font-size: 18px;
    font-weight: 700;
    margin: 0 0 8px;
}

.xoxo-puzzle-club {
    font-size: 13px;
    color: var(--xoxo-text-muted);
    margin-bottom: 16px;
}

.xoxo-puzzle-pieces-grid {
    display: grid;
    gap: 4px;
    margin-bottom: 16px;
}

/* v5.4.8 [TACHE 84 BUG 3b] Grilles completes pour TOUTES les decoupes supportees
   par le plugin (3, 4, 6, 8, 9, 12 pieces), conformes a la demande utilisateur :
   - 3 cartes  -> 3 colonnes x 1 ligne
   - 4 cartes  -> 2 colonnes x 2 lignes
   - 6 cartes  -> 3 colonnes x 2 lignes
   - 8 cartes  -> 4 colonnes x 2 lignes
   - 9 cartes  -> 3 colonnes x 3 lignes
   - 12 cartes -> 4 colonnes x 3 lignes */
.xoxo-puzzle-pieces-grid.grid-3x1 {
    grid-template-columns: repeat(3, 1fr);
}

.xoxo-puzzle-pieces-grid.grid-2x2 {
    grid-template-columns: repeat(2, 1fr);
}

.xoxo-puzzle-pieces-grid.grid-3x2 {
    grid-template-columns: repeat(3, 1fr);
}

.xoxo-puzzle-pieces-grid.grid-4x2 {
    grid-template-columns: repeat(4, 1fr);
}

.xoxo-puzzle-pieces-grid.grid-3x3 {
    grid-template-columns: repeat(3, 1fr);
}

.xoxo-puzzle-pieces-grid.grid-4x3 {
    grid-template-columns: repeat(4, 1fr);
}

/* v5.4.8 [TACHE 84 BUG 4] Ligne createur (avatar + pseudo cote a cote). */
.xoxo-puzzle-creator-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 12px;
}
.xoxo-puzzle-creator-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    border: 1.5px solid #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.xoxo-puzzle-creator-row .xoxo-puzzle-club {
    font-size: 13px;
    color: var(--xoxo-text-muted, #666);
    margin: 0;
    line-height: 1.2;
}

/* v5.4.8 [TACHE 84 BUG 5+6+7] + v5.4.9 [TACHE 85 BUG 2] Bloc recompense puzzle. 
   Marge bas de 25px pour aerer l'espace entre le bloc et le bouton "Obtenir le cadeau"
   (conforme demande utilisateur TACHE 85 BUG 2). */
.xoxo-puzzle-reward-block {
    margin-top: 12px;
    margin-bottom: 25px;
    padding: 10px 12px;
    background: #fff7fb;
    border: 1px solid #ffe0f0;
    border-radius: 8px;
}
.xoxo-puzzle-reward-type {
    display: inline-block;
    padding: 3px 10px;
    background: #FF00AA;
    color: #fff;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    margin-bottom: 6px;
}
.xoxo-puzzle-reward-label {
    font-size: 12px;
    font-weight: 600;
    color: #555;
    margin-bottom: 4px;
}
.xoxo-puzzle-reward-desc {
    font-size: 13px;
    color: #333;
    line-height: 1.4;
}
.xoxo-puzzle-reward-validity {
    font-size: 11px;
    color: #888;
    font-style: italic;
    margin-top: 4px;
}
.xoxo-puzzle-reward-claimed-badge {
    display: inline-block;
    margin-top: 12px;
    padding: 8px 16px;
    background: #e8f7ef;
    color: #16a34a;
    border: 1px solid #86efac;
    border-radius: 8px;
    font-weight: 700;
    font-size: 13px;
}
/* v5.4.8 [TACHE 84 BUG 7] + v5.5.2 [TACHE 88 BUG 3] Etat VISUEL desactive du bouton
   "Obtenir le cadeau" tant que le puzzle n'est pas integralement complete.
   v5.5.2 : renforcement du contraste disabled vs enabled (demandes utilisateur repetees).
   Etat disabled : fond gris clair (#e5e7eb), texte gris fonce (#9ca3af), aucune ombre.
   Etat enabled  : fond rose XoXo #FF00AA ecclatant, ombre rose subtile, curseur pointer. */
.xoxo-claim-puzzle-reward {
    transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.12s ease;
}
.xoxo-claim-puzzle-reward:not(:disabled):not([disabled]) {
    background: #FF00AA !important;
    color: #fff !important;
    box-shadow: 0 3px 10px rgba(255, 0, 170, 0.28);
}
.xoxo-claim-puzzle-reward:not(:disabled):not([disabled]):hover {
    background: #e6009a !important;
    transform: translateY(-1px);
    box-shadow: 0 5px 14px rgba(255, 0, 170, 0.38);
}
.xoxo-claim-puzzle-reward:disabled,
.xoxo-claim-puzzle-reward[disabled] {
    opacity: 0.65 !important;
    cursor: not-allowed !important;
    background: #e5e7eb !important;
    color: #9ca3af !important;
    border-color: #e5e7eb !important;
    box-shadow: none !important;
    text-shadow: none !important;
    pointer-events: none;
}
.xoxo-claim-puzzle-reward:disabled:hover,
.xoxo-claim-puzzle-reward[disabled]:hover {
    background: #e5e7eb !important;
    color: #9ca3af !important;
    transform: none !important;
    box-shadow: none !important;
}

/* v5.4.9 [TACHE 85 BUG 3] + v5.5.2 [TACHE 88 BUG 2] + v5.5.3 [TACHE 89 BUG 2]
   Bouton "Supprimer" (corbeille + texte) visible dans l'angle superieur droit de la
   vignette du puzzle. Visible UNIQUEMENT pour le createur du puzzle. Click
   stop-propagation => ne declenche pas l'ouverture de la popup detail.
   v5.5.3 : le theme SocialV / BuddyPress applique sur les boutons des regles parent
   (flex-direction:column dans certains conteneurs grid) qui forcaient l'empilement
   icone au-dessus du label. Fix : hardening de specificite avec !important strategique
   sur flex-direction, flex-wrap et les dimensions du SVG pour imposer absolument la
   presentation icone-ET-label-sur-une-meme-ligne quelle que soit la cascade CSS
   environnante. */
.xoxo-puzzle-delete-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 5;
    min-height: 30px !important;
    display: inline-flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    padding: 6px 12px 6px 10px !important;
    border: none;
    border-radius: 18px !important;
    background: #dc2626 !important;
    color: #fff !important;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(220,38,38,0.25);
    transition: background 0.18s ease, transform 0.12s ease, box-shadow 0.18s ease;
    outline: none !important;
    -webkit-appearance: none !important;
    appearance: none !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    letter-spacing: 0.2px !important;
    text-transform: none !important;
    white-space: nowrap !important;
    width: auto !important;
    height: auto !important;
    vertical-align: middle;
}
.xoxo-puzzle-delete-btn:hover {
    background: #b91c1c !important;
    transform: scale(1.04);
    box-shadow: 0 3px 10px rgba(220,38,38,0.35);
}
.xoxo-puzzle-delete-btn:active {
    transform: scale(0.97);
}
.xoxo-puzzle-delete-btn:disabled {
    cursor: not-allowed;
    background: #999 !important;
    transform: none !important;
}
.xoxo-puzzle-delete-btn::before,
.xoxo-puzzle-delete-btn::after,
.xoxo-puzzle-delete-btn:hover::before,
.xoxo-puzzle-delete-btn:hover::after,
.xoxo-puzzle-delete-btn:focus::before,
.xoxo-puzzle-delete-btn:focus::after {
    content: none !important;
    display: none !important;
}
.xoxo-puzzle-delete-btn > svg {
    display: inline-block !important;
    pointer-events: none !important;
    flex-shrink: 0 !important;
    vertical-align: middle !important;
    width: 14px !important;
    height: 14px !important;
    margin: 0 !important;
}
.xoxo-puzzle-delete-btn .xoxo-puzzle-delete-btn-label {
    display: inline-block !important;
    color: #fff !important;
    pointer-events: none !important;
    white-space: nowrap !important;
    text-transform: none !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    vertical-align: middle !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* v5.5.3 [TACHE 89 BUG 3b] Bouton "Modifier" : memes principes que Supprimer, mais
   couleur bleue #3b82f6 pour distinguer l'action editable de l'action destructive.
   Positionne a GAUCHE du bouton Supprimer pour etre cote a cote.
   v5.6.0 [TACHE 96] Ecart strict de 25px entre les deux boutons : le bouton Supprimer
   est a right:10px avec une largeur rendue de ~98px (icone 14 + gap 6 + texte 60 +
   padding 6/12/6/10). L'offset du bouton Modifier devient donc 10 + 98 + 25 = 133px
   pour garantir un gap visuel constant de 25px. */
.xoxo-puzzle-edit-btn {
    position: absolute;
    top: 10px;
    right: 133px;
    z-index: 5;
    min-height: 30px !important;
    display: inline-flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    padding: 6px 12px 6px 10px !important;
    border: none;
    border-radius: 18px !important;
    background: #3b82f6 !important;
    color: #fff !important;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(59,130,246,0.25);
    transition: background 0.18s ease, transform 0.12s ease, box-shadow 0.18s ease;
    outline: none !important;
    -webkit-appearance: none !important;
    appearance: none !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    letter-spacing: 0.2px !important;
    text-transform: none !important;
    white-space: nowrap !important;
    width: auto !important;
    height: auto !important;
    vertical-align: middle;
}
.xoxo-puzzle-edit-btn:hover {
    background: #2563eb !important;
    transform: scale(1.04);
    box-shadow: 0 3px 10px rgba(59,130,246,0.35);
}
.xoxo-puzzle-edit-btn:active {
    transform: scale(0.97);
}
.xoxo-puzzle-edit-btn::before,
.xoxo-puzzle-edit-btn::after,
.xoxo-puzzle-edit-btn:hover::before,
.xoxo-puzzle-edit-btn:hover::after,
.xoxo-puzzle-edit-btn:focus::before,
.xoxo-puzzle-edit-btn:focus::after {
    content: none !important;
    display: none !important;
}
.xoxo-puzzle-edit-btn > svg {
    display: inline-block !important;
    pointer-events: none !important;
    flex-shrink: 0 !important;
    vertical-align: middle !important;
    width: 14px !important;
    height: 14px !important;
    margin: 0 !important;
}
.xoxo-puzzle-edit-btn .xoxo-puzzle-edit-btn-label {
    display: inline-block !important;
    color: #fff !important;
    pointer-events: none !important;
    white-space: nowrap !important;
    text-transform: none !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    vertical-align: middle !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* v5.4.9 [TACHE 85 BUG 1] Barre de filtres par type de grille (nombre de pieces).
   Positionnee sous la barre de filtres par statut, avant la grille des puzzles.
   v5.5.2 [TACHE 88 BUG 1] Restructuration en 2 rangees centrees :
   - row-top    : label + bouton "Toutes"
   - row-bottom : les 6 boutons de taille (3/4/6/8/9/12) alignes sur UNE ligne. */
.xoxo-puzzle-grid-filters {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    margin: 6px 0 18px;
    padding: 10px 14px;
    background: #fafafa;
    border-radius: 8px;
    border: 1px solid #eee;
}
.xoxo-puzzle-grid-filters-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    justify-content: center;
}
.xoxo-puzzle-grid-filters-row-top {
    /* Rangee 1 : label + "Toutes" centres */
    gap: 12px;
}
.xoxo-puzzle-grid-filters-row-bottom {
    /* Rangee 2 : tous les boutons de taille centres, saut de ligne possible uniquement
       sur tres petits ecrans (grace a flex-wrap:wrap ci-dessus). */
    gap: 8px;
}
.xoxo-puzzle-grid-filters .xoxo-filter-label {
    font-size: 11px;
    font-weight: 700;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin-right: 0;
}
.xoxo-puzzle-grid-filter {
    padding: 5px 12px !important;
    font-size: 12px !important;
    border-radius: 6px !important;
    font-weight: 600 !important;
}
.xoxo-puzzle-grid-filter.active {
    background: #FF00AA !important;
    color: #fff !important;
    border-color: #FF00AA !important;
}

/* v5.5.0 [TACHE 86] Modale de confirmation suppression puzzle enrichie (preview compensation). */
#xoxo-delete-puzzle-modal .xoxo-delpuz-content {
    max-width: 560px;
    width: 94%;
    padding: 0;
    overflow: hidden;
    border-radius: 16px;
}
.xoxo-delpuz-body { padding: 32px 28px 28px; }
.xoxo-delpuz-header { text-align: center; margin-bottom: 22px; }
.xoxo-delpuz-icon {
    display: inline-flex;
    width: 60px; height: 60px;
    align-items: center; justify-content: center;
    background: linear-gradient(135deg, #fee2e2, #fecaca);
    color: #dc2626;
    border-radius: 50%;
    margin-bottom: 12px;
}
.xoxo-delpuz-title { font-size: 22px; font-weight: 800; margin: 0 0 6px; color: #1f2937; }
.xoxo-delpuz-subtitle { font-size: 15px; color: #6b7280; margin: 0; font-weight: 600; }

/* v5.5.0 [TACHE 86] Message d'avertissement bienveillant affiche AVANT le recap chiffre.
   Ton non-accusateur : rappelle la valeur des puzzles et invite a reflechir avant de supprimer. */
.xoxo-delpuz-advisory {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: 16px 18px;
    margin: 18px 0 0;
    background: linear-gradient(135deg, #fff1f7 0%, #fef6fb 100%);
    border: 1px solid #fbcfe8;
    border-left: 4px solid #FF00AA;
    border-radius: 12px;
}
.xoxo-delpuz-advisory.neutral {
    background: #f9fafb;
    border-color: #e5e7eb;
    border-left-color: #9ca3af;
}
.xoxo-delpuz-advisory-icon {
    flex-shrink: 0;
    width: 38px; height: 38px;
    display: inline-flex;
    align-items: center; justify-content: center;
    background: #fff;
    color: #FF00AA;
    border-radius: 50%;
    box-shadow: 0 2px 4px rgba(255, 0, 170, 0.12);
}
.xoxo-delpuz-advisory.neutral .xoxo-delpuz-advisory-icon { color: #6b7280; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.xoxo-delpuz-advisory-content { flex: 1; font-size: 13.5px; line-height: 1.6; color: #4b5563; }
/* v5.5.3 [TACHE 89 BUG 3a] Correctif critique : precedemment `.xoxo-delpuz-advisory-content strong`
   avait `display: block` (pour styler le titre "Avant de supprimer..."), ce qui forcait
   CHAQUE <strong> du texte a se mettre sur une ligne dediee. Les emphases inline type
   "modifier votre puzzle" / "compensation automatique en points" / "notification bienveillante"
   etaient donc cassees en 5+ morceaux illisibles. Fix : display:block reserve UNIQUEMENT
   au titre via la classe dediee `.xoxo-delpuz-advisory-title`. Les <strong> dans les
   paragraphes gardent leur display:inline natif. */
.xoxo-delpuz-advisory-content .xoxo-delpuz-advisory-title {
    display: block;
    font-size: 15px;
    color: #1f2937;
    margin: 0 0 10px;
    font-weight: 700;
}
.xoxo-delpuz-advisory-content strong { display: inline; }
.xoxo-delpuz-advisory-content p {
    margin: 0 0 10px;
    line-height: 1.6;
}
.xoxo-delpuz-advisory-content p:last-child { margin-bottom: 0; }

.xoxo-delpuz-impact {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin: 18px 0 8px;
    padding: 16px;
    background: #fafafa;
    border: 1px solid #eee;
    border-radius: 12px;
}
.xoxo-delpuz-stat { text-align: center; padding: 10px 4px; border-right: 1px solid #e5e7eb; }
.xoxo-delpuz-stat:last-child { border-right: none; }
.xoxo-delpuz-stat-value { font-size: 28px; font-weight: 800; color: #1f2937; line-height: 1; }
.xoxo-delpuz-stat.compensation .xoxo-delpuz-stat-value { color: #FF00AA; }
.xoxo-delpuz-stat-label { font-size: 10px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.4px; margin-top: 6px; font-weight: 700; }
.xoxo-delpuz-impact.empty {
    display: flex;
    align-items: center;
    gap: 12px;
    grid-template-columns: unset;
    text-align: left;
    padding: 14px 16px;
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #1e40af;
    font-size: 13px;
}
.xoxo-delpuz-impact.empty svg { flex-shrink: 0; }
.xoxo-delpuz-impact-note {
    font-size: 13px;
    line-height: 1.55;
    color: #4b5563;
    margin: 12px 2px 0;
    padding: 12px 14px;
    background: #fff7ed;
    border: 1px solid #fed7aa;
    border-radius: 10px;
}
.xoxo-delpuz-actions { display: flex; gap: 12px; justify-content: center; margin-top: 22px; flex-wrap: wrap; }
.xoxo-delpuz-actions .xoxo-btn { min-width: 150px; padding: 12px 22px; font-weight: 600; }
.xoxo-delpuz-confirm {
    background: #dc2626 !important;
    color: #fff !important;
    border: 2px solid #dc2626 !important;
}
.xoxo-delpuz-confirm:hover:not(:disabled) {
    background: #b91c1c !important;
    border-color: #b91c1c !important;
    transform: translateY(-1px);
}
.xoxo-delpuz-confirm:disabled { opacity: 0.6; cursor: not-allowed; }

@media (max-width: 560px) {
    .xoxo-delpuz-impact { grid-template-columns: 1fr; }
    .xoxo-delpuz-stat { border-right: none; border-bottom: 1px solid #e5e7eb; }
    .xoxo-delpuz-stat:last-child { border-bottom: none; }
}

/* v5.4.8 [TACHE 84 BUG 8] Progression puzzle (barre + texte). */
.xoxo-puzzle-progress-wrap { margin: 8px 0 12px; }
.xoxo-puzzle-progress-text { font-size: 12px; color: #555; margin-bottom: 4px; font-weight: 600; }
.xoxo-puzzle-progress-bar { width: 100%; height: 6px; background: #f0e6ee; border-radius: 3px; overflow: hidden; }
.xoxo-puzzle-progress-fill { height: 100%; background: linear-gradient(90deg, #FF00AA, #ff4dc4); transition: width .3s ease; }

/* v5.4.8 [TACHE 84 BUG 8] Popup de details du puzzle. */
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-content {
    max-width: 680px;
    width: 94%;
    max-height: 90vh;
    overflow-y: auto;
}
.xoxo-puzzle-detail-layout { display: flex; flex-direction: column; gap: 18px; padding: 8px 4px; }
.xoxo-puzzle-detail-header { text-align: center; }
.xoxo-puzzle-detail-title { font-size: 22px; font-weight: 800; margin: 0 0 10px; color: #222; }
.xoxo-puzzle-detail-creator { display: inline-flex; align-items: center; gap: 8px; color: #666; font-size: 14px; }
.xoxo-puzzle-detail-description { font-size: 14px; line-height: 1.55; color: #333; margin: 0; padding: 0 6px; }
.xoxo-puzzle-detail-pieces { max-width: 480px; margin: 0 auto; width: 100%; }
.xoxo-puzzle-detail-progress { padding: 12px 14px; background: #fafafa; border-radius: 10px; border: 1px solid #eee; }
.xoxo-puzzle-detail-progress-text { font-size: 14px; color: #444; margin-bottom: 6px; }
.xoxo-puzzle-detail-reward { padding: 14px 16px; background: #fff7fb; border: 1px solid #ffe0f0; border-radius: 10px; }

/* Reset CSS agressif sur la croix de la popup puzzle-detail (coherent avec bp-puzzles.php) */
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close {
    position: absolute; top: 10px; right: 10px; z-index: 10;
    width: 44px; height: 44px;
    display: flex; align-items: center; justify-content: center;
    border: none !important; border-radius: 50%;
    background: #fff; color: #999; cursor: pointer; padding: 0;
    outline: none !important; box-shadow: none !important;
    -webkit-appearance: none !important; appearance: none !important;
    text-decoration: none !important;
}
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close:hover { background: rgba(255,0,170,0.08); color: #FF00AA; }
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close::before,
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close::after,
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close:hover::before,
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close:hover::after,
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close:focus::before,
#xoxo-puzzle-detail-modal .xoxo-puzzle-detail-close:focus::after { content: none !important; display: none !important; }

.xoxo-puzzle-piece {
    aspect-ratio: 3/4;
    border-radius: 4px;
    overflow: hidden;
    background: var(--xoxo-bg-light);
    border: 1px solid var(--xoxo-border);
}

.xoxo-puzzle-piece.owned {
    border-color: var(--xoxo-success);
}

.xoxo-puzzle-piece.owned img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.xoxo-puzzle-piece.missing {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--xoxo-text-muted);
    font-size: 20px;
    font-weight: 700;
    position: relative;
}

/* v7.0.11 [TACHE 162] REFONTE - Pieces de puzzle non possedees : alignement
   strict avec la regle unifiee FO (decision Q4.A). Avant : grayscale(100%)
   blur(3px) opacity 0.5 -> blur trop faible vs grille principale (8px) et
   pas de logo overlay -> incoherence visuelle. Apres : grayscale(100%)
   blur(8px) opacity 0.9 + logo overlay centre absolu (~50% largeur).
   Le selecteur .xoxo-puzzle-piece doit etre en position relative pour le
   centrage absolu de ::after (deja le cas via .xoxo-puzzle-piece de base). */
.xoxo-puzzle-piece.missing img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(100%) blur(8px);
    -webkit-filter: grayscale(100%) blur(8px);
    opacity: 0.9;
}
.xoxo-puzzle-piece.missing {
    position: relative;
}
.xoxo-puzzle-piece.missing::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 50%;
    height: 50%;
    background-image: url('../images/logo-overlay.png');
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
    z-index: 5;
    opacity: 0.95;
    filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.4));
    -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.4));
}

/* v5.4.3 [TACHE 79 BUG 5] Piece dont la carte a ete supprimee : overlay "Carte indisponible". */
.xoxo-puzzle-piece.unavailable {
    position: relative;
    border-color: #e63946;
    border-style: dashed;
    background: #1a1a1a;
}
.xoxo-puzzle-piece.unavailable img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.95;
    filter: none;
}
.xoxo-puzzle-piece-unavail-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(230, 57, 70, 0.95);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 4px rgba(0,0,0,0.35);
    pointer-events: none;
}

.xoxo-puzzle-progress {
    font-size: 14px;
    color: var(--xoxo-text-light);
    margin-bottom: 8px;
}

.xoxo-puzzle-reward {
    padding: 12px;
    background: var(--xoxo-bg-light);
    border-radius: 8px;
    font-size: 13px;
    margin-bottom: 16px;
}

.xoxo-puzzle-reward strong {
    display: block;
    margin-bottom: 4px;
}

/* v5.5.9 [TACHE 95 BUG 1] Mention affichee au createur du puzzle en lieu et place
   du CTA "Obtenir le cadeau" (un createur ne reclame pas son propre cadeau).
   Rendu coherent avec les pills existantes du plugin (xoxo-puzzle-reward-claimed-badge). */
.xoxo-puzzle-creator-notice {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 18px;
    margin-top: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--xoxo-primary, #FF00AA);
    background: rgba(255, 0, 170, 0.08);
    border: 1px solid rgba(255, 0, 170, 0.25);
    border-radius: 999px;
    text-align: center;
    line-height: 1.3;
}

/* ============================
   Leaderboard
   ============================ */
.xoxo-leaderboard-table {
    width: 100%;
    border-collapse: collapse;
}

.xoxo-leaderboard-table th,
.xoxo-leaderboard-table td {
    padding: 12px 16px;
    text-align: left;
    border-bottom: 1px solid var(--xoxo-border);
}

.xoxo-leaderboard-table th {
    font-size: 12px;
    text-transform: uppercase;
    color: var(--xoxo-text-muted);
    font-weight: 600;
    letter-spacing: 0.5px;
}

.xoxo-leaderboard-table tr:hover {
    background: var(--xoxo-bg-light);
}

.xoxo-leaderboard-rank {
    font-size: 18px;
    font-weight: 700;
    width: 40px;
}

.xoxo-leaderboard-rank:nth-child(1) {
    color: var(--xoxo-rares);
}

/* ============================
   Pack Opening Results
   ============================ */
.xoxo-pack-opening {
    text-align: center;
    padding: 40px;
    max-width: 800px;
}

.xoxo-pack-animation {
    min-height: 300px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.xoxo-pack-cards-reveal {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
    margin: 24px 0;
}

.xoxo-reveal-card {
    width: 120px;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--xoxo-shadow);
    animation: revealCard 0.5s ease forwards;
    opacity: 0;
    transform: scale(0.8) rotateY(180deg);
}

.xoxo-reveal-card img {
    width: 100%;
    display: block;
}

.xoxo-reveal-card .xoxo-reveal-info {
    padding: 8px;
    font-size: 11px;
    text-align: center;
    background: var(--xoxo-bg);
}

.xoxo-reveal-card .xoxo-reveal-badge {
    font-size: 10px;
    font-weight: 700;
    display: block;
    margin-top: 2px;
}

.xoxo-reveal-card.duplicate .xoxo-reveal-badge {
    color: var(--xoxo-warning);
}

.xoxo-reveal-card.new .xoxo-reveal-badge {
    color: var(--xoxo-success);
}


/* ============================
   FO-11 : Avatar BuddyPress dynamique sur cartes sexy
   ============================ */
.xoxo-card-sexy-avatar {
    position: absolute;
    bottom: 10%;
    left: 50%;
    transform: translateX(-50%);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    overflow: hidden;
    border: 2px solid #fff;
    box-shadow: 0 2px 8px rgba(0,0,0,0.3);
    z-index: 3;
    pointer-events: none;
}
.xoxo-card-sexy-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.xoxo-card-sexy-avatar-detail {
    width: 80px;
    height: 80px;
    border-width: 3px;
    bottom: 12%;
}

/* ============================
   FO-19 : Badges configurables sur les cartes
   v5.2.1 : Déplacés dans .xoxo-card-info, inline à côté du badge type
   ============================ */
.xoxo-card-info-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
}
.xoxo-card-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    line-height: 1.3;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

/* ============================
   Sécurité des échanges (v5.0.4)
   ============================ */

/* Carte déjà échangée (verrouillée) */
.xoxo-card-item.xoxo-card-locked {
    position: relative;
}

.xoxo-card-item.xoxo-card-locked::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.1);
    pointer-events: none;
    z-index: 1;
}

.xoxo-card-lock-badge {
    z-index: 10;
    animation: pulse-lock 2s infinite;
}

@keyframes pulse-lock {
    0%, 100% { transform: scale(1); box-shadow: 0 2px 8px rgba(255, 0, 170, 0.3); }
    50% { transform: scale(1.05); box-shadow: 0 4px 12px rgba(255, 0, 170, 0.5); }
}

.xoxo-card-cooldown-badge {
    z-index: 10;
    animation: pulse-cooldown 2s infinite;
}

@keyframes pulse-cooldown {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* Carte en période de cooldown */
.xoxo-card-item.xoxo-card-cooldown .xoxo-card-image {
    position: relative;
}

.xoxo-card-item.xoxo-card-cooldown .xoxo-card-image::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(59, 130, 246, 0.05) 100%);
    pointer-events: none;
}



/* v5.6.1 [TACHE 97 BUG 3] Popup "Modifier le puzzle" : defense en profondeur contre
   un pseudo-element injecte par le theme SocialV (ou une regle tierce) qui rendait
   un rectangle vide en haut a droite (tentative de dessiner une croix FontAwesome
   absente via `content: "\f00d"`). Notre propre bouton .xoxo-modal-close avec SVG
   natif est desormais present (voir JS renderEditPuzzleModal). On neutralise les
   pseudo-elements parasites cote CSS pour garantir un rendu propre quel que soit
   le theme actif. */
#xoxo-edit-puzzle-modal .xoxo-modal-content::before,
#xoxo-edit-puzzle-modal .xoxo-modal-content::after,
#xoxo-edit-puzzle-modal .xoxo-editpuz-content::before,
#xoxo-edit-puzzle-modal .xoxo-editpuz-content::after {
    content: none !important;
    display: none !important;
}
#xoxo-edit-puzzle-modal .xoxo-modal-close {
    z-index: 20;
}
#xoxo-edit-puzzle-modal .xoxo-modal-close::before,
#xoxo-edit-puzzle-modal .xoxo-modal-close::after {
    content: none !important;
    display: none !important;
}

/* ============================
   v6.0.0 [TACHE 7] BUG-T7 fix : Responsive minmax(0, 1fr) pour .xoxo-my-cards-grid
   Extension du fix desktop (cards.css L.14) a tous les breakpoints responsive
   pour garantir une grille strictement egale sur toutes les tailles d'ecran.
   Place en fin de fichier pour surcharger sans ambiguite les regles responsive
   de responsive.css (cascade + specificite identique mais source plus tardive).
   ============================ */
@media (max-width: 1024px) {
    .xoxo-my-cards-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
@media (max-width: 768px) {
    .xoxo-my-cards-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
@media (max-width: 480px) {
    .xoxo-my-cards-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

