/* =================================================================
   scaard : WitcherStreamr
   Espace membre. Meme vocabulaire visuel que le site public :
   aplats opaques, entailles en coin, accent orange.
   Aucun degrade, aucun flou : la regle du site public vaut ici aussi.
   ================================================================= */

:root {
    --text:       #EDEFF3;
    --muted:      #949BA8;
    /* Releve de #6C7381, qui tombait a 3.3 pour 1 sur le fond des
       cartes claires, sous le seuil de 4.5 exige pour du texte normal.
       Cette teinte passe partout ou elle sert (4.51 au pire) tout en
       restant nettement en dessous de --muted, pour que la hierarchie
       des trois gris tienne encore. */
    --dim:        #828997;

    --panel:      #161A24;
    --panel-hi:   #1D2231;
    --line:       #262C3A;
    --line-hi:    #3A4254;

    --accent:     #FF7A50;
    --accent-ink: #1A0B05;
    --vert:       #4ADE80;
    --rouge:      #FF8FA0;

    /* Trois colonnes ne tiennent pas dans 1000px. La page s'elargit
       donc, mais reste bornee : au-dela, l'oeil traverse tout l'ecran
       pour relier un libelle a sa valeur. */
    --maxw:       1340px;
    /* Le bandeau et le pied ont leur propre largeur, fixe : une page qui
       elargit son contenu en redefinissant --maxw (le calendrier, par
       exemple) ne doit pas deplacer le cadre. D'une page a l'autre, la
       marque et les onglets restent ainsi exactement au meme endroit. */
    --maxw-barre: 1340px;
    --header-h:   62px;
    --cut:        12px;

    /* La courbe d'assouplissement du site public, reprise telle quelle :
       les deux pages doivent bouger de la meme facon. */
    --ease: cubic-bezier(.16, .84, .3, 1);

    --font-display: "Space Grotesk", system-ui, sans-serif;
    --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* La police de WitTCG. Declaree ici depuis que le jeu est ouvert a
   tous : une regle @font-face ne telecharge rien tant qu'aucun texte ne
   l'utilise, donc elle ne coute rien aux pages qui l'ignorent. */
@font-face {
    font-family: 'Valorant';
    src: url('tcg/font/valorant.woff2') format('woff2');
    font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }
/* [hidden] doit toujours cacher. Le navigateur le fait avec un
   display:none de faible poids, qu'une simple classe posant display
   (flex, grid) ecrase sans bruit : l'element reste visible alors que le
   HTML le dit cache. Le piege s'est referme trois fois ici — sur les
   volets des parametres, sur la fenetre elle-meme et sur le texte de la
   roue. On le ferme pour de bon. */
[hidden] { display: none !important; }



/* La place de la barre de defilement est toujours reservee, qu'il y ait de
   quoi defiler ou non. Sans cela, une page courte (les jeux) ou qui ne
   defile pas (la famille) n'a pas de barre, son contenu centre glisse
   d'une demi-barre, et le bandeau saute d'un onglet a l'autre. */
html { scrollbar-gutter: stable; }

/* Colonne pleine hauteur : le bandeau en haut, le contenu qui pousse,
   le pied colle en bas. Sans cela, sur un ecran de connexion ou un
   message de panne, qui tiennent en quelques lignes, le pied remontait
   au milieu de la page et flottait au-dessus du vide.

   Le bandeau garde son position: sticky : un conteneur flex ne le gene
   pas, seul un overflow cache sur un ancetre l'aurait neutralise.
   La boite de dialogue, elle, est dans la couche superieure du
   navigateur quand elle s'ouvre, et fermee elle ne s'affiche pas : dans
   les deux cas elle ne compte pas comme colonne. */
body {
    margin: 0;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.6;
    color: var(--text);
    background: var(--page-bg, #0B0E16);
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

/* ============================== BARRE ========================== */

.barre {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--page-bg, #0B0E16);
    border-bottom: 1px solid var(--line);
}

.barre__row {
    max-width: var(--maxw-barre);
    margin: 0 auto;
    min-height: var(--header-h);
    padding: 8px clamp(16px, 4vw, 32px);
    display: flex;
    align-items: center;
    gap: 12px;
}

.barre__marque {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.02rem;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Le nom de la page, pour qui n'est pas connecte : il n'y a alors
   qu'un ecran, donc pas d'onglets a proposer. */
.barre__ici {
    color: var(--dim);
    font-size: 0.86rem;
    white-space: nowrap;
}

.barre__ici::before {
    content: "/";
    margin-right: 10px;
    color: var(--line-hi);
}

/* Les onglets. Meme idiome que la barre du site public : un filet a
   l'accent sous la page en cours, le reste en retrait. La barre a
   toujours la meme hauteur, onglet actif ou non, parce que le filet est
   deja la en transparent. */
.barre__onglets {
    display: flex;
    align-items: center;
    gap: clamp(4px, 2vw, 16px);
    margin-left: 6px;
    min-width: 0;
}

.barre__onglet {
    padding: 6px 2px;
    color: var(--muted);
    font-size: 0.9rem;
    text-decoration: none;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    transition: color .16s var(--ease), border-color .16s var(--ease);
}
.barre__onglet:hover { color: var(--text); }
.barre__onglet.est-ici {
    color: var(--text);
    font-weight: 600;
    border-bottom-color: var(--accent);
}
.barre__onglet:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.barre__moi {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* Le lien du profil : la photo et le pseudo, tels qu'ils etaient. */
.barre__profil {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 3px 8px 3px 3px;
    margin: -3px -8px -3px -3px;
    border-radius: 999px;
    transition: background-color .16s ease;
}
.barre__profil:hover { background: var(--panel-hi); }
.barre__profil:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.barre__pseudo {
    font-size: 0.88rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 22ch;
}

.barre__retour { margin-left: auto; color: var(--muted); font-size: 0.88rem; }
.barre__retour:hover { color: var(--text); }

.pastille {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--panel-hi);
}

.pastille--vide {
    display: grid;
    place-items: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--muted);
}

/* La deconnexion, reduite a sa porte. Elle garde une cible de 34px :
   une icone de 16px seule serait un piege au doigt sur telephone. */
.sortir {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--dim);
    cursor: pointer;
    transition: background-color .16s ease, color .16s ease;
}

.sortir svg { width: 16px; height: 16px; display: block; }
.sortir:hover { background: var(--panel-hi); color: var(--text); }
.sortir:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.lien-sobre {
    padding: 0;
    border: 0;
    background: none;
    color: var(--dim);
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.lien-sobre:hover { color: var(--text); }

/* ============================== PAGE =========================== */

.page {
    /* Prend toute la hauteur restante, sans jamais se laisser comprimer
       par son contenu : c'est ce qui repousse le pied en bas. */
    flex: 1 0 auto;
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    padding: clamp(24px, 5vw, 44px) clamp(16px, 4vw, 32px) 64px;
}

.titre {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.4rem, 3.4vw, 1.9rem);
    letter-spacing: -0.02em;
}

.note {
    margin: 14px 0 0;
    color: var(--dim);
    font-size: 0.8rem;
    line-height: 1.5;
}

.intro {
    margin: 10px 0 22px;
    color: var(--muted);
    font-size: 0.95rem;
}

/* --- Carte --- */

.carte {
    padding: clamp(20px, 3.4vw, 28px);
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 12px;
    /* Chaque bloc porte son rang dans --i : les cartes se posent l'une
       apres l'autre au lieu d'apparaitre toutes ensemble. `backwards`
       les tient a leur etat de depart pendant le delai, sinon elles
       clignoteraient en place avant de partir. */
    animation: fade-up .62s var(--ease) calc(.07s * var(--i, 0)) backwards;
}

.carte--seule {
    max-width: 420px;
    margin: clamp(20px, 8vh, 80px) auto;
}

.carte__titre {
    margin: 0 0 16px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

/* --- Avis --- */

.avis {
    margin: 0 0 18px;
    padding: 11px 14px;
    border-left: 2px solid var(--line-hi);
    background: var(--panel-hi);
    font-size: 0.88rem;
}

.avis--ok     { border-left-color: var(--vert);  color: var(--vert); }
.avis--erreur { border-left-color: var(--rouge); color: var(--rouge); }
.avis--info   { border-left-color: var(--accent); color: var(--text); }
.avis--volant { margin-bottom: 16px; }

/* ============================== TETE =========================== */

.tete {
    animation: fade-up .62s var(--ease) backwards;
    display: flex;
    align-items: center;
    /* Quatre groupes tiennent en ligne sur un grand ecran et se
       replient l'un sous l'autre quand la place manque. Sans wrap, le
       pseudo se serait comprime jusqu'a devenir illisible. */
    flex-wrap: wrap;
    gap: clamp(14px, 3vw, 20px);
    margin-bottom: clamp(20px, 3vw, 28px);
}

/* Le bloc d'identite prend la place restante : compteurs et solde sont
   ainsi repousses a droite, ensemble, au lieu de flotter au milieu. */
.tete__texte { flex: 1 1 260px; min-width: 0; }

.tete__avatar {
    animation: pop-in .7s cubic-bezier(.2, .9, .3, 1.3) .06s backwards;
    width: 72px;
    height: 72px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--panel-hi);
    border: 1px solid var(--line);
}

.tete__avatar--vide {
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--muted);
}

.tete__rang {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    margin: 6px 0 0;
    color: var(--muted);
    font-size: 0.86rem;
}

.tete__rang sup { font-size: 0.7em; }

/* La phrase qui dit ce qui reste a parcourir. Plus eteinte que la place
   au classement : on la lit une fois, pas a chaque visite. */
.tete__suite {
    margin: 5px 0 0;
    color: var(--dim);
    font-size: 0.8rem;
}

/* Le titre du membre. Sa couleur arrive par --rang, posee sur l'element
   par le serveur puis par le script : l'echelle vit dans points.php, et
   le CSS n'a pas a la repeter rang par rang. Le repli sur --muted sert
   au cas ou la variable manquerait, jamais a l'affichage normal.

   Fond opaque et entaille en coin, comme les boutons : un rang est une
   piece du meme jeu, pas une etiquette collee par-dessus. */
.rang {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 3px 11px;
    border: 1px solid var(--rang, var(--muted));
    background: var(--panel-hi);
    color: var(--rang, var(--muted));
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px,
                       100% 100%, 6px 100%, 0 calc(100% - 6px));
}

.rang__pastille {
    width: 7px;
    height: 7px;
    flex: 0 0 auto;
    background: var(--rang, var(--muted));
    transform: rotate(45deg);
}

/* Le rang vient de monter, dans la page et sans rechargement. */
.rang--neuf { animation: pop-in .5s cubic-bezier(.2, .9, .3, 1.3); }

/* ============================== L'ECHELLE ====================== */

/* La pastille est un summary : le triangle natif est retire, il se pose
   a gauche et rien ne l'aligne d'un navigateur a l'autre. */
.rangs { display: contents; }
.rang { cursor: pointer; list-style: none; }
.rang::-webkit-details-marker { display: none; }
.rang:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Rien n'annonce le clic : le fond qui s'eclaire au survol suffit, et
   une fleche a cote d'un nom de rang ressemblait a un ornement pose la
   pour faire joli. */
.rang:hover { background: var(--line); }

/* Le panneau. Sans JavaScript il se deplie sous la pastille, encadre
   pour qu'on voie ou il commence ; dans la modale, la boite fournit
   deja le cadre et il n'en a plus besoin.

   La pleine largeur vient du display: contents pose sur le details : le
   panneau devient un element de la meme ligne que la pastille, et sans
   cette base il se serrerait a cote d'elle. */
.rangs__panneau {
    flex: 1 1 100%;
    margin: 10px 0 0;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--panel);
}
.modale .rangs__panneau { margin: 0; padding: 0; border: 0; background: none; }
.modale .rangs__ligne { padding-left: 0; padding-right: 0; }
.modale .rangs__ligne.est-ici { padding-left: 10px; padding-right: 10px; margin: 0 -10px; }

.rangs__liste {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Chaque ligne entre a son tour. Le decalage se calcule sur son rang
   dans l'echelle, pose en --i par le serveur : la liste se deroule du
   bas de l'echelle vers le haut, dans l'ordre ou on la lit. */
@keyframes rang-entre {
    from { opacity: 0; transform: translateX(-10px); }
    to   { opacity: 1; transform: none; }
}

/* Des lignes separees par un filet, comme le journal des gains : c'est
   une liste, pas une pile de cartes. */
.rangs__ligne {
    display: flex;
    align-items: center;
    gap: 11px;
    /* Le meme retrait pour toutes : la ligne du moment porte un fond,
       pas un decalage. Sans ca, son losange et son nom glissaient de
       dix pixels par rapport aux autres. */
    padding: 10px;
    border-bottom: 1px solid var(--line);
    animation: rang-entre .34s var(--ease) calc(var(--i, 0) * 45ms) backwards;
}
.rangs__ligne:last-child { border-bottom: 0; }

/* Le losange du rang, plein une fois le palier franchi, creux tant
   qu'il reste a atteindre. */
.rangs__pastille {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border: 1px solid var(--rang, var(--muted));
    transform: rotate(45deg);
}
.rangs__ligne.est-passe .rangs__pastille,
.rangs__ligne.est-ici .rangs__pastille { background: var(--rang, var(--muted)); }

.rangs__texte { min-width: 0; flex: 1 1 auto; }

.rangs__nom {
    display: block;
    font-family: var(--font-display);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--dim);
}
.rangs__ligne.est-passe .rangs__nom { color: var(--muted); }
.rangs__ligne.est-ici .rangs__nom { color: var(--rang, var(--text)); }

.rangs__mot {
    display: block;
    color: var(--dim);
    font-size: 0.76rem;
    line-height: 1.45;
}

.rangs__seuil {
    flex: 0 0 auto;
    color: var(--dim);
    font-size: 0.76rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Le rang du moment : un aplat sourd et l'entaille en coin du site,
   plutot qu'un filet colle sur le bord gauche. C'est la seule ligne qui
   porte un fond, donc on la trouve sans la chercher. */
.rangs__ligne.est-ici {
    border-bottom-color: transparent;
    background: var(--panel-hi);
    clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px,
                       100% 100%, 9px 100%, 0 calc(100% - 9px));
}
.rangs__ligne.est-ici .rangs__seuil {
    color: var(--rang, var(--accent));
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.7rem;
}

.rangs__note {
    margin: 12px 0 0;
    color: var(--dim);
    font-size: 0.76rem;
    line-height: 1.5;
}

.tete__solde {
    margin-left: auto;
    text-align: right;
    line-height: 1.1;
}

.tete__solde-n {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.6rem, 4.6vw, 2.2rem);
    color: var(--accent);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.tete__solde-w {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1rem, 2.6vw, 1.25rem);
    color: var(--accent);
    margin-left: 3px;
}

.tete__solde-l {
    display: block;
    font-size: 0.74rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--dim);
}

/* ============================== GRILLE ========================= */

/* Une seule grille pour les trois blocs, ecrite du petit ecran vers le
   grand : par defaut tout s'empile dans l'ordre du HTML, et chaque
   palier ajoute une colonne quand la place existe. L'inverse, partir du
   grand ecran et retirer, oblige a defaire des regles au lieu d'en
   poser, et laisse toujours un cas non traite tout en bas.

   Les colonnes laterales sont bornees en largeur : un cadeau du jour ou
   un journal n'ont pas besoin de grandir avec l'ecran, alors que la
   vitrine gagne a chaque pixel qu'on lui donne. C'est elle qui prend
   tout le reste, d'ou le minmax(0, 1fr) : sans le 0, une tuile au nom
   long imposerait sa largeur a toute la colonne.

   align-items: start empeche les trois colonnes de s'etirer a la
   hauteur de la plus grande, ce qui laisserait des cartes vides. */
.grille {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(14px, 2.4vw, 20px);
    align-items: start;
}

.colonne {
    display: grid;
    gap: clamp(14px, 2.4vw, 20px);
    /* Une colonne ne doit jamais etre plus large que sa part de
       grille : sans cette borne, un long libelle la fait deborder. */
    min-width: 0;
}

.colonne--action { gap: 10px; }

/* Deux colonnes : l'action tient a gauche, la boutique prend le reste.
   Le suivi passe sous les deux et se partage en autant de cartes que la
   largeur en accepte. */
@media (min-width: 880px) {
    .grille { grid-template-columns: minmax(260px, 320px) minmax(0, 1fr); }
    .colonne--suivi {
        grid-column: 1 / -1;
        grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    }
}

/* Trois colonnes : le suivi remonte a droite. La boutique reste au
   milieu, la ou se porte le regard, et garde la part variable. */
@media (min-width: 1240px) {
    .grille { grid-template-columns: minmax(250px, 300px) minmax(0, 1fr) minmax(280px, 330px); }
    .colonne--suivi {
        grid-column: auto;
        grid-template-columns: 1fr;
    }
}

/* Les compteurs, dans le bandeau. Trois nombres qu'on ne consulte pas
   a chaque visite n'ont a occuper ni une carte entiere, ni une bande en
   face de la boutique : ils tiennent dans le vide du bandeau. */
.mini {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 20px;
    margin: 0;
    padding: 9px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel);
    animation: fade-up .62s var(--ease) .1s backwards;
}

.mini__paire { display: flex; align-items: baseline; gap: 6px; }
.mini dt { color: var(--dim); font-size: 0.78rem; }
.mini dd {
    margin: 0;
    font-family: var(--font-display);
    font-size: 0.92rem;
    font-variant-numeric: tabular-nums;
}

/* ============================== BOUTIQUE ======================= */

/* Pleine largeur sous la grille : les cartes de recompenses ont besoin
   de place, et la boutique est une seconde lecture de la page, pas une
   colonne de plus. */
.boutique__tete {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin-bottom: 12px;
    animation: fade-up .62s var(--ease) .1s backwards;
}

.boutique__titre {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.02em;
}

.boutique__mot {
    margin: 0;
    color: var(--muted);
    font-size: 0.86rem;
}

/* Une sortie de points ne se lit pas comme un gain. */
.journal__points--sortie { color: var(--muted); }

/* La vitrine : des tuiles compactes, faites pour qu'on en aligne dix
   sans que la page devienne une liste a derouler. Chacune s'ouvre sur
   place et prend alors toute la largeur de la rangee, parce qu'un
   panneau coince dans une colonne de 160px serait illisible. */
.vitrine {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
    gap: 12px;
    margin-bottom: clamp(14px, 2.4vw, 20px);
    align-items: start;
}

.tuile {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    animation: fade-up .5s var(--ease) calc(.05s * var(--i, 0)) backwards;
}

.tuile[open] {
    grid-column: 1 / -1;
    border-color: var(--line-hi);
}

/* La face visible. La fleche native du navigateur est retiree : elle
   place un triangle a gauche que rien n'aligne d'un navigateur a
   l'autre. */
.tuile__face {
    display: grid;
    grid-template-rows: auto 1fr auto;
    gap: 8px;
    padding: 14px;
    cursor: pointer;
    list-style: none;
    /* Hauteur commune a toutes les tuiles. Elle est POSEE et non
       deduite du contenu : sans elle, une tuile au nom long depassait
       ses voisines et la grille partait en escalier. La rangee du
       milieu s'etire (1fr), le nom flotte donc au meme endroit partout
       et le prix reste colle en bas. */
    min-height: 152px;
}

.tuile__face::-webkit-details-marker { display: none; }
.tuile__face:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tuile:not([open]) .tuile__face:hover { background: var(--panel-hi); }

/* Le carre de couleur, signe distinctif de la recompense. */
.tuile__icone {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: var(--teinte, var(--accent));
    color: #14100C;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    line-height: 1;
    overflow: hidden;
}

.tuile__icone img { width: 100%; height: 100%; object-fit: cover; }

.tuile__nom {
    font-weight: 600;
    font-size: 0.92rem;
    line-height: 1.3;
    /* Deux lignes au plus, coupees proprement : c'est ce qui rend la
       hauteur commune tenable quel que soit le nom saisi au dashboard.
       Le nom entier reste lisible au survol, par l'attribut title. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

.tuile__prix {
    justify-self: start;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--panel-hi);
    color: var(--accent);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

/* Hors de portee : la tuile s'efface sans disparaitre, l'objectif reste
   visible. */
.tuile--chere { opacity: .62; }
.tuile--chere .tuile__prix { color: var(--muted); }

/* Le panneau ouvert, sous la face. */
.tuile__panneau {
    padding: 0 14px 14px;
    border-top: 1px solid var(--line);
    padding-top: 14px;
    animation: fade-up .3s var(--ease);
}

.tuile[open] .tuile__face { background: var(--panel-hi); }

.tuile__desc {
    margin: 0 0 14px;
    color: var(--muted);
    font-size: 0.88rem;
    max-width: 62ch;
}

.tuile__form { margin: 0; max-width: 420px; }

.tuile__note {
    margin: 10px 0 0;
    color: var(--dim);
    font-size: 0.76rem;
}

.offre__label {
    display: block;
    margin: 0 0 6px;
    color: var(--muted);
    font-size: 0.8rem;
}

.offre__champ {
    width: 100%;
    margin: 0 0 12px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-hi);
    color: var(--text);
    font: inherit;
    font-size: 0.9rem;
}

.offre__champ:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.bouton--offre { width: 100%; }

.offre__cite { color: var(--dim); font-style: italic; }

/* ============================== CADEAU ========================= */

.cadeau { text-align: center; }

.cadeau__gain {
    animation: pop-in .66s cubic-bezier(.2, .9, .3, 1.3) .18s backwards;
    margin: 4px 0 2px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2.6rem, 9vw, 3.6rem);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.cadeau__w {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.42em;
    color: var(--accent);
    margin-left: 6px;
    vertical-align: 0.9em;
}

.cadeau__unite {
    display: block;
    margin-top: 6px;
    font-family: var(--font-body);
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--dim);
}

/* Les trois lignes qui changent d'un etat a l'autre ont leur place
   reservee. Sans ca la carte grandissait et retrecissait au rythme des
   phrases : « Disponible maintenant » n'occupe pas autant que
   « Prochain cadeau dans 23 h 59 min », et la colonne est etroite. */
.cadeau__detail {
    margin: 0 0 22px;
    min-height: 1.6em;
    color: var(--muted);
    font-size: 0.86rem;
}

.cadeau__form { margin: 0; }

.cadeau__minuterie {
    margin: 14px 0 0;
    min-height: 1.6em;
    font-size: 0.88rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.cadeau__serie {
    margin: 16px 0 0;
    /* Deux lignes, le maximum qu'atteignent les phrases de serie. */
    min-height: calc(3.2em + 16px);
    padding-top: 16px;
    border-top: 1px solid var(--line);
    font-size: 0.88rem;
    color: var(--muted);
}

.cadeau__serie strong { color: var(--text); }

/* La part des 24 h deja ecoulee. Elle remplace un chiffre qui descend
   par quelque chose qui se voit d'un coup d'oeil, et elle avance
   toute seule : la largeur est transitionnee, le script ne fait que
   poser la nouvelle valeur chaque seconde. */
.jauge {
    height: 3px;
    margin: 12px 0 0;
    background: var(--line);
    overflow: hidden;
}

.jauge__part {
    height: 100%;
    width: 0;
    background: var(--accent);
    transition: width 1s linear;
}

.jauge--pleine .jauge__part { background: var(--vert); }

/* Le gain qui s'envole du bouton. Cree par le script, retire par lui. */
.gain-volant {
    position: absolute;
    left: 50%;
    top: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.5rem;
    color: var(--vert);
    pointer-events: none;
    white-space: nowrap;
    animation: envol 1.25s cubic-bezier(.2, .8, .3, 1) forwards;
}

.cadeau__form { position: relative; }

/* ============================== BOUTONS ======================== */

/* L'entaille en coin est celle des boutons du site public. */
.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 26px;
    border: 0;
    background: var(--accent);
    color: var(--accent-ink);
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.95rem;
    cursor: pointer;
    clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px,
                       100% 100%, 9px 100%, 0 calc(100% - 9px));
    transition: filter .16s ease, transform .16s ease;
}

.bouton:hover { filter: brightness(1.08); transform: translateY(-1px); }
.bouton:active { transform: translateY(0); }
.bouton:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }

/* Le bouton secondaire, a cote d'un bouton d'accent : meme forme, meme
   entaille, mais il ne tire pas l'oeil. Dans la feuille commune et non
   dans celle d'une page, parce que trois pages en avaient besoin et que
   la premiere l'avait garde pour elle. */
.bouton--fantome {
    background: var(--panel-hi);
    color: var(--text);
    border: 1px solid var(--line-hi);
}
.bouton--fantome:hover { background: var(--panel); filter: none; }

.bouton--cadeau {
    width: 100%;
    padding-block: 15px;
    font-size: 1rem;
    position: relative;
    overflow: hidden;   /* la lame ne deborde pas de l'entaille */
}

/* Un seul passage clair en travers du bouton, comme les cartes reseaux
   du site public le font a leur apparition. La lame ne vit que le temps
   de l'annonce du gain : hors de cet etat, elle attend hors cadre. */
.bouton--cadeau::after {
    content: "";
    position: absolute;
    top: -60%;
    bottom: -60%;
    left: 0;
    width: 40px;
    background: rgba(255, 255, 255, .55);
    transform: skewX(-18deg) translateX(-320%);
    pointer-events: none;
}

.bouton--cadeau.est-gagne::after {
    animation: lame .62s cubic-bezier(.3, .7, .3, 1) 1;
}

/* Reclame : le bouton reste lisible, mais ne s'annonce plus cliquable. */
.bouton:disabled {
    background: var(--panel-hi);
    color: var(--dim);
    cursor: not-allowed;
    transform: none;
    filter: none;
}

/* Le vert ne dure que le temps de l'annonce du gain. */
.bouton.est-gagne {
    background: var(--vert);
    color: #06210F;
}

.bouton--discord {
    width: 100%;
    background: #5865F2;
    color: #fff;
}

/* Le lien d'evitement. Hors de l'ecran tant qu'il n'a pas le focus,
   jamais display:none, qui le retirerait de l'ordre de tabulation et
   le rendrait donc inatteignable, c'est-a-dire inutile. */
.evitement {
    position: absolute;
    left: 10px;
    top: -60px;
    z-index: 30;
    padding: 9px 14px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    transition: top .14s var(--ease);
}
.evitement:focus { top: 10px; }

/* La progression vers le rang suivant. Meme couleur que la pastille du
   rang en cours, pour qu'on lise les deux comme une seule information.
   La hauteur est fine : c'est un reperage, pas une mesure. */
.avance {
    max-width: 320px;
    height: 4px;
    margin: 8px 0 0;
    background: var(--panel-hi);
    border: 1px solid var(--line);
    overflow: hidden;
}
.avance__part {
    height: 100%;
    background: var(--rang, var(--accent));
    transition: width .5s var(--ease);
}

/* Sous 560px, le bandeau porte quatre choses pour une largeur de
   trois : le pseudo s'efface, l'avatar dit deja qui est connecte et le
   nom reste lisible dans la page. */
@media (max-width: 560px) {
    .barre__row { gap: 10px; }
    .barre__pseudo { display: none; }
    .barre__marque { font-size: 0.94rem; max-width: 40vw; }
    .barre__onglet { font-size: 0.86rem; }
}

/* Le bouton du menu, invisible sur grand ecran. */
.barre__burger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 38px;
    height: 38px;
    align-items: center;
    padding: 0;
    border: 1px solid var(--line-hi);
    border-radius: 10px;
    background: transparent;
    cursor: pointer;
}
.barre__burger span {
    display: block;
    width: 18px;   /* dans un bouton, Chrome n'etire pas les traits : sans largeur ils disparaissaient */
    height: 2px;
    border-radius: 2px;
    background: var(--text);
    transition: transform .2s var(--ease), opacity .2s var(--ease);
}
.barre__burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Ouvert, les trois traits deviennent une croix. */
.barre.est-ouverte .barre__burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.barre.est-ouverte .barre__burger span:nth-child(2) { opacity: 0; }
.barre.est-ouverte .barre__burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Sous 760 px, quatre onglets ne tiennent plus a cote du nom du site et
   de l'avatar. Avec barre.js (classe est-js), ils passent dans un menu
   qui s'ouvre sous le bandeau, en liste, avec de grandes zones a
   toucher. Sans script, ils restent dans la barre et passent a la
   ligne : rien ne devient inaccessible. */
@media (max-width: 760px) {
    .barre { position: sticky; }
    .barre.est-js .barre__burger { display: inline-flex; order: 3; }
    .barre.est-js .barre__moi { margin-left: auto; }
    .barre.est-js .barre__onglets {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        display: none;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        margin: 0;
        padding: 8px clamp(16px, 4vw, 32px) 14px;
        background: var(--page-bg, #0B0E16);
        border-bottom: 1px solid var(--line);
        box-shadow: 0 18px 30px rgba(0, 0, 0, .45);
    }
    .barre.est-js.est-ouverte .barre__onglets { display: flex; animation: menu .18s var(--ease); }
    .barre.est-js .barre__onglet {
        padding: 13px 12px;
        border-bottom: 0;
        border-radius: 10px;
        font-size: 1rem;
    }
    .barre.est-js .barre__onglet.est-ici { background: var(--panel); border-left: 3px solid var(--accent); }

    .barre:not(.est-js) .barre__row { flex-wrap: wrap; }
}

@keyframes menu { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
    .barre__burger span { transition: none; }
    .barre.est-js.est-ouverte .barre__onglets { animation: none; }
}

/* Lu, jamais vu. Ni display:none ni visibility:hidden, qui retireraient
   le texte de la vocalisation : un rectangle de decoupe d'un pixel, la
   seule methode qui le laisse dans l'arbre d'accessibilite. */
.lu-seulement {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Le pied de page : un seul lien, celui qu'un espace qui enregistre
   des donnees doit rendre atteignable de partout. */
.pied {
    display: flex;
    justify-content: center;
    gap: 18px;
    flex: 0 0 auto;
    width: 100%;
    max-width: var(--maxw-barre);
    margin: 0 auto;
    padding: 24px clamp(14px, 3vw, 22px) 32px;
    border-top: 1px solid var(--line);
    text-align: center;
}
.pied__lien {
    color: var(--dim);
    font-size: 0.78rem;
    text-decoration: none;
    text-underline-offset: 3px;
}
.pied__lien:hover { color: var(--muted); text-decoration: underline; }

/* ============================== COMPTEURS ====================== */

.compteurs {
    margin: 0;
    display: grid;
    gap: 2px;
}

.compteur {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--line);
}

.compteur:last-child { border-bottom: 0; padding-bottom: 0; }

.compteur dt {
    color: var(--muted);
    font-size: 0.86rem;
}

.compteur dd {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
}

/* ============================== JOURNAL ======================== */

.journal {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 2px;
}

.journal__ligne {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 2px 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--line);
}

.journal__ligne:last-child { border-bottom: 0; padding-bottom: 0; }

.journal__detail { font-size: 0.86rem; }

.journal__points {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.journal__date {
    grid-column: 1 / -1;
    color: var(--dim);
    font-size: 0.76rem;
}

.journal__vide {
    color: var(--dim);
    font-size: 0.86rem;
}

/* La ligne qui vient d'arriver se glisse en haut de la liste et se
   signale une fois par la couleur, puis se range avec les autres. */
.journal__ligne--neuf { animation: journal-in .5s var(--ease) backwards; }
.journal__ligne--neuf .journal__detail { animation: neuf 1.6s ease-out; }

/* ============================== MODALE ========================= */

/* La tuile s'ouvre ici. Le <dialog> natif porte deja le placement au
   centre, la capture du clavier et la touche Echap : rien de tout cela
   n'est refait a la main. */
.modale {
    width: min(460px, calc(100vw - 32px));
    padding: 0;
    border: 1px solid var(--line-hi);
    border-radius: 14px;
    background: var(--panel);
    color: var(--text);
    animation: modale-in .28s var(--ease);
}

.modale::backdrop {
    background: rgba(6, 8, 14, .72);
    animation: fondu-in .28s ease;
}

.modale__titre {
    margin: 0;
    padding: 20px 52px 14px 22px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.12rem;
    letter-spacing: -0.01em;
    border-bottom: 1px solid var(--line);
}

.modale__corps { padding: 18px 22px 22px; }

/* Le panneau perd son filet et ses marges de tuile une fois dedans :
   c'est la modale qui cadre, maintenant. */
.modale__corps .tuile__panneau {
    padding: 0;
    border-top: 0;
    animation: none;
}

.modale__corps .tuile__form { max-width: none; }

.modale__fermer-form { margin: 0; }

.modale__fermer {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}

.modale__fermer:hover { background: var(--panel-hi); color: var(--text); }
.modale__fermer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@keyframes modale-in {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Un groupe de boutons radio ou de cases a cocher. Les options sont
   empilees : sur une seule ligne, deux options longues se coupaient
   n'importe ou et on ne savait plus quelle case allait avec quel mot. */
.offre__groupe {
    display: grid;
    gap: 2px;
    margin: 0 0 12px;
}

.offre__coche {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border-radius: 8px;
    font-size: 0.9rem;
    cursor: pointer;
}

.offre__coche:hover { background: var(--panel-hi); }

.offre__coche input {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    accent-color: var(--accent);
    cursor: pointer;
}

.offre__coche input:disabled,
.offre__coche input:disabled + span { cursor: not-allowed; opacity: .6; }

/* Un champ facultatif le dit, plutot que de laisser deviner. */
.offre__option {
    margin-left: 6px;
    color: var(--dim);
    font-size: 0.92em;
}

/* Un textarea suit le meme habillage que les autres champs. */
textarea.offre__champ { resize: vertical; min-height: 78px; font-family: inherit; }

/* ============================ ANIMATIONS ======================= */
/* Memes traces que le site public : une page et son espace membre ne
   peuvent pas bouger de deux facons differentes. */

@keyframes fade-up {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes pop-in {
    from { opacity: 0; transform: scale(.84); }
    to   { opacity: 1; transform: scale(1); }
}

/* Coup de lame unique en travers du bouton. */
@keyframes lame {
    from { transform: skewX(-18deg) translateX(-320%); }
    to   { transform: skewX(-18deg) translateX(1100%); }
}

/* Le gain quitte le bouton et s'efface en montant. */
@keyframes envol {
    from { opacity: 0; transform: translate(-50%, 6px) scale(.9); }
    25%  { opacity: 1; transform: translate(-50%, -8px) scale(1); }
    to   { opacity: 0; transform: translate(-50%, -62px) scale(1); }
}

@keyframes journal-in {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes neuf {
    from { color: var(--accent); }
    to   { color: var(--text); }
}

/* ================= MOUVEMENT REDUIT ============================ *
 * Meme lecture que sur le site public : prefers-reduced-motion vise le
 * MOUVEMENT, pas les fondus de couleur ni d'opacite. On fige donc les
 * deplacements et on garde les retours visuels, sans quoi la page
 * paraitrait inanimee alors que rien ne genait.
 */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        /* Les entrees sautent a leur etat final plutot que d'etre
           supprimees : en fill `backwards`, elles resteraient sinon
           bloquees a leur etat de depart, donc invisibles. */
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-property: opacity, color, background-color, border-color,
                             box-shadow, fill, stroke, filter, width !important;
    }

    .bouton:hover { transform: none; }

    /* Le gain ne s'envole plus, il se pose et s'efface sur place. */
    .gain-volant {
        transform: translate(-50%, -34px);
        animation: fondu 1.1s ease-out forwards;
    }
}

@keyframes fondu {
    from { opacity: 1; }
    to   { opacity: 0; }
}

/* ============================== CATALOGUE ====================== */

/* Le bandeau d'une page qui n'a ni avatar ni solde a montrer. */
.tete--page { display: block; }

.oeuvres { margin: 0 0 clamp(20px, 3vw, 28px); }

.oeuvres__titre {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin: 0 0 10px;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}
.oeuvres__compte {
    color: var(--dim);
    font-family: var(--font-body);
    font-size: 0.82rem;
    font-weight: 400;
}

/* Une oeuvre : une ligne qu'on deplie. Bordure et fond opaques, comme
   les cartes du reste de l'espace. */
.oeuvre {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--panel);
    margin-bottom: 8px;
    overflow: hidden;
}
.oeuvre[open] { border-color: var(--line-hi); }

.oeuvre__face {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    cursor: pointer;
    list-style: none;
}
.oeuvre__face::-webkit-details-marker { display: none; }
.oeuvre__face:hover { background: var(--panel-hi); }
.oeuvre__face:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.oeuvre__img {
    flex: 0 0 auto;
    width: 46px;
    height: 66px;
    object-fit: cover;
    border-radius: 6px;
    background: var(--panel-hi);
}
.oeuvre__img--vide { display: block; }

.oeuvre__texte { flex: 1 1 auto; min-width: 0; }

.oeuvre__nom {
    display: block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.96rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.oeuvre__meta {
    display: block;
    margin-top: 2px;
    color: var(--dim);
    font-size: 0.8rem;
}
.oeuvre__meta strong { color: var(--accent); font-weight: 700; }

/* Ma note, a droite : pleine quand elle existe, creuse quand elle
   attend. C'est le seul endroit de la ligne qui me concerne. */
.oeuvre__mienne {
    flex: 0 0 auto;
    padding: 5px 10px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: var(--accent-ink);
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 700;
    clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 7px,
                       100% 100%, 7px 100%, 0 calc(100% - 7px));
}
.oeuvre__mienne--vide {
    background: none;
    border-color: var(--line-hi);
    color: var(--dim);
    font-weight: 600;
}

.oeuvre__panneau {
    padding: 4px 12px 14px;
    border-top: 1px solid var(--line);
}

.oeuvre__synopsis {
    margin: 12px 0;
    color: var(--muted);
    font-size: 0.86rem;
    line-height: 1.6;
}

/* L'avis de la maison. Entaille et aplat sourd : il se distingue des
   avis des membres sans leur voler la vedette. */
.oeuvre__sien {
    margin: 0 0 14px;
    padding: 10px 12px;
    background: var(--panel-hi);
    clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px,
                       100% 100%, 9px 100%, 0 calc(100% - 9px));
}
.oeuvre__sien-tete {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--dim);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.oeuvre__sien-note {
    color: var(--accent);
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: 0;
}
.oeuvre__sien-mot {
    margin: 5px 0 0;
    color: var(--text);
    font-size: 0.87rem;
    line-height: 1.6;
}

/* Le formulaire. */
.avis-form { margin: 0 0 14px; }
.avis-form__haut { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.avis-form__label {
    display: block;
    margin-bottom: 5px;
    color: var(--dim);
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.avis-form__haut .avis-form__label { margin: 0; }

.avis-form__note,
.avis-form__mot {
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-hi);
    color: var(--text);
    font: inherit;
    font-size: 0.9rem;
}
.avis-form__note { padding: 7px 10px; }
.avis-form__mot { width: 100%; padding: 9px 11px; resize: vertical; line-height: 1.55; }
.avis-form__note:focus, .avis-form__mot:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.avis-form__pied { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 10px; }
.bouton--avis { padding: 9px 18px; font-size: 0.88rem; }

/* Ce que les autres en ont dit. */
.avis-liste { margin: 0; padding: 14px 0 0; list-style: none; border-top: 1px solid var(--line); }
.avis-liste__ligne { padding: 10px 0; border-bottom: 1px solid var(--line); }
.avis-liste__ligne:last-child { border-bottom: 0; padding-bottom: 0; }

.avis-liste__qui {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 3px;
    font-size: 0.85rem;
    font-weight: 600;
}
.avis-liste__note {
    color: var(--accent);
    font-family: var(--font-display);
    font-size: 0.82rem;
}
.avis-liste__date { color: var(--dim); font-size: 0.76rem; font-weight: 400; }
.avis-liste__mot { margin: 0; color: var(--muted); font-size: 0.87rem; line-height: 1.6; }


/* --- Chercher et trier le catalogue ------------------------------
   Une adresse par etat : la recherche et le tri sont des liens et un
   formulaire en GET, donc on peut les garder, les partager, et revenir
   dessus avec le bouton Precedent. */
.filtres {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 22px;
    align-items: center;
    margin: 0 0 16px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--panel);
}

.filtres__label {
    color: var(--dim);
    font-size: 0.76rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.filtres__chercher { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

.filtres__champ {
    min-width: 0;
    width: 190px;
    padding: 7px 11px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-hi);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}
.filtres__champ:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.filtres__vider { color: var(--dim); font-size: 0.8rem; }
.filtres__tris { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }

.pastilles { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }

/* Le critere actif se reconnait a trois choses a la fois, le fond, la
   bordure et la graisse : la couleur seule ne suffit jamais. */
.pastille-tri {
    display: inline-block;
    padding: 5px 11px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--panel-hi);
    color: var(--muted);
    font-size: 0.82rem;
    text-decoration: none;
}
.pastille-tri:hover { border-color: var(--line-hi); color: var(--text); }
.pastille-tri.est-on {
    border-color: var(--accent);
    color: var(--text);
    font-weight: 600;
}
.pastille-tri:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Le filtre n'est pas un tri : il retire des lignes. Une bordure
   tiretee le dit avant qu'on ait lu son libelle. */
.pastille-tri--filtre { border-style: dashed; }
.pastille-tri--filtre.est-on { border-style: solid; background: var(--accent); color: var(--accent-ink); }

.filtres__compte {
    margin: -8px 0 16px;
    color: var(--dim);
    font-size: 0.82rem;
}
.filtres__compte a { color: var(--muted); }

/* --- Noter une oeuvre, dans sa boite ------------------------------
   Plus large que la boite d'une recompense : on y lit un resume, l'avis
   de la maison, on note, on ecrit, et on lit ce que les autres ont dit.
   La hauteur est bornee et c'est le corps qui defile, sinon la boite
   depassait de l'ecran des que trois avis s'ajoutaient. */
.modale--oeuvre {
    width: min(720px, calc(100vw - 28px));
    max-height: 86vh;
}
.modale--oeuvre[open] { display: flex; flex-direction: column; }
.modale--oeuvre .modale__corps {
    overflow-y: auto;
    /* La place de la barre est reservee meme quand il n'y a rien a
       faire defiler : sans ca, le contenu sautait de quelques pixels
       vers la gauche des que la liste d'avis s'allongeait. */
    scrollbar-gutter: stable;

    /* Une barre a soi, discrete : celle du systeme prend une quinzaine
       de pixels et taille une bande claire au bord de la boite.
       Firefox et la norme d'abord. Le rail reste transparent, c'est le
       fond de la modale qu'on voit dessous. */
    scrollbar-width: thin;
    scrollbar-color: var(--line-hi) transparent;
}

/* Chrome, Edge, Safari. Le curseur fait 8 px de large mais porte 2 px
   de bordure transparente decoupee sur le fond : il en reste 4 a
   l'ecran, une trace plutot qu'une barre. Il s'eclaircit au survol,
   pour se laisser attraper quand on le cherche. */
.modale--oeuvre .modale__corps::-webkit-scrollbar { width: 8px; }
.modale--oeuvre .modale__corps::-webkit-scrollbar-track { background: transparent; }
.modale--oeuvre .modale__corps::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: 999px;
    background: var(--line-hi);
    background-clip: padding-box;
}
.modale--oeuvre .modale__corps::-webkit-scrollbar-thumb:hover {
    background: #4B5568;
    background-clip: padding-box;
}
.modale--oeuvre .modale__corps::-webkit-scrollbar-button { display: none; }
/* Dans la boite, le panneau n'a plus de cadre a lui : la boite le
   fournit deja. */
.modale__corps .oeuvre__panneau { padding: 0; border-top: 0; }

/* Le curseur de note. Zero au bout a gauche veut dire « je ne note
   pas » : un controle qui glisse doit pouvoir ne rien dire, sinon
   l'ouvrir reviendrait deja a noter. */
.jauge-note { margin: 0 0 16px; }
.jauge-note__rang { display: flex; align-items: center; gap: 14px; }

.jauge-note__curseur {
    flex: 1 1 auto;
    min-width: 0;
    height: 26px;
    margin: 0;
    background: none;
    accent-color: var(--accent);
    cursor: pointer;
}
.jauge-note__curseur:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* La valeur, en gros a droite : c'est elle qu'on regarde en glissant. */
.jauge-note__valeur {
    flex: 0 0 auto;
    min-width: 5.2ch;
    text-align: right;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}
.jauge-note__curseur.est-vide + .jauge-note__valeur,
.jauge-note__curseur[value="0"] + .jauge-note__valeur { color: var(--dim); }

/* Les bornes, sous le rail, alignees sur ses extremites. */
.jauge-note__bornes {
    display: flex;
    justify-content: space-between;
    margin: 2px 0 0;
    padding-right: calc(5.2ch + 14px);
    color: var(--dim);
    font-size: 0.72rem;
}

/* Retirer n'est pas enregistrer : le bouton le dit sans crier. */
.bouton--retirer {
    background: none;
    border: 1px solid var(--line-hi);
    color: var(--dim);
    font-weight: 600;
    padding: 9px 16px;
    font-size: 0.86rem;
}
.bouton--retirer:hover { border-color: var(--rouge); color: var(--rouge); filter: none; }

/* Le brouillon repris. Un liseré orange et un ton sobre : c'est une
   information, pas une alerte, mais il faut qu'on sache avant de
   refermer que ce qu'on lit n'est pas encore parti. */
.brouillon {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin: 0 0 12px;
    padding: 9px 12px;
    border-left: 2px solid var(--accent);
    background: var(--panel-hi);
    color: var(--muted);
    font-size: 0.82rem;
}

.brouillon__jeter {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.brouillon__jeter:hover { color: var(--text); }
.brouillon__jeter:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* =================== PASSAGE ENTRE LES PAGES ===================
   Le site public et l'espace n'ont pas le meme bandeau : plus large
   dans l'espace, plus serre. D'une page a l'autre, le navigateur fait
   glisser chaque piece du bandeau jusqu'a sa nouvelle place (la marque,
   les liens, le bouton du membre) et fond le reste de la page, au lieu
   de tout redessiner d'un coup. Les memes noms sont poses des deux
   cotes (assets/css/style.css et espace/assets/espace.css). Un
   navigateur qui ne connait pas ces regles change de page comme avant. */
@view-transition { navigation: auto; }

::view-transition-group(*) {
    animation-duration: .42s;
    animation-timing-function: cubic-bezier(.16, .84, .3, 1);
}
::view-transition-old(root),
::view-transition-new(root) { animation-duration: .28s; }

/* Les liens et le bouton du membre ne sont pas les memes d'une page a
   l'autre : ils glissent et se fondent, a leur taille, sans etre etires
   au gabarit de l'autre page. Le bouton du membre reste cale a droite. */
::view-transition-old(wsr-liens), ::view-transition-new(wsr-liens),
::view-transition-old(wsr-moi), ::view-transition-new(wsr-moi) {
    width: auto;
    height: 100%;
    object-fit: none;
}
::view-transition-old(wsr-moi), ::view-transition-new(wsr-moi) { left: auto; right: 0; }

@media (prefers-reduced-motion: reduce) {
    @view-transition { navigation: none; }
}

.barre          { view-transition-name: wsr-barre; }
.barre__marque  { view-transition-name: wsr-marque; }
.barre__onglets { view-transition-name: wsr-liens; }
.barre__moi     { view-transition-name: wsr-moi; }

/* Les icones des badges reglés « partout », a cote d'un pseudo : une petite
   tuile bordee de la couleur du badge, centree sur la ligne du texte. */
.insigne {
    margin-left: 5px;
    font-size: 0.62em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.55em;
    height: 1.55em;
    flex: 0 0 auto;
    box-sizing: border-box;
    padding: 0;
    border: 1px solid color-mix(in srgb, currentColor 55%, transparent);
    border-radius: 5px;
    background: color-mix(in srgb, currentColor 12%, transparent);
    line-height: 1;
    /* Exactement la hauteur du texte, posee sur sa ligne : un conteneur
       qui coupe ce qui depasse (overflow: hidden) ne la rogne plus. */
    vertical-align: -0.18em;
}
.insigne::before { display: block; }

/* Dans le bandeau, la bordure du badge un peu plus marquee. */
.barre__pseudo .insigne { border-width: 1.5px; border-color: color-mix(in srgb, currentColor 75%, transparent); }

/* Le badge colle sur une photo : le meme partout (bandeau, profils, section
   Animes, arbre de la famille). Une tuile carree en bas a droite, 40 % de
   la photo, qui deborde un peu, cernee de la couleur du fond comme la
   pastille de statut de Discord. Ses mesures suivent la photo. */
.cadre-insigne { position: relative; display: inline-flex; flex: 0 0 auto; line-height: 0; }
.insigne-colle {
    /* Centre sur le bord du rond, a 45° en bas a droite (85 % de la photo),
       quelle que soit la taille de la photo et du badge. */
    --t: min(42%, 24px);
    position: absolute;
    left: calc(85% - var(--t) / 2);
    top: calc(85% - var(--t) / 2);
    width: var(--t);
    height: var(--t);
    min-width: 11px;
    min-height: 11px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid color-mix(in srgb, currentColor 65%, transparent);
    border-radius: 28%;
    background: color-mix(in srgb, currentColor 20%, #11151F);
    /* L'anneau prend la couleur du fond OU EST la photo (--fond-insigne,
       pose par la carte qui la contient) : sur une carte plus claire que la
       page, un anneau couleur de page se voyait comme une grosse bordure. */
    box-shadow: 0 0 0 2px var(--fond-insigne, var(--page-bg, #0B0E16));
    container-type: size;
    line-height: 1;
    pointer-events: auto;
}
.insigne-colle .bi { display: block; width: 1em; height: 1em; font-size: 62cqh; line-height: 1; }
.insigne-colle .bi::before { display: block; line-height: 1; vertical-align: 0; transform: translateY(7%); }   /* les glyphes tombent un peu haut dans leur boite */

/* La recherche de membres du bandeau : la loupe deroule un champ dans la
   barre meme, vers la gauche ; les noms s'affichent dessous. */
.barre__cherche { position: relative; margin-left: auto; display: flex; align-items: center; gap: 4px; }
.barre.est-js .barre__cherche + .barre__moi, .barre__cherche + .barre__moi { margin-left: 6px; }
.barre__loupe {
    order: 2;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--dim);
    font-size: 0.95rem;
    cursor: pointer;
    transition: background-color .16s ease, color .16s ease;
}
.barre__loupe .bi::before { display: block; }
.barre__loupe:hover, .barre__loupe[aria-expanded="true"] { background: var(--panel-hi); color: var(--text); }
.barre__loupe:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.barre__cherche-boite {
    order: 1;
    position: relative;
    width: 0;
    opacity: 0;
    visibility: hidden;
    transition: width .32s var(--ease), opacity .2s ease, visibility 0s linear .32s;
}
.barre__cherche.est-ouverte .barre__cherche-boite {
    width: 210px;
    opacity: 1;
    visibility: visible;
    transition: width .32s var(--ease), opacity .2s ease .05s, visibility 0s;
}
.barre__cherche-boite input {
    width: 100%;
    height: 34px;
    padding: 0 12px;
    border: 1px solid var(--line-hi);
    border-radius: 999px;
    background: var(--panel);
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
}
.barre__cherche-boite input:focus { outline: none; border-color: var(--accent); }
.barre__cherche-boite input::-webkit-search-cancel-button { display: none; }
.barre__cherche-liste {
    position: absolute;
    z-index: 40;
    top: calc(100% + 8px);
    right: 0;
    width: max(100%, 240px);
    margin: 0;
    padding: 0;
    list-style: none;
}
.barre__cherche-liste:not(:empty) {
    padding: 4px;
    border: 1px solid var(--line-hi);
    border-radius: 12px;
    background: var(--panel);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .45);
    animation: fade-up .22s var(--ease);
}
.barre__cherche-qui {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 8px;
    border-radius: 8px;
    font-size: 0.86rem;
}
.barre__cherche-qui span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barre__cherche-qui:hover, .est-actif > .barre__cherche-qui { background: var(--panel-hi); }
.barre__cherche-qui img, .barre__cherche-ini { flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
.barre__cherche-ini { display: grid; place-items: center; background: var(--panel-hi); color: var(--muted); font-size: 0.7rem; font-weight: 700; }
.barre__cherche-vide { padding: 8px 10px; color: var(--dim); font-size: 0.84rem; }
/* Sur telephone : un champ plus court, et les noms sur la largeur de l'ecran. */
@media (max-width: 760px) {
    .barre__cherche.est-ouverte .barre__cherche-boite { width: min(150px, 38vw); }
    .barre__cherche-liste { position: fixed; top: calc(var(--header-h) + 6px); left: 12px; right: 12px; width: auto; }
}
@media (prefers-reduced-motion: reduce) {
    .barre__cherche-boite, .barre__cherche.est-ouverte .barre__cherche-boite { transition: none; }
}
/* Sur telephone, la deconnexion s'efface le temps de chercher : la place manque. */
@media (max-width: 760px) {
    .barre:has(.barre__cherche.est-ouverte) .sortir { display: none; }
}

/* Sur telephone, la recherche sort du bandeau : un petit bouton discret,
   flottant en bas a droite (au-dessus de la barre d'onglets de la section
   Animes), qui deroule son champ vers la gauche ; les noms s'affichent
   au-dessus. Meme champ, meme script, seule la place change. */
@media (max-width: 760px) {
    .barre__cherche {
        position: fixed;
        z-index: 45;
        right: 14px;
        bottom: calc(14px + env(safe-area-inset-bottom));
        margin: 0;
    }
    body:has(.an-onglets) .barre__cherche { bottom: calc(76px + env(safe-area-inset-bottom)); }
    .barre.est-js .barre__cherche + .barre__moi, .barre__cherche + .barre__moi { margin-left: auto; }
    .barre__loupe {
        width: 40px;
        height: 40px;
        border: 1px solid var(--line-hi);
        border-radius: 50%;
        background: var(--panel);
        color: var(--muted);
        font-size: 0.9rem;
        box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
    }
    .barre__cherche.est-ouverte .barre__cherche-boite { width: calc(100vw - 28px - 44px); }
    .barre__cherche-boite input { height: 40px; box-shadow: 0 6px 18px rgba(0, 0, 0, .35); }
    .barre__cherche-liste { position: absolute; top: auto; bottom: calc(100% + 8px); left: 0; right: auto; width: 100%; }
    .barre:has(.barre__cherche.est-ouverte) .sortir { display: revert; }
}

/* Le cadre de profil : une image autour de la photo, partout ou elle
   s'affiche. 112 % de la photo, centre : son anneau mord un peu sur le
   bord de la photo au lieu de s'ajouter autour (a 124 %, il doublait sa
   taille). Le badge colle passe par-dessus. */
.cadre-photo {
    position: absolute;
    left: -6%;
    top: -6%;
    width: 112%;
    height: 112%;
    max-width: none;
    pointer-events: none;
    z-index: 1;
}
.insigne-colle { z-index: 2; }

/* Un badge a image : l'image remplit la tuile, sous la meme bordure. */
.insigne-colle.avec-image { overflow: hidden; background: var(--fond-insigne, var(--page-bg, #0B0E16)); }
.insigne-colle .badge-img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 0; }

/* =================== LE CLASSEMENT DES POINTS ===================
   Le total en haut de « Mon espace » s'ouvre dessus. */
button.tete__solde {
    padding: 6px 10px;
    margin-right: -10px;
    border: 0;
    border-radius: 10px;
    background: none;
    color: inherit;
    font: inherit;
    text-align: right;
    cursor: pointer;
    transition: background-color .16s ease;
}
button.tete__solde:hover { background: var(--panel-hi); }
button.tete__solde:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tete__solde-l .bi { margin-left: 6px; color: var(--accent); font-size: 0.9em; }

.modale.modale--classement { width: min(560px, calc(100vw - 24px)); }
.modale--classement .modale__corps {
    max-height: min(70vh, 640px);
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--line-hi) transparent;
}

.podium { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; gap: 8px; margin: 4px 0 18px; padding: 0; list-style: none; }
.podium__place a { display: grid; justify-items: center; gap: 4px; text-align: center; }
.podium__photo { width: 56px; height: 56px; }
.podium__place--1 .podium__photo { width: 72px; height: 72px; }
.podium__nom { max-width: 100%; margin-top: 4px; font-weight: 600; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.podium__points { color: var(--accent); font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; }
.podium__marche {
    width: 100%;
    margin-top: 6px;
    padding: 8px 0;
    background: var(--panel-hi);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.2rem;
    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
}
.podium__place--1 .podium__marche { padding: 18px 0; background: color-mix(in srgb, #FFC94D 22%, var(--panel-hi)); color: #FFC94D; }
.podium__place--2 .podium__marche { padding: 12px 0; color: #C9D1DD; }
.podium__place--3 .podium__marche { color: #D9925B; }
.podium__place.est-moi .podium__nom { color: var(--accent); }

.classement { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.classement__ligne {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 8px;
}
.classement__ligne:hover { background: var(--panel-hi); }
.classement__ligne.est-moi { background: color-mix(in srgb, var(--accent) 12%, var(--panel)); box-shadow: inset 2px 0 0 var(--accent); }
.classement__place { color: var(--dim); font-family: var(--font-display); font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.classement__qui { display: flex; align-items: center; gap: 10px; min-width: 0; }
.classement__photo { width: 30px; height: 30px; }
.classement__nom { font-weight: 600; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.classement__titre { padding: 2px 8px; border: 1px solid color-mix(in srgb, var(--r) 45%, transparent); border-radius: 999px; color: var(--r); font-size: 0.72rem; font-weight: 600; white-space: nowrap; }
.classement__points { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.classement__points small { color: var(--dim); font-size: 0.75em; }
.classement__ecart { padding: 2px 0; color: var(--dim); text-align: center; }
@media (max-width: 520px) {
    .classement__titre { display: none; }
    .classement__ligne { grid-template-columns: 28px minmax(0, 1fr) auto; }
}
/* Dans le classement, les badges colles un peu plus petits. */
.modale--classement .insigne-colle { --t: min(36%, 20px); }

/* Un booster WitTCG : son design debout, a la forme du paquet. */
.tuile__icone--paquet {
    width: 36px;
    height: 60px;
    border-radius: 4px;
    background: none;
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.45);
}

/* --- L'application installable (assets/app.js, notif.js) --- */

.appli { display: grid; gap: 12px; }
.appli .carte__titre { margin-bottom: 0; }
.appli__tete { display: flex; align-items: center; gap: 12px; }
.appli__icone { flex: none; width: 48px; height: 48px; border-radius: 12px; }
.appli__texte { margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.45; }
.appli__installer { justify-self: start; }
.appli__note { margin: 0; }
.appli__note--ok { color: var(--text); }
.appli__note--ok i { color: #4ade80; }
.appli__notifs { display: grid; gap: 10px; padding-top: 14px; border-top: 1px solid var(--line); }
.appli__notifs[hidden] { display: none; }
.appli__sous { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 0.95rem; }
.appli__etat { margin: 0; }
.appli__activer {
    justify-self: start; padding: 9px 14px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer;
    font: 700 0.85rem var(--font-body); color: var(--accent-ink); background: var(--accent);
}
.appli__activer.est-couper { color: var(--text); background: var(--panel-hi); }
.appli__activer:disabled { opacity: 0.45; cursor: default; }
.appli__choix { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 2px 10px; }
.appli__case { display: flex; align-items: center; gap: 10px; padding: 6px 4px; border-radius: 8px; font-size: 0.86rem; cursor: pointer; }
.appli__case:hover { background: var(--panel-hi); }
.appli__case input { width: 16px; height: 16px; margin: 0; accent-color: var(--accent); }
.appli__case:has(input:disabled) { opacity: 0.45; cursor: default; }

/* ============================== ENTREE ========================= */
/* L'ecran de connexion. Deux colonnes : ce que l'espace apporte, et
   par ou l'on entre. Il reprend le vocabulaire du site public (le
   panneau, l'angle coupe, l'accent chaud) sans copier une carte : c'est
   la premiere page qu'un visiteur voit, elle a droit a sa mise en page. */

.entree {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(24px, 4vw, 52px);
    align-items: center;
    max-width: 940px;
    margin: clamp(16px, 6vh, 64px) auto;
}

.entree__marque {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.76rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--muted);
}
.entree__marque::before {
    content: "";
    width: 20px;
    height: 2px;
    background: var(--accent);
}

.entree__titre {
    margin: 0 0 14px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 5.4vw, 2.9rem);
    line-height: 1.05;
    letter-spacing: -0.03em;
}

.entree__texte {
    margin: 0 0 24px;
    max-width: 38ch;
    color: var(--muted);
}

.entree__liste {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 11px;
    font-size: 0.92rem;
    color: var(--text);
}
.entree__liste li {
    display: flex;
    align-items: center;
    gap: 11px;
}
/* L'icone dans sa case, pour que les trois lignes s'alignent quelle
   que soit la largeur du glyphe. */
.entree__liste i {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    background: var(--panel-hi);
    border: 1px solid var(--line);
    font-size: 0.92rem;
    color: var(--accent);
}

/* Le nom du jeu, dans sa police. Valorant pose ses lettres plus haut
   et un peu plus petites qu'Inter : on le recale sur la ligne de base
   des autres entrees de la liste. */
.entree__wittcg {
    font-family: 'Valorant', var(--font-display), sans-serif;
    font-size: 0.92em;
    letter-spacing: 0.05em;
    position: relative;
    top: 1px;
    /* L'interlettrage s'ajoute aussi APRES la derniere lettre : sans
       cette compensation, le deux-points qui suit flottait a deux
       espaces du nom. */
    margin-right: -0.05em;
}

.entree__portes {
    padding: clamp(22px, 3.4vw, 30px);
    background: var(--panel);
    border: 1px solid var(--line);
    clip-path: polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut),
                       100% 100%, var(--cut) 100%, 0 calc(100% - var(--cut)));
}

.entree__sous-titre {
    margin: 0 0 18px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.portes {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Un bouton par fournisseur. Le fond reste celui du site : seule la
   marque porte sa couleur, dans le logo et au survol. Trois aplats
   satures cote a cote jureraient avec le reste de l'espace, et le
   bouton le plus colore attirerait l'oeil sans raison. */
.porte {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 13px 16px;
    background: var(--panel-hi);
    border: 1px solid var(--line-hi);
    color: var(--text);
    font-size: 0.95rem;
    text-decoration: none;
    transition: border-color .16s var(--ease), transform .16s var(--ease), background .16s var(--ease);
}
.porte:hover {
    background: var(--panel);
    border-color: var(--marque, var(--accent));
    transform: translateY(-1px);
}
.porte:focus-visible {
    outline: 2px solid var(--marque, var(--accent));
    outline-offset: 2px;
}

.porte__logo {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    color: var(--marque, var(--text));
}
.porte__texte { flex: 1; }
.porte__texte b { font-weight: 600; }

.porte__fleche {
    flex-shrink: 0;
    font-size: 0.9rem;
    color: var(--dim);
    transition: transform .16s var(--ease), color .16s var(--ease);
}
.porte:hover .porte__fleche {
    color: var(--marque, var(--accent));
    transform: translateX(3px);
}

/* Les couleurs officielles, posees une fois chacune. */
.porte--discord { --marque: #5865F2; }
.porte--tiktok  { --marque: #25F4EE; }
.porte--patreon { --marque: #FF424D; }

.entree__note { margin-top: 16px; }

@media (max-width: 760px) {
    .entree {
        grid-template-columns: 1fr;
        gap: 26px;
    }
    /* Sur telephone, on entre d'abord ; l'argumentaire vient apres. */
    .entree__portes { order: -1; }
    .entree__texte  { max-width: none; }
}

/* --- Un onglet qui en contient d'autres (Animations) --- */
/* Il s'ouvre au survol et au clavier, sans une ligne de script. Le
   titre reste un lien vers sa premiere entree : au doigt, ou le survol
   n'existe pas, on tombe sur la page plutot que dans le vide. */

.barre__groupe { position: relative; display: inline-flex; }

.barre__onglet--groupe { display: inline-flex; align-items: center; gap: 5px; }
.barre__fleche {
    font-size: 0.68rem;
    transition: transform .16s var(--ease);
}
.barre__groupe:hover .barre__fleche,
.barre__groupe:focus-within .barre__fleche { transform: rotate(180deg); }

.barre__sous {
    position: absolute;
    top: 100%;
    left: 50%;
    z-index: 40;
    display: flex;
    flex-direction: column;
    min-width: 170px;
    padding: 6px;
    background: var(--panel);
    border: 1px solid var(--line-hi);
    box-shadow: 0 18px 40px rgba(0,0,0,0.45);
    /* Invisible mais pose : il garde sa place, donc sa largeur ne saute
       pas a l'ouverture. Le pointeur le traverse sans le declencher. */
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, -6px);
    transition: opacity .14s var(--ease), transform .14s var(--ease), visibility .14s;
}
.barre__groupe:hover .barre__sous,
.barre__groupe:focus-within .barre__sous {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 4px);
}
/* Un pont invisible entre l'onglet et le menu : sans lui, descendre la
   souris de l'un a l'autre traverse un vide et le menu se referme. */
.barre__sous::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -8px;
    height: 8px;
}

.barre__souslien {
    padding: 9px 12px;
    color: var(--muted);
    font-size: 0.88rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background .14s var(--ease), color .14s var(--ease);
}
.barre__souslien:hover { background: var(--panel-hi); color: var(--text); }
.barre__souslien.est-ici { color: var(--text); font-weight: 600; }
.barre__souslien:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Sur telephone, le bandeau devient une liste verticale (barre.js) :
   le deroulant s'y aplatit plutot que de flotter. */
@media (max-width: 760px) {
    .barre__groupe { display: block; width: 100%; }
    .barre__sous {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        min-width: 0;
        padding: 0 0 0 14px;
        background: none;
        border: 0;
        box-shadow: none;
    }
    .barre__fleche { display: none; }
}

/* Offrir un booster : a qui part le paquet. Un resume (le destinataire
   choisi, « Pour moi » au depart) qui s'ouvre sur l'annuaire des
   membres et sa recherche. Memes aplats et memes entailles que le reste
   de la boutique ; le choix coche prend l'accent. */
.offrir {
    margin: 0 0 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--panel-hi);
}

.offrir__resume {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px 8px 8px;
    cursor: pointer;
    list-style: none;
}
.offrir__resume::-webkit-details-marker { display: none; }
.offrir__resume:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 8px; }

.offrir__pastille {
    flex: none;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--line-hi);
    color: var(--text);
    font: 700 0.72rem/1 var(--font-display);
    overflow: hidden;
}
.offrir__pastille img { display: block; width: 100%; height: 100%; object-fit: cover; }

.offrir__qui { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.offrir__nom { font-weight: 600; font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.offrir__aide { font-size: 0.78rem; color: var(--dim); }

.offrir__resume::after {
    content: "";
    flex: none;
    width: 8px;
    height: 8px;
    margin-right: 4px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg) translateY(-2px);
    transition: transform .2s var(--ease);
}
.offrir[open] .offrir__resume::after { transform: rotate(-135deg) translate(-2px, -2px); }
.offrir.est-offert { border-color: var(--accent); }
.offrir.est-offert .offrir__aide { color: var(--accent); }

.offrir__annuaire { border-top: 1px solid var(--line); padding: 8px; animation: fade-up .25s var(--ease); }

.offrir__cherche {
    width: 100%;
    margin: 0 0 8px;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--panel);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}
.offrir__cherche:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.offrir__liste {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 4px;
    max-height: 232px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--line-hi) transparent;
}
.offrir__liste::-webkit-scrollbar { width: 4px; }
.offrir__liste::-webkit-scrollbar-track { background: transparent; }
.offrir__liste::-webkit-scrollbar-thumb { background: var(--line-hi); border-radius: 2px; }
.offrir__liste::-webkit-scrollbar-thumb:hover { background: var(--muted); }

.offrir__ligne {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 6px 8px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.88rem;
}
.offrir__ligne[hidden] { display: none; }
.offrir__ligne:hover { background: var(--panel); }
.offrir__ligne .offrir__pastille { width: 26px; height: 26px; font-size: 0.64rem; }
.offrir__ligne .offrir__nom { font-weight: 500; font-size: inherit; }

/* Le bouton radio reste atteignable au clavier, mais c'est la ligne
   entiere qui montre le choix. */
.offrir__radio { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.offrir__ligne:has(.offrir__radio:checked) {
    background: var(--accent);
    color: var(--accent-ink);
    clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 7px 100%, 0 calc(100% - 7px));
}
.offrir__ligne:has(.offrir__radio:checked) .offrir__nom { font-weight: 700; }
.offrir__ligne:has(.offrir__radio:focus-visible) { outline: 2px solid var(--text); outline-offset: -2px; }

.offrir__vide { margin: 8px 6px 4px; font-size: 0.85rem; color: var(--muted); }
.offrir__vide[hidden] { display: none; }
