/* ─── GameTracker — thème "gamy" sombre néon ─────────────────────────── */

:root {
  --bg: #0b0d16;
  --bg-2: #121523;
  --panel: #151a2c;
  --panel-2: #1b2138;
  --line: rgba(120, 140, 255, .14);
  --text: #e8ecff;
  /* Texte secondaire qu'on demande vraiment de LIRE (descriptions, aides,
     sous-titres de section) — retour de Tim, 2026-08-10 : "la font grise un
     peu terne". --muted tombait à 5,27:1 de contraste sur --panel-2, ce qui
     passe AA mais fatigue en Rajdhani (police étroite et maigre) sur
     plusieurs lignes ; --text-2 monte à ~10:1.
     --muted N'EST PAS remplacé partout : il reste le bon choix pour les
     libellés et métadonnées (dates, unités, raretés, compteurs, placeholders),
     où l'effacement porte la hiérarchie. Tout basculer aplatirait la page. */
  --text-2: #c5cdec;
  --muted: #8b93b8;
  --accent: #7c5cff;
  --accent-2: #00e5c3;
  --gold: #ffb938;
  --danger: #ff5470;
  --steam: #66c0f4;
  --psn: #4a7fff;
  --ea: #ff4747;
  --ubisoft: #949df0;
  --radius: 14px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Repéré par Tim : le logo centré de #loading (position:fixed;inset:0)
   se décale d'environ 8px quand la scrollbar verticale apparaît — mesuré
   en réel (clientWidth passe de 1920 à 1905 dès que le contenu du
   dashboard, déjà rendu en dessous pendant le chargement, dépasse la
   hauteur d'écran). .loading-active bloque le scroll de la page tant que
   l'écran de chargement est affiché, pour que la scrollbar n'apparaisse
   qu'une fois révélé — retiré par hideLoadingScreen() (app.js) et par le
   repli "pas de session" qui masque #loading directement. */
body.loading-active { overflow: hidden; }

body {
  background:
    radial-gradient(1200px 500px at 80% -10%, rgba(124, 92, 255, .16), transparent 60%),
    radial-gradient(900px 400px at 0% 110%, rgba(0, 229, 195, .07), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: 'Rajdhani', system-ui, sans-serif;
  min-height: 100vh;
  /* Pied de page collé en bas même sur une vue courte (retour de Tim :
     Changelog/Roadmap n'a pas assez de contenu pour pousser le footer
     jusqu'au bas réel de l'écran). Un seul des 4 <div id="view-*"> est
     visible à la fois (les autres sont display:none, donc hors flux flex) —
     lui donner flex-grow comble l'espace restant et pousse .site-footer
     tout en bas, sans toucher au défilement normal si le contenu est plus
     grand que l'écran (flex-shrink:0 sur ces vues). */
  display: flex; flex-direction: column;
}
#view-overview, #view-leaderboards, #view-analyses, #view-profile, #view-admin { flex: 1 0 auto; }

/* ─── Topbar ─── */
.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 22px 32px 10px;
  flex-wrap: wrap;
}
.logo {
  font-family: 'Orbitron', sans-serif;
  font-weight: 900; font-size: 22px; letter-spacing: 2px;
  text-shadow: 0 0 24px rgba(124, 92, 255, .55);
  white-space: nowrap;
}
.logo-accent { color: var(--accent); }
/* Pictogrammes TYG (frontend/icons.js) — remplacent les émojis. Taille en em : l'icône
   suit le font-size de son conteneur ; couleur = currentColor, donc elle s'allume avec le
   texte. Pas `.ic` : cette classe est déjà celle des conteneurs d'émoji de la navigation. */
.ico { width: 1.35em; height: 1.35em; margin: -.2em 0; vertical-align: -.3em; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.ico-gold { color: #ffb938; } .ico-silver { color: #c9d1e6; } .ico-bronze { color: #c8763a; }
/* Couleur des conteneurs d'icône : les émojis portaient chacun la leur, une icône prend celle de son
   conteneur. Turquoise pour les tuiles et les titres (le violet, trop sombre sur ce fond, se lisait mal ;
   retour de Tim, 2026-10-03), couleur de plateforme pour les cartes du Guide. */
.guide-card-icon, .roadmap-icon, .section-title .ico { color: var(--accent-2); }
.guide-card.steam .guide-card-icon { color: var(--steam); }
.guide-card.psn .guide-card-icon { color: var(--psn); }
/* Logo pioche (topbar + sidebar) — désactivé pour l'instant (retour de Tim,
   2026-08-21), règle gardée pour une réactivation rapide. Taille en em pour
   suivre le font-size du .logo parent (22px topbar, 18px sidebar) sans
   dupliquer la règle. */
.logo-pickaxe { height: 1.4em; width: auto; vertical-align: middle; margin: -.15em -2px -.15em 0; }
.search {
  flex: 1; min-width: 200px; max-width: 420px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font: 600 15px 'Rajdhani', sans-serif;
  padding: 9px 14px; outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(124, 92, 255, .18); }
.search::placeholder { color: var(--muted); }
.sort-wrap { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; text-transform: uppercase; letter-spacing: 1px; }
/* Pendant du .sort-wrap { display:none } mobile plus bas — sans ce
   display:none de base, le bouton "⇅ Tri" (créé pour piloter le <select>
   caché sous 700px) restait aussi visible sur desktop à côté du <select>
   natif, en double. Repéré en écrivant le CSS desktop de cette même zone
   (2026-08-24), jamais vérifié en vrai jusque-là. */
.mobile-sort-wrap { display: none; }
.sort-wrap select {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 600 14px 'Rajdhani', sans-serif; padding: 7px 10px; outline: none;
}

.topbar-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; flex-wrap: wrap; }
/* Témoin de synchro en arrière-plan (retour de Tim) — visible depuis
   n'importe quelle page une fois "Continuer en arrière-plan" cliqué sur le
   popup de sync, cliquable pour le rouvrir. */
.sync-indicator {
  display: flex; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid rgba(124, 92, 255, .4); border-radius: 999px;
  color: var(--accent-2); font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .3px;
  padding: 6px 12px; cursor: pointer; transition: border-color .18s;
}
.sync-indicator:hover { border-color: var(--accent); }
.sync-indicator-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  border: 2px solid rgba(0, 229, 195, .3); border-top-color: var(--accent-2);
  animation: spin .8s linear infinite;
}
/* Badge "jeux non identifiés" (mockup mockup-unmatched-games.html, retour de
   Tim) — même principe que .sync-indicator : accès permanent dans la topbar,
   pas seulement un déclenchement post-sync, tant qu'il reste des jeux non
   ignorés. */
.unmatched-indicator {
  display: flex; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid rgba(255, 185, 56, .4); border-radius: 999px;
  color: var(--gold); font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .3px;
  padding: 6px 12px; cursor: pointer; transition: border-color .18s;
}
.unmatched-indicator:hover { border-color: var(--gold); }
/* Cloche notifications (mockup-wishlist-notif.html, retour de Tim
   2026-08-31) — même famille visuelle que .topbar-avatar, badge façon
   .sidebar-badge. Masquée par défaut (classe .hidden posée dans le HTML),
   affichée/masquée par renderWishlistSidebarBadge() selon qu'il reste au
   moins un jeu de la wishlist à J-5 ou moins. */
.topbar-bell {
  position: relative; width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: var(--panel); border: 1px solid var(--line); color: var(--text-2);
  display: flex; align-items: center; justify-content: center; font-size: 17px;
  cursor: pointer; transition: border-color .18s;
}
.topbar-bell.hidden { display: none; }
.topbar-bell:hover { border-color: var(--accent); color: var(--text); }
.topbar-bell-badge {
  position: absolute; top: -4px; right: -4px;
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16;
  font: 800 10px 'Orbitron', sans-serif; min-width: 16px; height: 16px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; padding: 0 3px;
  border: 2px solid var(--panel);
}
.topbar-bell-badge.hidden { display: none; }
.topbar-bell[aria-expanded="true"] { border-color: var(--accent); color: var(--text); box-shadow: 0 0 0 3px rgba(124, 92, 255, .18); }

/* Panneau de la cloche (mockup mockup-cloche-notifications.html, variante B,
   2026-10-04) : « À régler » épinglé, puis l'historique de 30 jours. Posé dans
   la page sous la cloche (positionNotifPanel), toute la largeur sur téléphone. */
.npanel { position: absolute; z-index: 600; width: 392px; max-width: calc(100vw - 16px); background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 18px 50px rgba(0, 0, 0, .45); overflow: hidden; }
.npanel.hidden { display: none; }
.npanel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 16px 11px; border-bottom: 1px solid var(--line); }
.npanel-title { font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1.4px; color: var(--text); text-transform: uppercase; }
.npanel-mark { font: 600 13px 'Rajdhani', sans-serif; color: var(--accent-2); background: none; border: none; cursor: pointer; padding: 0; }
.npanel-body { max-height: min(560px, calc(100vh - 200px)); overflow-y: auto; }
.npanel-group { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.3px; text-transform: uppercase; color: var(--muted);
  padding: 12px 16px 4px; display: flex; gap: 8px; align-items: center; }
.npanel-group .n { font: 800 10px 'Orbitron', sans-serif; color: #0b0d16; background: var(--gold); border-radius: 999px; padding: 1px 6px; letter-spacing: 0; }
.npanel-pinned { background: rgba(255, 185, 56, .05); border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.npanel-empty { color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; padding: 22px 16px; margin: 0; text-align: center; }
.nitem { display: grid; grid-template-columns: 34px 1fr auto; gap: 11px; align-items: start; padding: 9px 16px; position: relative; cursor: pointer; }
.nitem:hover { background: rgba(124, 92, 255, .07); }
.nitem:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.nitem.unread::before { content: ''; position: absolute; left: 6px; top: 22px; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-2); box-shadow: 0 0 8px rgba(0, 229, 195, .7); }
.nitem-ic { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center; justify-content: center; border: 1px solid; flex-shrink: 0; }
.nitem-ic .ico { width: 17px; height: 17px; }
.nitem-ic.c-friend { color: var(--accent); border-color: rgba(124, 92, 255, .45); background: rgba(124, 92, 255, .12); }
.nitem-ic.c-release { color: var(--accent-2); border-color: rgba(0, 229, 195, .4); background: rgba(0, 229, 195, .09); }
.nitem-ic.c-gold { color: var(--gold); border-color: rgba(255, 185, 56, .45); background: rgba(255, 185, 56, .1); }
.nitem-ic.c-tyg { color: #0b0d16; border-color: transparent; background: linear-gradient(140deg, var(--accent), var(--accent-2)); }
.nitem-ic.c-game { color: var(--steam); border-color: rgba(102, 192, 244, .4); background: rgba(102, 192, 244, .09); }
.nitem-ic.c-psn { color: var(--psn); border-color: rgba(74, 127, 255, .45); background: rgba(74, 127, 255, .1); }
.nitem-ic.c-danger { color: var(--danger); border-color: rgba(255, 84, 112, .45); background: rgba(255, 84, 112, .1); }
.nitem-txt { min-width: 0; }
.nitem-t { font: 700 14.5px/1.25 'Rajdhani', sans-serif; color: var(--text); overflow-wrap: anywhere; }
.nitem-s { font: 500 13px/1.35 'Rajdhani', sans-serif; color: var(--text-2); margin-top: 2px; overflow-wrap: anywhere; }
.nitem-when { font: 600 12px 'Rajdhani', sans-serif; color: var(--muted); white-space: nowrap; padding-top: 2px; }
.nitem-tag { font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--gold);
  border: 1px solid rgba(255, 185, 56, .5); border-radius: 6px; padding: 0 5px; margin-left: 6px; vertical-align: 1px; white-space: nowrap; }
.nitem-link { background: none; border: none; padding: 0; font: inherit; color: var(--text-2); cursor: pointer; text-decoration: underline;
  text-decoration-color: rgba(197, 205, 236, .35); text-underline-offset: 2px; }
.nitem-link:hover { color: var(--accent-2); }
.nitem-acts { display: flex; gap: 6px; margin-top: 7px; }
.nitem-btn { font: 700 12.5px 'Rajdhani', sans-serif; border-radius: 8px; padding: 4px 11px; border: 1px solid var(--line); background: var(--bg); color: var(--text-2); cursor: pointer; }
.nitem-btn.primary { border: none; background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; }
.nitem-btn:disabled { opacity: .5; cursor: default; }
.npanel-news { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 16px; border: none; border-top: 1px solid var(--line);
  background: var(--bg-2); font: 600 13.5px 'Rajdhani', sans-serif; color: var(--text-2); cursor: pointer; text-align: left; }
.npanel-news .ico { width: 16px; height: 16px; color: var(--muted); flex-shrink: 0; }
.npanel-news b { color: var(--text); }
.npanel-news .go { margin-left: auto; color: var(--accent-2); white-space: nowrap; }
.npanel-foot { padding: 9px 16px 11px; font: 500 12px 'Rajdhani', sans-serif; color: var(--muted); border-top: 1px solid var(--line); }
@media (max-width: 760px) {
  .npanel { width: auto; left: 0; right: 0; max-width: none; border-radius: 0; border-left: none; border-right: none; }
}
/* Changelog ouvert depuis la cloche : le jour mis en évidence. */
.changelog-entry.cl-hl { background: rgba(0, 229, 195, .06); box-shadow: inset 3px 0 0 var(--accent-2); padding-left: 10px; padding-right: 8px; border-radius: 0 8px 8px 0; margin-bottom: 3px; }
.cl-from { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--accent-2); margin-left: 8px; }
.cl-ann { font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--accent-2); }
/* Pastille profil topbar (tâche #21, retour de Tim) — raccourci direct vers
   le sommaire du Profil (initiale ou photo). */
.topbar-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  background: linear-gradient(140deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font: 800 13px 'Orbitron', sans-serif; color: #0b0d16;
  border: none; cursor: pointer; overflow: hidden;
  box-shadow: 0 0 12px rgba(124, 92, 255, .35);
  transition: box-shadow .2s;
}
.topbar-avatar:hover { box-shadow: 0 0 18px rgba(124, 92, 255, .55); }
.topbar-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ─── Nav desktop dans la topbar (mockup mockup-desktop-topbar-nav.html,
   retour de Tim) — en dessous de 761px, la barre du bas (.mnav) prend le
   relais. Masquée par défaut (mobile-first) : @media (min-width: 761px)
   plus bas l'affiche. */
.topbar-nav { display: none; align-items: center; gap: 4px; }
.topbar-nav-link {
  position: relative;
  background: none; border: none; border-radius: 10px;
  color: var(--muted); font: 700 14px 'Rajdhani', sans-serif; letter-spacing: .3px;
  padding: 8px 14px; cursor: pointer; transition: all .16s;
  display: flex; align-items: center; gap: 6px; white-space: nowrap;
}
.topbar-nav-link:hover { color: var(--text); background: rgba(124, 92, 255, .1); }
.topbar-nav-link.active {
  color: var(--text);
  background: linear-gradient(120deg, rgba(124, 92, 255, .3), rgba(0, 229, 195, .14));
  box-shadow: inset 0 0 0 1px rgba(124, 92, 255, .45), 0 0 16px rgba(124, 92, 255, .18);
}
.topbar-nav-link.soon { cursor: default; opacity: .55; }
.topbar-nav-link.soon:hover { background: none; color: var(--muted); }
.topbar-nav-link .sidebar-badge { font-size: 11px; padding: 1px 7px; }
.topbar-spacer { flex: 1; }

/* Recherche repliée en loupe sur desktop (façon Hashnode, retour de Tim) —
   même #search qu'avant, juste enveloppé. Par défaut (mobile-first) les
   deux enveloppes passent en display:contents : le <input> reste un
   enfant flex direct de .topbar, exactement comme avant ce chantier, donc
   le comportement mobile existant (recherche toujours visible, pleine
   largeur en 2e rangée) n'est pas touché d'un pixel. @media (min-width:
   701px) plus bas leur redonne une vraie boîte pour le panneau ancré. */
.topbar-search, .search-panel { display: contents; }
.search-icon-btn { display: none; }

/* Boutons d'action réduits à leur icône (même gabarit que la topbar
   mobile, désormais aussi sur desktop, retour de Tim : "je convertirais
   aussi le 'ajouter un jeu' en +"). Scopé à .chip-icon-only plutôt que
   d'élargir la règle .chip-label déjà utilisée par .filters-view-controls
   sous 700px (styles.css plus bas) — .chip-label seul est réutilisé sur
   une dizaine de boutons dans toute l'app, l'étendre sans le scoper
   aurait effacé leur libellé visuel partout, pas seulement sur ces deux
   boutons-là. */
.chip-icon-only {
  width: 38px; height: 38px; flex: none; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; border-radius: 50%;
}
.chip-icon-only .chip-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Petite indication de fraîcheur des données (retour de Tim) — discrète,
   en haut à droite du dashboard, alignée sur le padding horizontal du
   premier kpi-group juste en dessous. Vide (donc invisible) tant que
   loadData() n'a pas résolu state.lastSyncedAt. */
.last-synced-note {
  padding: 14px 32px 0; margin: 0; text-align: right;
  color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif;
}

/* ─── Stat tiles (regroupées par kpi-group, tâche #41) ─── */
.kpi-group { padding: 0 32px; margin-top: 6px; }
.kpi-group-label {
  color: var(--muted); font: 700 11px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: 1.6px; margin: 14px 0 8px;
}
/* KPI de la vue d'ensemble (mockup mockup-kpis-sans-barre.html, piste 2b,
   2026-10-05) : un panneau par groupe, colonnes séparées d'un filet. Les filets
   sont des ombres posées à gauche et en haut de chaque case : ils restent justes
   quand la grille passe de quatre à deux colonnes, et le panneau les rogne au bord. */
.kpi-panel {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 12px 0 4px; background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
}
.kpi-cell {
  display: flex; align-items: center; gap: 14px; padding: 16px 20px; min-width: 0;
  box-shadow: -1px 0 0 var(--line), 0 -1px 0 var(--line);
}
.kpi-ic {
  width: 40px; height: 40px; flex: none; border-radius: 10px; display: grid; place-items: center;
  color: var(--accent-2); background: rgba(124, 92, 255, .12); border: 1px solid rgba(124, 92, 255, .3);
}
.kpi-ic .ico { width: 20px; height: 20px; margin: 0; vertical-align: 0; }
.kpi-ic.gold { color: var(--gold); background: rgba(255, 185, 56, .10); border-color: rgba(255, 185, 56, .35); }
.kpi-ic img { width: 22px; height: auto; }   /* coupes officielles de Leaderboards */
/* Leaderboards : cinq chiffres (platines et trois paliers, succès Steam). */
.kpi-panel-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* Fiche ami : la barre par plateforme prend la largeur de la colonne. */
.fr-kpis .fr-stat-bar { margin-top: 8px; }
.kpi-body { min-width: 0; flex: 1; }
.kpi-val { font: 700 28px/1.1 'Orbitron', sans-serif; color: var(--text); letter-spacing: .3px; white-space: nowrap; }
.kpi-val.gold { color: var(--gold); }
.kpi-lbl { font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted); margin-top: 4px; }
.kpi-sub { font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); margin-top: 4px; }
.kpi-sub .up { color: var(--accent-2); font-weight: 700; }
.kpi-short { display: none; }
/* Entre la tablette et l'écran large, quatre colonnes ne tiennent plus. */
@media (max-width: 960px) { .kpi-panel-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 860px) { .kpi-panel, .kpi-panel-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) {
  .kpi-cell { padding: 12px; gap: 10px; align-items: flex-start; }
  .kpi-ic { width: 32px; height: 32px; border-radius: 9px; }
  .kpi-ic .ico { width: 17px; height: 17px; }
  .kpi-ic img { width: 18px; }
  .kpi-val { font-size: 21px; }
  .kpi-long { display: none; }
  .kpi-short { display: inline; }
}

/* ─── Filtres ─── */
.filters { display: flex; align-items: center; gap: 14px; padding: 14px 32px; flex-wrap: wrap; }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip-sep { width: 1px; height: 22px; background: var(--line); }
.chip {
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; letter-spacing: .5px;
  padding: 6px 14px; cursor: pointer; text-transform: uppercase;
  transition: all .18s;
}
.chip:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
/* Variante "action principale" générique (déjà utilisée scopée à
   .setup-step.todo — ici non scopée, pour la wishlist et au-delà). */
.chip.primary { background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border-color: transparent; font-weight: 700; }
.dropdown-filter { position: relative; }
.dropdown-panel {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 30;
  min-width: 320px; max-width: min(560px, 90vw); max-height: 260px; overflow-y: auto;
  background: var(--panel-2); border: 1px solid var(--accent); border-radius: 12px;
  padding: 14px; box-shadow: 0 20px 44px rgba(0, 0, 0, .5);
  animation: fade .15s both;
}
.dropdown-panel .chip-row { gap: 8px; }
.chip.active {
  background: linear-gradient(120deg, rgba(124, 92, 255, .25), rgba(0, 229, 195, .12));
  border-color: var(--accent); color: var(--text);
  box-shadow: 0 0 14px rgba(124, 92, 255, .25);
}

/* ─── Filtres regroupés dans une carte (tâche #41) ─── */
.filters-card {
  margin: 14px 32px 4px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 20px;
}
.filters-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.filters-title {
  font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1px; color: var(--text);
  display: flex; align-items: center; gap: 8px;
  cursor: pointer; user-select: none;
}
.filters-title:hover { color: var(--text); }
.filters-title .st-chevron { width: 15px; height: 15px; }
/* Entonnoir plutôt que la loupe d'origine (retour de Tim, 2026-08-21) — une
   loupe évoque une recherche, pas un filtre. SVG (currentColor, même
   gabarit que .menu-btn svg) plutôt qu'un glyphe emoji : plus net, et
   rendu identique sur toutes les plateformes contrairement à 🔎/⚗️/etc.
   dont le rendu varie selon l'OS. */
.filters-title-icon { width: 15px; height: 15px; flex: none; }
.filters-view-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ─── Carte Filtres repliable (retour de Tim, 2026-08-14) — ne masque QUE
   .filter-groups ; .filters-card-head (titre + boutons de droite) reste
   toujours visible, repliée ou non. Même mécanisme max-height que les
   sections de jeux ci-dessous. ────────────────────────────────────────── */
.filters-card.collapsed .filters-title .st-chevron { transform: rotate(-90deg); }
.filter-groups {
  /* Pas de max-height fixe au repos : un plafond en dur coupait le contenu
     dès qu'il le dépassait (voir .game-section .grid plus bas pour le bug
     que ça a causé sur "Liste complète"). app.js anime max-height via une
     vraie mesure (scrollHeight) au moment du clic, puis le relâche
     (max-height:none) une fois déplié. */
  overflow: hidden;
  transition: max-height .3s cubic-bezier(.2, .8, .3, 1), opacity .22s ease-out, margin-top .3s;
  opacity: 1;
}
.filters-card.collapsed .filter-groups { max-height: 0; opacity: 0; margin-top: 0; pointer-events: none; }

/* ─── Panneau "Configurer la vue" — réordonnancement des sections de listes
   par glisser-déposer + création rapide d'une liste. ───────────────────── */
.configure-view-wrap { position: relative; }
.configure-view-panel {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 40;
  width: 320px;
  background: var(--panel-2); border: 1px solid var(--accent); border-radius: 14px;
  padding: 16px; box-shadow: 0 20px 44px rgba(0, 0, 0, .5);
  animation: fade .15s both;
}
.configure-view-panel.hidden { display: none; }
.cvp-title {
  font: 700 12px 'Orbitron', sans-serif; letter-spacing: .8px; color: var(--text);
  margin-bottom: 4px;
}
.cvp-sub { color: var(--muted); font: 500 12px 'Rajdhani', sans-serif; line-height: 1.5; margin-bottom: 14px; }
.cvp-list { display: flex; flex-direction: column; gap: 6px; }
.cvp-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 10px;
}
.cvp-row.pinned { opacity: .65; background: transparent; border-style: dashed; }
.cvp-handle { color: var(--muted); font-size: 14px; cursor: grab; letter-spacing: -2px; flex: none; }
.cvp-row.pinned .cvp-handle { cursor: default; color: var(--line); }
.cvp-swatch { width: 9px; height: 9px; border-radius: 50%; background: var(--c, var(--accent)); flex: none; }
.cvp-name { flex: 1; font: 700 12.5px 'Rajdhani', sans-serif; color: var(--text); letter-spacing: .3px; }
.cvp-pin-note { font: 600 9.5px 'Rajdhani', sans-serif; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
.cvp-count { font: 600 11px 'Rajdhani', sans-serif; color: var(--muted); }
.cvp-delete-btn {
  display: flex; align-items: center; justify-content: center; flex: none;
  width: 22px; height: 22px; padding: 0; border-radius: 6px;
  background: transparent; border: none; color: var(--muted); cursor: pointer;
  transition: color .15s, background .15s;
}
.cvp-delete-btn:hover { color: var(--danger); background: rgba(255, 84, 112, .14); }
.cvp-row.drag-over { border-color: var(--accent-2); box-shadow: 0 0 0 1px var(--accent-2); }
.cvp-row.dragging { opacity: .35; }
.cvp-note { color: var(--muted); font: 500 11px 'Rajdhani', sans-serif; margin-top: 12px; line-height: 1.5; }
.cvp-create-row {
  display: flex; gap: 8px; margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--line);
}
.cvp-create-row input {
  flex: 1; background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 600 12.5px 'Rajdhani', sans-serif; padding: 7px 10px;
}
.cvp-create-row input:focus { outline: none; border-color: var(--accent); }
.cvp-create-row .chip { padding: 7px 12px; font-size: 11.5px; }
.filter-groups { display: flex; flex-wrap: wrap; gap: 20px 28px; }
.filter-group { display: flex; flex-direction: column; gap: 7px; }
.filter-group-label {
  color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: 1.4px;
}
.filters-reset {
  color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; text-decoration: underline;
  text-underline-offset: 3px; cursor: pointer; background: none; border: none;
}
.filters-reset:hover { color: var(--text); }
.active-count {
  background: var(--accent); color: #0b0d16; border-radius: 999px;
  font: 800 10px 'Rajdhani', sans-serif; padding: 1px 7px; margin-left: 6px;
}

@media (max-width: 760px) {
  .filter-groups { gap: 14px 20px; }
  .kpi-group { padding: 0 16px; }
  .filters-card { margin-left: 16px; margin-right: 16px; }
}

/* ─── Grille de jaquettes ─── */
main { padding: 10px 32px; }
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 20px;
  /* Pas de `perspective` ici (2026-09-30, cinquième retour sur l'inclinaison
     des jaquettes : « elles bougent et s'étirent violemment, surtout dans la
     liste complète ») : son point de fuite est le CENTRE de la grille, et
     celle de « Liste complète » fait 27 130 px de haut. Une carte en haut ou
     en bas s'y trouvait à ~13 000 px du point de fuite — 3° d'inclinaison y
     faisaient passer la dernière carte de 437 à 847 px de haut et bondir de
     205 px. La perspective est portée par chaque carte, dans sa propre
     transformation (attachTilt). */
}

/* Dashboard : "En cours" mis en avant, une section par liste de l'utilisateur
   (générées dynamiquement, voir renderListSectionScaffolding() dans app.js),
   puis "Liste complète" — plutôt qu'une grille plate unique. */
.game-section { margin-bottom: 34px; }
.section-title {
  display: flex; align-items: center; gap: 10px; cursor: pointer; user-select: none;
  font: 700 15px 'Orbitron', sans-serif; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--text); margin-bottom: 16px;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.section-title:hover { color: var(--text); }
.st-label { flex: 1; }
.playing-section .section-title { color: var(--accent-2); }
.list-section.muted .section-title { color: var(--muted); }

/* ─── Repli/dépli d'une section (retour de Tim, 2026-08-14) — chevron
   cliquable, état persisté en localStorage (voir getCollapsedSections()/
   saveCollapsedSections() dans app.js). max-height plutôt que display:none
   pour garder la transition animée. ─────────────────────────────────── */
.st-chevron {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex: none;
  transition: transform .25s cubic-bezier(.2, .8, .3, 1);
  color: var(--muted);
}
.st-count {
  font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .3px; text-transform: none;
  color: var(--muted); background: var(--panel); border: 1px solid var(--line);
  border-radius: 999px; padding: 1px 8px;
}
.game-section.collapsed .st-chevron { transform: rotate(-90deg); }
.game-section .grid, .game-section .section-empty-hint {
  /* Pas de max-height fixe au repos (retour de Tim, 2026-08-16) : un plafond
     en dur (4000px) coupait "Liste complète" dès que la bibliothèque le
     dépassait — plus moyen de scroller jusqu'en bas. app.js anime
     max-height via une vraie mesure (scrollHeight) au moment du clic sur le
     chevron, puis le relâche (max-height:none) une fois déplié, donc aucun
     plafond ne s'applique jamais au repos, quelle que soit la taille de la
     bibliothèque. */
  overflow: hidden;
  transition: max-height .35s cubic-bezier(.2, .8, .3, 1), opacity .25s ease-out, margin-top .35s;
  opacity: 1;
}
.game-section.collapsed .grid, .game-section.collapsed .section-empty-hint {
  max-height: 0; opacity: 0; margin-top: -20px; pointer-events: none;
}

/* Section de liste sans jeu — reste affichée (contrairement à l'ancien
   comportement où Backlog/Abandonné se masquaient si vides) pour servir de
   cible au glisser-déposer. */
.section-empty-hint {
  border: 1px dashed var(--line); border-radius: var(--radius);
  padding: 22px; text-align: center; color: var(--muted);
  font: 600 12.5px 'Rajdhani', sans-serif;
}

/* "En cours" en plus grand et plus espacé que le reste — c'est la section
   qu'on veut mettre en avant. */
.grid-playing {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 28px;
}

/* ── Vue Liste (esquisse 1c, mockup mockup-list-view.html, retour de Tim
   2026-08-21) — bascule Grille/Liste juste après la carte filtres.
   body.list-view fait passer TOUS les .grid (dont .grid-playing, qui garde
   sinon un gap plus large) en colonne pleine largeur d'un coup, plutôt que
   de basculer une classe sur chaque conteneur de section individuellement
   — un seul point de bascule pour toute la page. ─────────────────────── */
.view-toggle-row { display: flex; justify-content: flex-end; gap: 6px; margin: 20px 0; }
body.list-view .grid { display: flex; flex-direction: column; gap: 8px; }

.list-row {
  display: flex; align-items: center; gap: 14px; padding: 10px 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.list-row:hover { border-color: rgba(124, 92, 255, .5); background: var(--panel-2); }
.list-row.selected { outline: 2px solid var(--accent); outline-offset: 2px; }
.list-row-cover { width: 46px; height: 62px; border-radius: 6px; object-fit: cover; flex: none; background: var(--panel-2); }
/* width/height/border-radius répétés explicitement plutôt que de compter
   sur .cover-fallback (width/height:100%, définie plus bas dans la
   feuille) : à spécificité égale, la règle définie en dernier gagnerait et
   ferait perdre la taille fixe de la vignette. */
.list-row-cover.cover-fallback { width: 46px; height: 62px; border-radius: 6px; font-size: 13px; }
.list-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.list-row-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.list-row-name { font: 700 14.5px 'Rajdhani', sans-serif; color: var(--text); }
.list-row-bar-row { display: flex; align-items: center; gap: 10px; }
.list-row-bar-row .ttb-bar { flex: 1; }
.list-row-bar-row .ttb-note, .list-row-bar-row .warn { flex: none; white-space: nowrap; }
.list-row-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; min-width: 92px; }
.list-row-side .hours { font-family: 'Orbitron', sans-serif; font-size: 15px; font-weight: 700; }
.list-row-side .last-played { font-size: 11px; }

@media (max-width: 640px) {
  .list-row { flex-wrap: wrap; }
  .list-row-side { flex-direction: row; align-items: center; justify-content: space-between; width: 100%; margin-left: 60px; }
}

/* Drag & drop entre Backlog et Liste complète. */
.card.dragging { opacity: .35; }
.grid.drop-target {
  outline: 2px dashed var(--accent-2); outline-offset: 10px;
  border-radius: var(--radius);
  background: rgba(0, 229, 195, .05);
}
/* Témoin de réordonnancement libre (mockup mockup-manual-card-order.html) —
   un enfant de grille comme un autre, .grid/.list-view le décale
   naturellement au fil du survol plutôt que de nécessiter un calcul de
   position manuel. */
.card-placeholder {
  border: 2px dashed var(--accent-2); border-radius: var(--radius);
  background: rgba(0, 229, 195, .06);
  min-height: 260px;
  animation: fade .12s both;
}
.list-view .card-placeholder { min-height: 64px; }

.card {
  position: relative;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  overflow: hidden;
  cursor: pointer;
  transform-style: preserve-3d;
  transition: transform .18s ease-out, box-shadow .25s, border-color .25s;
  animation: card-in .5s cubic-bezier(.2, .8, .3, 1) both;
  /* Cascade bornée à 20 cartes (2026-09-26). Sans le min(), le délai vaut
     `--i * 28ms` sur TOUTE la grille : avec les 441 jeux de la bibliothèque,
     la dernière carte attendait 12,3 s avant de bouger — et `both` lui fait
     tenir l'état de départ pendant tout ce temps, soit une carte invisible,
     26 px trop bas et à 94 %. Défiler vers le bas dans les secondes qui
     suivent un chargement tombait donc sur des cartes figées, qui bondissaient
     au survol. 20 × 28 ms = 0,56 s, l'ordre d'un écran de cartes. */
  animation-delay: calc(min(var(--i), 20) * 28ms);
}
@keyframes card-in {
  from { opacity: 0; transform: translateY(26px) scale(.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Rejouée seulement au tout premier chargement — sinon un simple drag & drop
   ou changement de filtre redonnait l'impression que toute la page se recharge. */
.card.no-anim { animation: none; }
.card:hover {
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55), 0 0 24px rgba(124, 92, 255, .25);
  border-color: rgba(124, 92, 255, .55);
  z-index: 2;
}
.card.playing { border-color: rgba(0, 229, 195, .4); }
.card.playing:hover { box-shadow: 0 18px 44px rgba(0, 0, 0, .55), 0 0 26px rgba(0, 229, 195, .35); }

/* Contour + lueur tournante pour les jeux platinés — le ruban de couleur
   (conic-gradient) tourne en continu autour de la carte ; --angle enregistrée
   via @property pour une interpolation fluide de l'angle (sans ça, l'angle
   sauterait d'une valeur à l'autre au lieu de tourner). */
@property --angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
.card.platinum {
  border-color: rgba(0, 229, 195, .5);
  box-shadow: 0 0 16px rgba(0, 229, 195, .18);
}
.card.platinum::before {
  content: ''; position: absolute; inset: 0; border-radius: var(--radius);
  padding: 2px; pointer-events: none; z-index: 1;
  background: conic-gradient(from var(--angle), var(--accent), var(--accent-2), var(--gold), var(--accent-2), var(--accent));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: platinum-ring-spin 4s linear infinite;
}
@keyframes platinum-ring-spin { to { --angle: 360deg; } }
.card.platinum:hover { box-shadow: 0 18px 44px rgba(0, 0, 0, .55), 0 0 30px rgba(0, 229, 195, .4); }

.cover-wrap { position: relative; aspect-ratio: 3 / 4; overflow: hidden; background: var(--bg-2); }
.cover {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .45s cubic-bezier(.2, .8, .3, 1), filter .45s;
}
.card:hover .cover { transform: scale(1.07); }
/* Pas de jaquette : la manette, en gris atténué (couleur du conteneur), un peu plus grande que le texte. */
.cover-fallback .ico, .living-tile-fallback .ico, .review-row-cover-empty .ico { width: 1.7em; height: 1.7em; }
.cover-fallback {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  font-family: 'Orbitron', sans-serif; font-size: 34px; color: rgba(139, 147, 184, .5);
  background:
    repeating-linear-gradient(45deg, rgba(124, 92, 255, .06) 0 10px, transparent 10px 20px),
    var(--bg-2);
}

/* sheen qui balaye la jaquette au hover */
.cover-wrap::after {
  content: '';
  position: absolute; inset: -40% auto -40% -80%; width: 55%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .16), transparent);
  transform: skewX(-18deg) translateX(0);
  transition: none; pointer-events: none;
}
.card:hover .cover-wrap::after { animation: sheen .8s ease-out; }
@keyframes sheen { to { transform: skewX(-18deg) translateX(480%); } }

/* halo pulsé pour les jeux en cours */
.badge-live {
  position: absolute; top: 8px; left: 8px;
  background: rgba(0, 20, 16, .8); border: 1px solid var(--accent-2);
  color: var(--accent-2); border-radius: 999px;
  font: 700 10px 'Orbitron', sans-serif; letter-spacing: 1px;
  padding: 4px 9px; backdrop-filter: blur(4px);
  display: flex; align-items: center; gap: 5px;
}
.badge-live .dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2);
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 229, 195, .7); }
  60% { box-shadow: 0 0 0 7px rgba(0, 229, 195, 0); }
}

/* Petit trophée dans la boîte d'infos (haut-droit), pas sur la jaquette —
   retour de Tim, 2026-08-05. Toujours visible (pas de fade-in) ; rejoue une
   rotation à chaque survol de la carte plutôt qu'une seule fois — testé en
   figé-après-un-seul-passage d'abord, le survol répété rend mieux à l'usage. */
.card-trophy-mini { position: absolute; top: 8px; right: 8px; width: 34px; z-index: 3; pointer-events: none; }
.card-trophy-mini img {
  width: 100%; object-fit: contain;
  filter: drop-shadow(0 0 8px rgba(0, 229, 195, .5)) drop-shadow(0 0 14px rgba(124, 92, 255, .3));
}
.card.platinum:hover .card-trophy-mini img { animation: trophy-spin-hover 2.2s ease-in-out; }
@keyframes trophy-spin-hover {
  0%   { transform: rotateY(0deg); }
  100% { transform: rotateY(1080deg); }
}

.badge-done {
  position: absolute; top: 8px; right: 8px;
  background: rgba(20, 16, 0, .75); border: 1px solid var(--gold); color: var(--gold);
  border-radius: 999px; font-size: 12px; padding: 3px 8px; backdrop-filter: blur(4px);
}

/* Carte devenue flex column (retour de Tim) : cover-wrap garde son
   aspect-ratio, card-body prend le reste (flex:1) et son propre pied de
   carte (.card-foot) se colle en bas via margin-top:auto — la grille étire
   déjà chaque carte à la hauteur de la plus grande de sa rangée, il restait
   juste à faire remonter cet espace en bas plutôt que le laisser vide. */
.card { display: flex; flex-direction: column; }
.card-body { position: relative; padding: 10px 12px 12px; display: flex; flex: 1; flex-direction: column; gap: 6px; }
.card-title {
  font-weight: 700; font-size: 15.5px; line-height: 1.15;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: 2.3em;
}
/* Hauteur figée (une ligne) + troncature d'un nom de plateforme trop long —
   sans ça, un badge qui retombe à la ligne pousse tout le reste (barre,
   tags, statut) plus bas sur cette carte précise, cassant l'alignement
   entre les cartes d'une même rangée (retour de Tim). */
.badges { display: flex; gap: 4px; flex-wrap: wrap; min-height: 20px; max-height: 20px; overflow: hidden; }
.badge {
  border: 1px solid; border-radius: 4px; padding: 1px 6px;
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase;
  white-space: nowrap; max-width: 108px; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom;
  /* Générique pour une plateforme ajoutée manuellement (tâche #31) sans
     couleur dédiée — surchargé par .badge.steam/.psn/.ea/.ubisoft ci-dessous. */
  color: var(--muted); border-color: var(--line);
}
.badge.steam { color: var(--steam); border-color: rgba(102, 192, 244, .5); }
.badge.psn { color: var(--psn); border-color: rgba(74, 127, 255, .55); }
.badge.ea { color: var(--ea); border-color: rgba(255, 71, 71, .5); }
.badge.ubisoft { color: var(--ubisoft); border-color: rgba(148, 157, 240, .55); }
.badge.early-access { color: var(--gold); border-color: rgba(255, 185, 56, .55); background: rgba(255, 185, 56, .08); }

.hours { font-family: 'Orbitron', sans-serif; font-size: 14px; font-weight: 700; }
.hours .na { color: var(--muted); font-family: 'Rajdhani', sans-serif; font-weight: 600; font-size: 13px; }

/* barre de progression vs référence IGDB */
.ttb-bar { position: relative; height: 8px; border-radius: 4px; background: var(--bg-2); border: 1px solid var(--line); }
.ttb-fill {
  position: absolute; inset: 0 auto 0 0; border-radius: 4px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 10px rgba(124, 92, 255, .5);
  transition: width .8s cubic-bezier(.2, .8, .3, 1);
}
.ttb-tick { position: absolute; top: -3px; bottom: -3px; width: 2px; background: rgba(232, 236, 255, .55); }
/* Le repère encore devant, quand le « normal » est derrière (nextRefSeconds) */
.ttb-tick.target { width: 3px; background: var(--gold); box-shadow: 0 0 8px rgba(255, 185, 56, .7); }
.ttb-note { color: var(--muted); font-size: 12px; }
.ttb-note .gold { color: var(--gold); }
.warn {
  color: var(--danger); font-size: 11.5px;
  border: 1px solid rgba(255, 84, 112, .4); border-radius: 5px;
  background: rgba(255, 84, 112, .08); padding: 2px 6px;
}

.list-badge {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  background: var(--c, var(--accent)); color: #0b0d16; border-radius: 6px;
  padding: 2px 8px; font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .3px;
}
/* Emplacement toujours réservé (vide si le jeu n'est dans aucune liste) —
   même logique que .badges ci-dessus : sans hauteur fixe, la présence ou
   l'absence du badge de liste décale la barre/les tags/le statut selon la
   carte (retour de Tim). */
.list-slot { min-height: 22px; }
.list-edit-row { margin-bottom: 0; }
.tags-row { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.tag-pill {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--c, var(--line)); color: var(--c, var(--muted));
  border-radius: 999px; padding: 1px 8px; font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .3px;
  background: color-mix(in srgb, var(--c, transparent) 12%, transparent);
}
.tag-pill.more { border-style: dashed; color: var(--muted); border-color: var(--line); background: none; }
/* Un seul tag visible sur la carte, le reste dans une bulle au clic sur
   "+N" (retour de Tim) — même mécanisme ouverture/fermeture que le panneau
   de filtre tags existant (stopPropagation + fermeture au clic document). */
.tag-more-trigger { cursor: pointer; }
.tag-popover {
  position: fixed; z-index: 30; display: flex; flex-wrap: wrap; gap: 5px; max-width: 220px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}
.tag-popover.hidden { display: none; }
.tag-edit-list { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 10px; min-height: 22px; }
.tag-edit-list .tag-pill { padding: 4px 6px 4px 11px; font-size: 12px; }
.tag-remove { background: none; border: none; color: inherit; cursor: pointer; font-size: 14px; line-height: 1; padding: 0 0 0 3px; opacity: .75; }
.tag-remove:hover { opacity: 1; }
.tag-empty { color: var(--muted); font-size: 12px; }
.tag-add-row { display: flex; gap: 6px; }
.tag-add-row input, .mode-add input, .mode-row .mode-rename-input {
  flex: 1; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 500 13px 'Rajdhani', sans-serif; padding: 6px 10px; outline: none;
}
.tag-add-row input:focus, .mode-add input:focus, .mode-row .mode-rename-input:focus { border-color: var(--accent); }
.mode-row .mode-rename-input { width: 100%; box-sizing: border-box; }
.tag-add-row .chip { padding: 5px 12px; }

.edit-row { margin-bottom: 12px; }
.edit-row:last-child { margin-bottom: 0; }
.edit-row label { display: block; color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .6px; margin-bottom: 5px; }
/* La couleur posée ici ne s'applique jamais : .version-hint/.edit-hint plus
   bas (ligne ~1108, 2026-08-05) redéfinit color, font et fond pour le même
   motif de lisibilité. Laissé tel quel plutôt que basculé sur --text-2, qui
   n'aurait rien changé. */
.edit-hint { color: var(--muted); font-size: 11px; margin-top: 5px; line-height: 1.4; }
.edit-input-row { display: flex; gap: 6px; }
.edit-input-row input {
  flex: 1; min-width: 0; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 500 13px 'Rajdhani', sans-serif; padding: 6px 10px; outline: none;
  color-scheme: dark;
}
.edit-input-row input:focus { border-color: var(--accent); }
.edit-input-row .chip { padding: 5px 12px; white-space: nowrap; }
.edit-version-select {
  flex: 1; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 500 12.5px 'Rajdhani', sans-serif; padding: 6px 8px; outline: none;
  color-scheme: dark;
}
.plat-row .manual-note { color: var(--muted); font-size: 10.5px; font-family: 'Rajdhani', sans-serif; }
.edit-input-row .chip.secondary { border-color: rgba(255, 84, 112, .4); color: var(--danger); padding: 5px 10px; }

.card-foot { display: flex; justify-content: space-between; align-items: center; margin-top: auto; padding-top: 6px; }
.pill { border-radius: 999px; font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; padding: 3px 9px; border: 1px solid; }
.pill.playing { color: var(--accent-2); border-color: rgba(0, 229, 195, .5); background: rgba(0, 229, 195, .08); }
.pill.played { color: #b9c2ee; border-color: rgba(148, 157, 240, .4); background: rgba(148, 157, 240, .08); }
.pill.finished { color: var(--gold); border-color: rgba(255, 185, 56, .5); background: rgba(255, 185, 56, .08); }
.pill.not_started { color: var(--muted); border-color: rgba(139, 147, 184, .35); }
.pill.installed { color: var(--muted); border-color: rgba(139, 147, 184, .35); border-style: dashed; }
.last-played { color: var(--muted); font-size: 12px; }

/* ─── Panneau détail plein écran (esquisse "test idée 3", 2026-08-01) ───
   Fond flouté plein écran façon "Terminé" (.finish-overlay). Seule la
   jaquette flotte librement (pas d'encadré) — les infos, elles, restent
   dans une "card" comme avant (juste replacée à côté de la jaquette
   plutôt qu'en slide-over étroit). */
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.detail {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .55);
  backdrop-filter: blur(20px);
  animation: fade .3s both;
}

/* Rangée flex qui portait .detail-inner et la colonne d'onglets flottants.
   Depuis le 2026-09-28 les onglets sont dans la boîte (.tabs-bar) : ce wrapper
   ne contient plus que .detail-inner, gardé pour ne rien changer au centrage. */
.detail-with-tabs { display: flex; align-items: center; gap: 20px; max-width: 100%; }
.detail-inner {
  display: flex; align-items: flex-start;
  width: min(1680px, 94vw); height: min(900px, 90vh);
  animation: modal-in .32s cubic-bezier(.2, .8, .3, 1) both;
}
@keyframes modal-in { from { transform: scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }

.detail-close {
  position: fixed; top: 20px; right: 24px; z-index: 60;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: 16px; width: 32px; height: 32px; cursor: pointer;
  transition: all .2s;
}
.detail-close:hover { color: var(--text); border-color: var(--accent); }

/* Icônes globales (suppression/masquage) — dans la boîte .detail-info-col
   (position:relative déjà en place pour le badge platine), coin haut-droit,
   plutôt que sur le fond flouté plein écran comme .detail-close (retour de
   Tim, 2026-08-04). */
.detail-icon-btn {
  position: absolute; top: 20px; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .3); border-radius: 8px;
  color: var(--text); font-size: 15px; width: 32px; height: 32px; cursor: pointer;
  transition: all .2s;
}
.detail-icon-btn:hover { color: var(--accent-2); border-color: var(--accent); background: rgba(255, 255, 255, .12); }
.detail-delete-btn { right: 20px; }
.detail-hide-btn { right: 60px; }

/* Picker de version (suppression globale) — réutilise le modal générique. */
.version-picker-list { display: flex; flex-direction: column; gap: 6px; max-height: 300px; overflow-y: auto; }
.version-picker-item {
  text-align: left; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 8px 12px; cursor: pointer; font: 500 13px 'Rajdhani', sans-serif;
  transition: border-color .15s;
}
.version-picker-item:hover { border-color: var(--accent); }

.detail-cover-col {
  flex: none; width: 460px; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 40px;
}
/* Jaquettes des autres éditions/versions (ex. Steam Complete Edition vs
   Remastered), nettement plus petites que la jaquette principale. */
.version-thumbs { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; max-width: 100%; }
.version-thumb {
  width: 64px; aspect-ratio: 3/4; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--line);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .4);
}
.detail-cover {
  width: 100%; max-width: 380px; aspect-ratio: 3/4; object-fit: cover; border-radius: 16px;
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .6), 0 0 50px rgba(124, 92, 255, .25);
}
.detail-info-col {
  position: relative;
  flex: 1; min-width: 0; height: 100%; overflow-y: auto; padding: 40px 48px 40px 32px;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35);
  border-radius: 20px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
}
/* Vrai trophée Platine PSN (fond retiré), en haut à droite de la boîte
   d'infos — jeux platinés uniquement. .has-platinum-badge réserve la place
   dans l'en-tête pour que le titre ne passe pas dessous. */
.detail-platinum-badge {
  position: absolute; top: 64px; right: 28px; width: 150px; z-index: 1;
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, .5)) drop-shadow(0 0 22px rgba(0, 229, 195, .35));
  animation: fade .5s .1s both;
}
.detail-header.has-platinum-badge { padding-right: 170px; }
.detail-platinum-mini { display: none; height: 56px; width: auto; align-self: center; margin-left: -6px;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .5)) drop-shadow(0 0 16px rgba(0, 229, 195, .3)); }
/* Titre du panneau détail : dégradé animé reprenant la palette du contour
   platine (accent/accent-2/gold), appliqué à tous les jeux — pas seulement
   les platinés (retour de Tim, 2026-08-05, "petite modif geek"). Un dégradé
   linéaire qui glisse plutôt qu'un conic-gradient tournant (adapté à du
   texte en ligne, contrairement à l'anneau autour d'une carte). */
.detail-title {
  font-family: 'Orbitron', sans-serif; font-size: 28px; font-weight: 700; line-height: 1.25; margin-bottom: 8px;
  background: linear-gradient(90deg, var(--text), var(--accent-2), var(--gold), var(--accent), var(--text));
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: title-shimmer 12s ease-in-out infinite;
}
@keyframes title-shimmer {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
.detail-sub { color: var(--muted); font-size: 14px; margin-top: 6px; }

@media (max-width: 860px) {
  /* .detail centrait (align-items:center) sans jamais permettre de
     défiler : une fois les onglets repassés au-dessus de .detail-inner
     (order:-1, règle plus bas) la hauteur totale dépassait le viewport et
     le centrage rognait le haut des onglets hors écran, sans aucun moyen
     de les atteindre (bug mobile 2026-08-19, "je ne vois pas tous les
     boutons de menus"). Ancré en haut + défilement plutôt que centré +
     hauteur figée (92vh) : .detail-inner reprend sa hauteur naturelle. */
  .detail { align-items: flex-start; overflow-y: auto; padding: 20px 0 40px; }
  .detail-inner { flex-direction: column; width: 94vw; height: auto; }
  .detail-cover-col { width: auto; padding: 24px 24px 0; }
  .detail-cover { width: 40vw; max-width: 220px; }
  /* align-self: stretch — dans la colonne de .detail-inner (align-items:
     flex-start), la boîte prenait sinon la largeur de son contenu le plus
     large : une description de trophée sur une ligne la portait à 843 px sur
     un écran de 375 (constaté le 2026-09-28, mockup-guide-powerpyx-page.html). */
  /* overflow: visible — c'est tout le panneau (.detail) qui défile ici ; si la
     boîte gardait overflow-y:auto, elle resterait le repère de la barre
     d'onglets collée et celle-ci partirait avec elle (constaté dans le mockup). */
  .detail-info-col { padding: 20px 24px 28px; height: auto; align-self: stretch; overflow: visible; }
  /* (Barre d'onglets en mise en page empilée : voir le @media qui suit
     .tabs-bar — placé ici, il était écrasé par les règles de base, écrites
     plus loin dans le fichier.) */
  /* .detail-close est fixed (top:20/right:24, relatif à l'écran) ; en layout
     empilé, le coin haut-droit de la boîte coïncide avec lui — badge platine
     descendu d'un cran pour lui laisser la place. */
  /* Le grand trophée laisse la place à une version réduite, 3ᵉ élément de
     la ligne des chiffres (.detail-platinum-mini, retour de Tim 2026-10-02,
     mockup mockup-fiche-trophee-mobile.html) : il descendait à côté d'eux
     sans en faire partie, et le coin haut-droit garde les icônes. */
  .detail-platinum-badge { display: none; }
  .detail-header.has-platinum-badge { padding-right: 0; }
  .detail-platinum-mini { display: block; }
}

.detail-stats { display: flex; gap: 26px; margin: 14px 0; }
.big-num { font-family: 'Orbitron', sans-serif; font-size: 26px; font-weight: 700; }
.big-num.ratio { color: var(--accent-2); }
.big-label { color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: 1.2px; }

/* Titres de section de la fiche (2026-10-04, mockup mockup-titres-sections-fiche.html,
   variante B) : Orbitron blanc avec un trait au dégradé de la marque. Avant, en
   Rajdhani gris, le titre ressortait moins que les lignes qu'il annonce (retour de
   Tim sur l'onglet Ajustements). Vaut pour tous les onglets de la fiche. */
.detail-section { border-top: 1px solid var(--line); padding: 18px 0 14px; }
.detail-section h3 {
  font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--text); margin-bottom: 12px; padding-left: 11px; position: relative;
}
.detail-section h3::before {
  content: ''; position: absolute; left: 0; top: 1px; bottom: 1px; width: 3px; border-radius: 2px;
  background: linear-gradient(var(--accent), var(--accent-2));
}
/* En-tête de la section Référence IGDB avec ref-search-btn (mockup validé
   docs/mockups/mockup-ref-search-alternative.html, retour de Tim 2026-08-28) —
   bouton toujours visible, pas seulement sur les cas détectés comme suspects. */
.ref-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.ref-search-btn { display: flex; align-items: center; gap: 5px; flex: none; font-size: 12px; padding: 5px 12px; }
.plat-row { display: flex; justify-content: space-between; font-size: 14.5px; font-weight: 600; padding: 4px 0; }
.plat-row .h { font-family: 'Orbitron', sans-serif; font-size: 13px; }

/* Navigation par onglets du panneau détail — une barre sous le titre et les
   chiffres, collée en haut pendant le défilement (retour de Tim, 2026-09-28 :
   « je ne suis pas convaincu sur la droite », mockup
   docs/mockups/mockup-onglets-haut-final.html, variante B). Remplace la
   colonne de boutons flottants à droite du panneau (2026-08-18) et son repli
   en rangée sous 1500 px. Le mini-titre (jaquette + nom) n'apparaît qu'une
   fois le titre sorti de l'écran (.stuck, posé par updateDetailTabsStuck()).
   Les icônes masquer/supprimer y vivent, à droite. #detail-tabs (id
   conservé, ciblé par app.js et par le tour de la fiche). Même style
   d'onglet que le menu Info (.info-bar). */
.tabs-bar, .info-bar {
  position: sticky; z-index: 5; display: flex; align-items: center; gap: 16px;
  background: rgba(24, 30, 50, .92); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
/* top négatif = le padding haut du conteneur qui défile : le collage se
   mesure depuis l'intérieur du padding, sans ça la barre flotte à 40 px du
   bord (constaté dans le mockup). */
.tabs-bar { top: -40px; margin: 0 -48px 18px -32px; padding: 0 48px 0 32px; transition: box-shadow .2s; }
.tabs-bar.stuck { box-shadow: 0 12px 26px rgba(0, 0, 0, .35); }
.tb-tabs { display: flex; gap: 26px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tb-tabs::-webkit-scrollbar { display: none; }

/* Onglet : plus lisible que les anciennes pilules (retour de Tim, « un poil
   plus visible ») — texte à lire (--text-2) plutôt que --muted, 13 px, et un
   soulignement dégradé épais avec un halo pour l'onglet actif. */
.detail-tab-btn, .info-tab-btn {
  position: relative; flex: none; display: inline-flex; align-items: center; gap: 7px;
  background: none; border: none; border-radius: 0; box-shadow: none; cursor: pointer;
  padding: 16px 2px 13px; color: var(--text-2);
  font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .9px; text-transform: uppercase; white-space: nowrap;
  transition: color .15s;
}
.detail-tab-btn::after, .info-tab-btn::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0;
  background: transparent; transition: background .15s;
}
.detail-tab-btn:hover, .info-tab-btn:hover { color: var(--text); }
.detail-tab-btn:hover::after, .info-tab-btn:hover::after { background: rgba(124, 92, 255, .45); }
.detail-tab-btn.active, .info-tab-btn.active { color: #fff; text-shadow: 0 0 14px rgba(124, 92, 255, .7); }
.detail-tab-btn.active::after, .info-tab-btn.active::after {
  background: linear-gradient(90deg, var(--accent), var(--accent-2)); box-shadow: 0 0 12px rgba(0, 229, 195, .45);
}
.detail-tab-btn:focus-visible, .info-tab-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.tab-panel.hidden { display: none; }

.tb-mini { display: none; align-items: center; gap: 8px; flex: none; font: 700 12.5px 'Orbitron', sans-serif; color: var(--text); white-space: nowrap; max-width: 220px; }
.tb-mini span { overflow: hidden; text-overflow: ellipsis; }
.tb-mini img { width: 22px; aspect-ratio: 3/4; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); flex: none; }
.tabs-bar.stuck .tb-mini { display: flex; }
.tb-icons { display: flex; gap: 8px; flex: none; }
.tb-icons .detail-icon-btn { position: static; }
/* La barre sépare déjà l'en-tête du contenu : le trait du haut de la première
   section de chaque onglet ferait un double trait juste dessous. */
.tabs-bar ~ .tab-panel > .detail-section:first-child { border-top: none; padding-top: 0; }

/* Mise en page empilée (< 860 px) : c'est tout le panneau qui défile. La barre
   se colle en haut de l'écran (top = -padding haut de .detail) et laisse 72 px
   libres à droite pour le ✕ de .detail-close, fixé à cet endroit. Doit rester
   APRÈS les règles de base ci-dessus : placées avant, elles les écrasaient
   (constaté à 375 px, barre à -28 px et icônes sous le ✕). */
@media (max-width: 860px) {
  .tabs-bar { top: -20px; margin: 0 -24px 14px; padding: 0 72px 0 24px; }
  .tb-tabs { gap: 18px; }
  .tb-mini span { display: none; }
}

/* ── Téléphone (< 600 px, 2026-09-30, mockup mockup-onglets-fiche-mobile.html,
   variante A). Mesuré à 375 px : 167 px de zone pour 576 px d'onglets, on
   voyait deux onglets et demi sans rien qui dise qu'il en restait trois.
   Icônes montées dans l'en-tête, libellés courts, fondu à droite tant qu'il
   reste des onglets, et un ✕ dans la barre collée : celui de la fiche défile
   avec elle (backdrop-filter de .detail). Règles de base d'abord, @media
   ensuite — dans l'autre ordre, elles l'écrasent. ── */
.detail-tab-btn .tab-short { display: none; }
.dh-actions { display: none; }
.tb-close {
  display: none; flex: none; align-items: center; justify-content: center;
  width: 32px; height: 32px; margin-left: 8px; cursor: pointer;
  background: none; border: 1px solid var(--line); border-radius: 8px; color: var(--muted); font-size: 15px;
}
.tb-close:hover { color: var(--text); border-color: var(--accent); }
@media (max-width: 600px) {
  .detail-header { position: relative; padding-right: 84px; }
  /* Platiné ou non, le titre laisse le coin aux icônes (la règle des jeux
     platinés, sous 860 px, le remettait à zéro). */
  .detail-header.has-platinum-badge { padding-right: 84px; }
  .dh-actions { position: absolute; top: 2px; right: 0; display: flex; gap: 8px; }
  .dh-actions .detail-icon-btn { position: static; }
  .tabs-bar { align-items: center; padding-right: 24px; }
  .tabs-bar.stuck { padding-right: 16px; }
  .tabs-bar .tb-icons { display: none; }
  .tabs-bar.stuck .tb-close { display: flex; }
  .tabs-bar.stuck .tb-mini { display: none; }
  .detail-tab-btn .tab-long { display: none; }
  .detail-tab-btn .tab-short { display: inline; }
  .tb-tabs {
    gap: 20px; padding-right: 30px;
    -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent); mask-image: linear-gradient(90deg, #000 82%, transparent);
  }
  .tb-tabs.at-end { -webkit-mask-image: none; mask-image: none; }
}

/* Journal de session : une ligne par jour, sous-liste indentée pour le
   détail par version quand plusieurs plateformes ont contribué ce jour-là. */
.session-log-entry { border-bottom: 1px dashed var(--line); padding: 6px 0; }
.session-log-entry:last-child { border-bottom: none; }
.session-log-breakdown { margin: 2px 0 2px 14px; }
.session-log-sub {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  color: var(--muted); padding: 2px 0;
}
.session-log-sub > span:first-child { flex: 1; }
.session-log-sub .h { font-family: 'Orbitron', sans-serif; font-size: 11.5px; }
/* Suppression d'une session chrono (retour de Tim, 2026-08-20) — même
   recette que .tag-remove (icône nue, opacité au repos, pleine au survol),
   visible uniquement sur les lignes manual_sessions (voir renderSessionLog). */
.session-delete-btn {
  flex: none; background: none; border: none; color: inherit; cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0; opacity: .5;
}
.session-delete-btn:hover { opacity: 1; color: var(--danger); }

.ttb-row { display: flex; justify-content: space-between; font-size: 13.5px; margin-bottom: 3px; }
.ttb-row-bar { height: 6px; border-radius: 3px; background: var(--bg-2); border: 1px solid var(--line); margin-bottom: 9px; position: relative; overflow: hidden; }
.ttb-row-fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; }

.trend-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.trend-head h3 { margin: 0; }
.trend-gran { gap: 4px; }
.trend-gran .chip { padding: 3px 9px; font-size: 10.5px; }
.trend-wrap { position: relative; }
#trend-canvas { width: 100%; height: 100px; display: block; cursor: crosshair; }
/* Graphique "Temps de jeu dans le temps" (Leaderboards, tâche demandée par
   Tim 2026-08-08) — même pattern que #trend-canvas, id différent (page à
   part) donc redéclaré. Plus haut que la version par jeu (140px vs 100px) :
   pleine largeur de page plutôt que dans le panneau détail plus étroit. */
#lb-trend-canvas { width: 100%; height: 140px; display: block; cursor: crosshair; }
.trend-tooltip {
  position: absolute; transform: translate(-50%, -100%);
  background: var(--panel-2); border: 1px solid var(--accent-2); border-radius: 6px;
  padding: 4px 9px; font: 700 11.5px 'Orbitron', sans-serif; color: var(--text);
  white-space: nowrap; pointer-events: none; z-index: 5;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
}
.trend-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 20px 0; }

.btn {
  width: 100%; margin-top: 6px;
  background: linear-gradient(120deg, rgba(255, 185, 56, .18), rgba(255, 185, 56, .06));
  border: 1px solid rgba(255, 185, 56, .5); border-radius: 10px;
  color: var(--gold); font: 700 14px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase;
  padding: 10px; cursor: pointer; transition: all .2s;
}
.btn:hover { box-shadow: 0 0 18px rgba(255, 185, 56, .3); }
.btn.secondary { border-color: var(--line); color: var(--muted); background: none; }

/* ─── Divers ─── */
.hidden { display: none !important; }
.empty { color: var(--muted); text-align: center; padding: 60px 0; font-size: 17px; }

/* Scène désert — bibliothèque réellement vide (state.games.length === 0),
   distincte du texte plat de .empty ci-dessus qui reste pour le cas "filtre
   trop restrictif" (des jeux existent mais aucun ne passe les filtres).
   Validée par mockup (docs/mockups/mockup-empty-desert.html). Pas de
   bordure ni de border-radius : var(--bg) est déjà le fond de la page, donc
   la scène se fond directement dans l'espace vide plutôt que de ressembler
   à une carte encadrée en plus. */
.desert-empty {
  position: relative; height: 320px; overflow: hidden;
  background:
    radial-gradient(2px 2px at 10% 20%, rgba(232,236,255,.5), transparent),
    radial-gradient(1.5px 1.5px at 25% 35%, rgba(232,236,255,.4), transparent),
    radial-gradient(2px 2px at 60% 15%, rgba(232,236,255,.45), transparent),
    radial-gradient(1.5px 1.5px at 80% 25%, rgba(232,236,255,.35), transparent),
    radial-gradient(1.5px 1.5px at 92% 40%, rgba(232,236,255,.4), transparent),
    radial-gradient(1200px 500px at 80% -10%, rgba(124, 92, 255, .16), transparent 60%),
    var(--bg);
}
.desert-moon {
  position: absolute; top: 26px; right: 60px; width: 46px; height: 46px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #eafffb, var(--accent-2));
  box-shadow: 0 0 30px rgba(0, 229, 195, .5);
}
.desert-dune {
  position: absolute; left: 0; right: 0; bottom: 78px; height: 40px;
  background: var(--bg-2);
  clip-path: polygon(0% 100%, 0% 60%, 15% 40%, 35% 55%, 55% 30%, 75% 50%, 100% 35%, 100% 100%);
  opacity: .6;
}
.desert-cactus { position: absolute; bottom: 88px; color: var(--accent-2); opacity: .55; }
.desert-cactus svg { display: block; filter: drop-shadow(0 0 6px rgba(0, 229, 195, .25)); }
.desert-tumbleweed {
  position: absolute; bottom: 86px; left: -60px; width: 34px; height: 34px;
  animation: tumbleweed-roll 11s linear infinite;
}
/* Rotation liée au déplacement horizontal (roule "physiquement"). left plutôt
   que translateX : animé en % de la largeur réelle du conteneur au lieu
   d'un vw qui déborderait la largeur de la colonne principale (sidebar +
   marges). Le rebond (haut/bas) est porté par l'enfant .desert-tumbleweed-hop
   plus bas : deux animations ne peuvent pas partager transform sur le même
   élément sans que l'une écrase l'autre. */
@keyframes tumbleweed-roll {
  0%    { left: -60px; transform: rotate(0deg); }
  48%   { left: 100%;  transform: rotate(900deg); }
  50%   { left: 100%;  transform: rotate(900deg); opacity: 0; }
  50.1% { left: -60px; transform: rotate(0deg); opacity: 0; }
  52%   { opacity: .9; }
  100%  { left: -60px; transform: rotate(0deg); opacity: .9; }
}
/* Rebond : hop-hop-hop avec une accélération "gravité" (chute rapide, montée
   qui ralentit) via des timing-functions différentes par moitié de
   keyframe, plutôt qu'un simple ease-in-out linéaire. */
.desert-tumbleweed-hop {
  width: 34px; height: 34px; color: var(--gold); opacity: .9;
  animation: tumbleweed-hop .55s infinite;
}
.desert-tumbleweed-hop svg { display: block; filter: drop-shadow(0 0 5px rgba(255, 185, 56, .4)); }
@keyframes tumbleweed-hop {
  0%   { transform: translateY(0); animation-timing-function: cubic-bezier(.33, 0, .67, 0); }
  50%  { transform: translateY(-16px); animation-timing-function: cubic-bezier(.33, 1, .67, 1); }
  100% { transform: translateY(0); }
}
.desert-text { position: absolute; left: 0; right: 0; bottom: 56px; text-align: center; }
.desert-text .t1 { font: 700 15px 'Orbitron', sans-serif; color: var(--text); margin-bottom: 4px; }
.desert-text .t2 { color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif; }
/* Bouton d'action sous le texte existant (mockup validé
   docs/mockups/mockup-desert-cta.html, retour de Tim) — la scène désert
   décrivait déjà quoi faire mais n'offrait aucune action cliquable. */
.desert-cta { position: absolute; left: 0; right: 0; bottom: -4px; text-align: center; }
.desert-cta button {
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border: none;
  border-radius: 999px; font: 700 12.5px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: uppercase;
  padding: 9px 20px; cursor: pointer; transition: filter .15s;
}
.desert-cta button:hover { filter: brightness(1.08); }
/* Écran de chargement "pluie de points" (retour de Tim, réf. mobbin →
   editions.shopify.com/editions/spring2026, mockup docs/mockups/
   mockup-loading-screen.html) — remplace l'ancien spinner simple pour
   #loading. .loading-pulse/@keyframes spin restent utilisés ailleurs
   (#sync-spinner), inchangés ci-dessous. */
.loading {
  position: fixed; inset: 0; z-index: 100; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px;
  background: var(--bg);
  transition: opacity .8s ease-out;
  will-change: opacity;
}
.loading.hidden { display: none; }
.loading.is-leaving { opacity: 0; pointer-events: none; }
/* Rechargement dans la journée (retours de Tim, 2026-10-03) : fond flou — la
   page se devine derrière —, petit sablier qui fait un tour complet (deux
   demi-tours, avec une courte pause entre les deux), ni pluie ni fondu. Voir
   LOADING_QUICK dans app.js. L'écran bloque toujours les clics le temps du
   chargement (environ une seconde). */
.loading.quick { transition: none; background: rgba(11, 13, 22, .35); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.loading.quick .loading-rain { display: none; }
.loading.quick .loading-icon { width: 56px; height: 56px; box-shadow: 0 0 30px rgba(124, 92, 255, .3); }
.loading.quick .loading-icon .sable-haut, .loading.quick .loading-icon .sable-bas { animation: none; }
.loading.quick .loading-icon .sable-haut { transform: translateY(98px); }
.loading.quick .loading-icon .sable-bas { transform: translateY(0); }
.loading.quick .loading-icon .verre { animation: tyg-verre-tour 1.2s cubic-bezier(.6, 0, .35, 1) .1s both; }
@keyframes tyg-verre-tour {
  0%       { transform: rotate(0deg); }
  42%, 58% { transform: rotate(180deg); }
  100%     { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .loading.quick .loading-icon .verre { animation: none; }
}

.loading-rain { position: absolute; inset: 0; width: 100%; height: 100%; }
.loading-rain-dot {
  animation: loading-rain-rise var(--duration, 4s) linear var(--delay, 0s) infinite;
  opacity: var(--alpha, .8);
  transform-origin: center;
  transition: opacity .5s ease-out, scale .5s ease-out;
  /* Repéré par Tim : petit saut juste avant que la dissolution ne démarre.
     140 points qui basculent leur transition d'un coup au moment où
     .is-leaving est posée forcent le navigateur à promouvoir 140 calques de
     composition en même temps, en plein milieu du déclenchement — will-change
     le fait par anticipation pendant que le point respire déjà (animation
     infinie en cours), avant que la dissolution n'en ait besoin. */
  will-change: opacity, scale;
}
@keyframes loading-rain-rise {
  0%   { translate: calc(var(--drift) * -0.5px) calc(var(--travel) * 0.5px); }
  100% { translate: calc(var(--drift) * 0.5px) calc(var(--travel) * -0.5px); }
}
/* Dissolution en particules au moment de révéler le dashboard (retour de
   Tim, réf. Shopify Editions) — les points continuent leur trajectoire de
   pluie mais grossissent et s'estompent, comme s'ils se dispersaient.
   Classe posée directement par JS (hideLoadingScreen(), app.js), PAS via
   .loading.is-leaving .loading-rain-dot : mesuré en réel (Web Animations
   API, Animation.currentTime) qu'un sélecteur composé qui bascule les 140
   points d'un coup force un décrochage du fil principal d'environ 200ms au
   moment précis du déclenchement — visible comme "un petit saut" (retour
   de Tim) juste avant la dissolution. hideLoadingScreen() étale la pose de
   cette classe sur quelques frames plutôt qu'un seul recalcul de style
   synchrone pour les 140 — vérifié : plus de décrochage mesuré. */
.loading-rain-dot.is-dissolving { opacity: 0; scale: 2.4; }
@media (prefers-reduced-motion: reduce) {
  .loading-rain-dot { animation-duration: calc(var(--duration, 4s) * 4); }
}

/* Repéré par Tim : "comme s'il déplaçait le GameTracker" — pas un vrai saut
   de position, mais un fondu enchaîné involontaire entre CE logo (centré) et
   celui, statique, de la topbar du dashboard en dessous (#topbar-logo, en
   haut à gauche). .loading-mark n'avait pas sa propre transition : il ne
   s'effaçait qu'au même rythme que le fond (.8s), donc restait partiellement
   visible pendant l'essentiel du fondu du fond — assez longtemps pour se
   superposer au logo de la topbar qui apparaît en transparence, l'œil lit ça
   comme un seul logo qui "saute" du centre vers le coin. Fondu propre et
   rapide (.2s), terminé bien avant que le fond ne devienne assez transparent
   pour révéler la topbar. */
.loading-mark { position: relative; display: flex; flex-direction: column; align-items: center; gap: 16px; transition: opacity .2s ease-out; }
.loading.is-leaving .loading-mark { opacity: 0; }
.loading-logo {
  font: 900 22px 'Orbitron', sans-serif; letter-spacing: 3px; color: var(--text);
  text-shadow: 0 0 24px rgba(124, 92, 255, .4);
}
.loading-label {
  font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 5px; text-transform: uppercase; color: var(--muted);
}

.loading-pulse {
  width: 46px; height: 46px; border-radius: 50%;
  border: 3px solid rgba(124, 92, 255, .25); border-top-color: var(--accent);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ─── Session en cours, plein écran (mockup mockup-session-fullscreen.html,
   retour de Tim) — même moule que .finish-overlay ("Terminé") : fond
   flouté plein écran, jaquette flottante à gauche, contenu à droite. Glow
   accent/accent-2 ("en direct") plutôt que doré (réservé à "Terminé").
   Réutilise @keyframes fade/finish-cover-in/finish-stat-in (déjà définis
   plus haut pour .detail/.finish-overlay) et @keyframes pulse (déjà
   utilisé par .timer-widget-dot ci-dessous) plutôt que d'en dupliquer. */
.session-overlay {
  position: fixed; inset: 0; z-index: 150;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .5); backdrop-filter: blur(20px);
  animation: fade .3s both;
}
.session-content { display: flex; gap: 44px; align-items: center; max-width: 900px; width: 92vw; padding: 20px; }
.session-cover {
  width: 260px; max-width: 40vw; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 16px; flex: none;
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .6), 0 0 50px rgba(124, 92, 255, .3);
  animation: finish-cover-in .6s cubic-bezier(.2, .8, .3, 1) both;
}
.session-info { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.session-live {
  display: flex; align-items: center; gap: 8px;
  font: 900 13px 'Orbitron', sans-serif; letter-spacing: 4px; color: var(--accent-2);
  animation: fade .4s both;
}
.session-live .dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent-2);
  animation: pulse 1.6s ease-in-out infinite;
}
.session-title { font: 700 28px 'Orbitron', sans-serif; margin: 4px 0 2px; animation: fade .4s .1s both; }
.session-sub { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; margin-bottom: 18px; animation: fade .4s .1s both; }
.session-clock {
  font: 800 clamp(56px, 8vw, 100px) 'Orbitron', sans-serif; letter-spacing: 2px;
  color: var(--text); font-variant-numeric: tabular-nums; line-height: 1;
  text-shadow: 0 0 40px rgba(124, 92, 255, .45);
  margin-bottom: 26px; opacity: 0; animation: finish-stat-in .5s ease-out .25s both;
}
.session-actions { display: flex; gap: 10px; opacity: 0; animation: fade .4s .5s both; }
.session-stop-btn {
  background: linear-gradient(120deg, var(--danger), #ff8a5c); color: #1a0b0b; border: none;
  border-radius: 10px; font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: uppercase;
  padding: 12px 22px; cursor: pointer; transition: filter .15s;
}
.session-stop-btn:hover { filter: brightness(1.08); }
.session-minimize-btn {
  background: none; border: 1px solid var(--line); border-radius: 10px;
  color: var(--muted); font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .3px;
  padding: 12px 18px; cursor: pointer; transition: all .15s;
}
.session-minimize-btn:hover { color: var(--text); border-color: var(--accent); }
@media (max-width: 700px) {
  .session-content { flex-direction: column; text-align: center; }
  .session-cover { max-width: 60vw; }
  .session-live { justify-content: center; }
  .session-actions { justify-content: center; }
}

/* ─── Chronomètre manuel : widget flottant + affichage en direct ─────── */
.timer-widget {
  position: fixed; bottom: 20px; right: 20px; z-index: 90;
  display: flex; align-items: center; gap: 10px;
  background: var(--panel-2); border: 1px solid var(--accent-2); border-radius: 12px;
  padding: 10px 14px; box-shadow: 0 14px 34px rgba(0, 0, 0, .5);
  font: 600 13px 'Rajdhani', sans-serif; color: var(--text);
  animation: fade .25s both; cursor: pointer;
}
.timer-widget-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent-2);
  animation: pulse 1.6s ease-in-out infinite;
}
.timer-widget-elapsed { font-family: 'Orbitron', sans-serif; font-weight: 700; color: var(--accent-2); }
.timer-widget .chip { padding: 4px 10px; font-size: 11.5px; }

/* ─── Sélection multiple + actions groupées (tâche #37) ──────────────── */
.card-select {
  position: absolute; top: 8px; left: 8px; z-index: 5;
  width: 24px; height: 24px; border-radius: 6px;
  background: rgba(11, 13, 22, .75); border: 1.5px solid rgba(255, 255, 255, .55);
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(4px); transition: background .15s, border-color .15s;
}
.card-select svg { opacity: 0; color: #0b0d16; transition: opacity .12s; }
.card.selected .card-select {
  background: var(--accent); border-color: var(--accent);
  box-shadow: 0 0 12px rgba(124, 92, 255, .5);
}
.card.selected .card-select svg { opacity: 1; }
.card.selected { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Les badges live/done partagent les coins de la jaquette avec la case à
   cocher — masqués en mode sélection pour éviter le chevauchement. */
.grid.selecting .badge-live, .grid.selecting .badge-done { display: none; }

.bulk-bar {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 90;
  display: flex; align-items: center; gap: 10px;
  background: var(--panel-2); border: 1px solid var(--accent); border-radius: 12px;
  padding: 10px 14px; box-shadow: 0 14px 34px rgba(0, 0, 0, .5);
  font: 600 13px 'Rajdhani', sans-serif; color: var(--text);
  animation: fade .2s both;
}
.bulk-bar .chip.secondary { border-color: rgba(255, 84, 112, .4); color: var(--danger); }
.bulk-bar .chip { display: inline-flex; align-items: center; gap: 6px; }

/* Résumé récapitulatif avant action groupée — même langage visuel que
   .modal-merge-* (jaquette + nom), en liste plutôt qu'en 2 colonnes. */
.modal-bulk-list { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; margin-bottom: 4px; }
.modal-bulk-item { display: flex; align-items: center; gap: 10px; font: 500 13px 'Rajdhani', sans-serif; color: var(--text); }
.modal-bulk-cover { width: 32px; aspect-ratio: 3/4; object-fit: cover; border-radius: 4px; flex: none; }
.modal-bulk-cover.cover-fallback { display: flex; align-items: center; justify-content: center; font-size: 10px; color: var(--muted); background: var(--bg-2); }
/* ─── Onglet Ajustements retravaillé (retour de Tim, 2026-08-05) ─────── */

/* Chrono : carte à part, globale au panneau (voir openDetail — plus dans
   l'onglet Ajustements), plus visible/stylée qu'un simple edit-row. */
.chrono-card {
  position: relative; overflow: hidden;
  background: radial-gradient(140% 160% at 100% 0%, rgba(0, 229, 195, .14), transparent 60%), var(--bg-2);
  border: 1px solid rgba(0, 229, 195, .35); border-radius: 16px;
  padding: 16px 20px; margin: 16px 0 4px;
}
.chrono-card::before {
  content: ""; position: absolute; inset: 0; border-radius: 16px; padding: 1px;
  background: linear-gradient(120deg, var(--accent-2), transparent 40%, transparent 60%, var(--accent));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; opacity: .5; pointer-events: none;
}
.chrono-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.chrono-eyebrow {
  font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1.8px;
  color: var(--accent-2); display: flex; align-items: center; gap: 7px;
}
.chrono-eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2);
  box-shadow: 0 0 8px var(--accent-2); animation: chrono-pulse 1.8s ease-in-out infinite;
}
@keyframes chrono-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.chrono-target { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }
.chrono-target b { color: var(--text); font-weight: 700; }
.chrono-body { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 10px; flex-wrap: wrap; }
.chrono-elapsed {
  font-family: 'Orbitron', sans-serif; font-size: 28px; font-weight: 700;
  color: var(--text); letter-spacing: 1px; font-variant-numeric: tabular-nums;
}
.chrono-elapsed .idle { color: var(--muted); font: 600 14px 'Rajdhani', sans-serif; letter-spacing: .3px; }
.chrono-actions { display: flex; align-items: center; gap: 8px; }
.chrono-btn {
  border: none; border-radius: 12px; padding: 11px 18px; cursor: pointer;
  font: 700 13px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .8px;
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  transition: transform .15s, box-shadow .15s;
}
.chrono-btn:hover { transform: translateY(-1px); }
.chrono-btn.start {
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16;
  box-shadow: 0 8px 22px rgba(124, 92, 255, .3);
}
.chrono-btn.stop {
  background: rgba(255, 84, 112, .14); color: var(--danger); border: 1px solid rgba(255, 84, 112, .4);
}
.chrono-btn:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }
.chip:disabled { opacity: .5; cursor: not-allowed; }

/* Temps réel total : nom de version à gauche (grand), champs h/min à droite
   — profite de la largeur plutôt qu'un label empilé au-dessus d'un input. */
.version-block { padding: 14px 0; border-bottom: 1px solid var(--line); }
.version-block:last-child { border-bottom: none; padding-bottom: 4px; }
.version-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.version-id { display: flex; align-items: center; gap: 10px; min-width: 0; }
.version-dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.version-name { font: 700 15.5px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.25; }
.version-name .platform { color: var(--muted); font-weight: 600; }
.version-fields { display: flex; align-items: center; gap: 6px; flex: none; }
.version-fields input {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); font: 600 14px 'Rajdhani', sans-serif; text-align: center;
  padding: 7px 4px; width: 52px;
}
.version-fields input:focus { border-color: var(--accent); outline: none; }
.version-fields .unit { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; margin-right: 2px; }
.version-fields .chip { padding: 5px 12px; white-space: nowrap; }
.version-extra { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.version-extra input {
  flex: 1; background: transparent; border: 1px dashed var(--line); border-radius: 8px;
  color: var(--text); font: 500 13px 'Rajdhani', sans-serif; padding: 6px 10px;
}
.version-extra input::placeholder { color: var(--muted); }

/* Dates : libellé à gauche, champ + bouton à droite (même logique que les
   lignes de version ci-dessus) plutôt qu'empilés verticalement. */
.date-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 9px 0; flex-wrap: wrap; }
.date-row:not(:last-child) { border-bottom: 1px solid var(--line); }
.date-row .date-label { font: 600 14px 'Rajdhani', sans-serif; color: var(--text); }

/* Texte d'indication/explication : plus lisible qu'un simple texte gris
   discret — icône + léger fond pour le distinguer du contenu principal
   sans l'alourdir (retour de Tim, 2026-08-05). */
.version-hint, .edit-hint {
  position: relative;
  color: #b7bfe6; font: 500 12.5px 'Rajdhani', sans-serif; line-height: 1.45;
  margin-top: 10px; padding: 7px 10px 7px 29px;
  background: rgba(124, 92, 255, .08); border-left: 2px solid rgba(124, 92, 255, .45);
  border-radius: 0 7px 7px 0;
}
/* Icône en absolu plutôt qu'en flex (2026-09-13) : en `display:flex`, tout
   enfant inline direct (<strong>, <code>, <b>) devenait un item flex à part
   entière — "tape <strong>SUPPRIMER</strong>" s'affichait en trois blocs
   séparés par le gap au lieu d'une phrase (modale de suppression de compte,
   repéré via le mockup Amis). Même géométrie qu'avant, mesurée au pixel :
   texte à 31px du bord extérieur (2 de bordure + 29 de padding = 10 + 14
   d'icône + 7 d'ancien gap), icône à 10px/7px du bord intérieur. */
.version-hint::before, .edit-hint::before {
  content: ""; width: 14px; height: 14px; background: var(--accent-2);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle fill=%22currentColor%22 fill-opacity=%22.18%22 cx=%2212%22 cy=%2212%22 r=%228.5%22/%3E%3Cpath d=%22M12 11v5.2M12 7.8v.01%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle fill=%22currentColor%22 fill-opacity=%22.18%22 cx=%2212%22 cy=%2212%22 r=%228.5%22/%3E%3Cpath d=%22M12 11v5.2M12 7.8v.01%22/%3E%3C/svg%3E") center / contain no-repeat;
  position: absolute; left: 10px; top: 8px;
}

/* ─── Célébration "Terminé" (fond flouté, jaquette + stats en cascade) ─── */
.finish-overlay {
  position: fixed; inset: 0; z-index: 150;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .5);
  backdrop-filter: blur(20px);
  animation: fade .3s both;
}
.finish-content {
  display: flex; gap: 40px; align-items: center;
  max-width: 860px; width: 92vw; padding: 20px;
}
.finish-cover {
  width: 260px; max-width: 40vw; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 16px; flex: none;
  border: 1px solid var(--line);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .6), 0 0 50px rgba(255, 185, 56, .25);
  animation: finish-cover-in .6s cubic-bezier(.2, .8, .3, 1) both;
}
@keyframes finish-cover-in {
  from { opacity: 0; transform: translateX(-30px) scale(.92); }
  to   { opacity: 1; transform: none; }
}
.finish-info { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.finish-label {
  font: 900 13px 'Orbitron', sans-serif; letter-spacing: 4px; color: var(--gold);
  animation: fade .4s both;
}
.finish-title {
  font: 700 30px 'Orbitron', sans-serif; margin-bottom: 8px;
  animation: fade .4s .1s both;
}
.finish-stats { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.finish-stat {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  border-bottom: 1px dashed var(--line); padding-bottom: 8px;
  opacity: 0; animation: finish-stat-in .5s ease-out calc(.25s + var(--i) * .18s) both;
}
@keyframes finish-stat-in {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}
.finish-stat-label { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1px; white-space: nowrap; }
.finish-stat-value { font: 700 16px 'Orbitron', sans-serif; color: var(--text); text-align: right; }
.finish-overlay #finish-close { align-self: flex-start; animation: fade .4s .9s both; }
/* « Le ranger dans une liste ? » (mockup mockup-fin-liste-tags.html, A sans tags, 2026-10-05) */
.finish-lists { border-top: 1px solid var(--line); padding-top: 14px; margin: 0 0 16px; display: flex; flex-direction: column; gap: 10px; animation: fade .4s .8s both; }
.finish-lists.hidden { display: none; }
.finish-lists-q { font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); text-transform: uppercase; letter-spacing: .5px; }
.finish-lists-row { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.finish-lists-row .chip { font-size: 13px; padding: 5px 11px; }
.finish-lists-row .chip .ico { width: 1em; height: 1em; vertical-align: -2px; }
.finish-lists-row .chip .now { font: 600 11px 'Rajdhani', sans-serif; color: var(--muted); margin-left: 4px; text-transform: none; }
.finish-lists-ok { color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; }

@media (max-width: 700px) {
  .finish-content { flex-direction: column; text-align: center; }
  .finish-cover { max-width: 60vw; }
  .finish-stat { flex-direction: column; align-items: center; gap: 2px; }
  .finish-stat-value { text-align: center; }
  .finish-lists-row { justify-content: center; }
}

/* ─── Célébration plein écran (nouveau platine) ──────────────────────── */
.celebration-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 40%, rgba(124, 92, 255, .28), rgba(5, 6, 12, .94) 70%);
  backdrop-filter: blur(4px);
  animation: fade .3s both;
}
.confetti-field { position: absolute; inset: 0; overflow: hidden; z-index: 1; pointer-events: none; }
.confetti-piece {
  position: absolute; top: -5%; width: 8px; height: 14px; opacity: .95; border-radius: 2px;
  animation-name: confetti-fall; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes confetti-fall {
  to { transform: translate(var(--drift, 0), 115vh) rotate(720deg); opacity: .15; }
}
.celebration-content {
  position: relative; z-index: 2; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.celebration-trophy {
  font-size: 130px; line-height: 1;
  filter: grayscale(1) brightness(1.8) drop-shadow(0 0 46px rgba(255, 255, 255, .85));
  animation: celebration-pop 1s cubic-bezier(.2, 1.5, .4, 1) both, celebration-idle 3s ease-in-out .9s infinite;
}
@keyframes celebration-pop {
  0%   { transform: scale(0) rotateY(0deg); opacity: 0; }
  70%  { transform: scale(1.15) rotateY(720deg); opacity: 1; }
  100% { transform: scale(1) rotateY(720deg); opacity: 1; }
}
@keyframes celebration-idle {
  0%, 100% { transform: scale(1) rotateY(720deg) rotate(-3deg); }
  50%      { transform: scale(1) rotateY(720deg) rotate(3deg); }
}
.celebration-title {
  font: 900 54px 'Orbitron', sans-serif; letter-spacing: 7px;
  background: linear-gradient(120deg, #fff, var(--accent-2), var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 30px rgba(255, 255, 255, .25));
  animation: fade .5s .25s both;
}
.celebration-game {
  font: 700 24px 'Rajdhani', sans-serif; color: var(--text);
  animation: fade .5s .45s both;
}
/* Le platine propose de ranger le jeu (2026-09-30, mockup mockup-jalons-final.html). */
.celebration-ask { color: var(--text-2); font: 500 16px 'Rajdhani', sans-serif; text-align: center; line-height: 1.5; animation: fade .5s .55s both; }
.celebration-ask b { color: var(--text); }
.celebration-actions { display: flex; gap: 10px; animation: fade .5s .65s both; }
.celebration-actions .chip { padding: 8px 22px; font-size: 13px; }
.celebration-overlay #celebration-close {
  margin-top: 8px; padding: 8px 22px; font-size: 13px;
  animation: fade .5s .65s both;
}

/* ─── Célébration "jeu ajouté" (retour de Tim, 2026-09-10, mockup
   mockup-game-added-celebration.html) — même famille que .finish-overlay/
   .celebration-overlay (fond flouté plein écran, fermeture par ✕ ou clic
   dehors), mais plus compacte : geste fréquent (chaque ajout de jeu), pas
   un événement rare comme le platine. ──────────────────────────────── */
.added-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 38%, rgba(0, 229, 195, .18), rgba(5, 6, 12, .88) 72%);
  backdrop-filter: blur(6px);
  animation: fade .25s both;
}
.added-overlay.hidden { display: none; }

/* Feux d'artifice : rafales de particules qui EXPLOSENT depuis un point puis
   retombent en s'estompant — délibérément différent de .confetti-piece (qui
   TOMBE du haut de l'écran) pour un effet "petit feu d'artifice" plus vif et
   plus court, cohérent avec la fréquence du geste. */
.firework-field { position: absolute; inset: 0; overflow: hidden; z-index: 1; pointer-events: none; }
.spark {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  animation-name: spark-burst; animation-timing-function: cubic-bezier(.15, .7, .3, 1); animation-fill-mode: forwards;
}
@keyframes spark-burst {
  0%   { transform: translate(0, 0) scale(1); opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; }
}

.added-content {
  position: relative; z-index: 2;
  display: flex; gap: 32px; align-items: center;
  background: var(--panel); border: 1px solid var(--line); border-radius: 20px;
  padding: 32px 36px; max-width: 680px; width: 92vw;
  box-shadow: 0 40px 90px rgba(0, 0, 0, .55), 0 0 60px rgba(0, 229, 195, .12);
  animation: added-pop .45s cubic-bezier(.2, 1.1, .3, 1) both;
}
@keyframes added-pop {
  from { opacity: 0; transform: scale(.9) translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.added-cover {
  width: 150px; aspect-ratio: 3/4; object-fit: cover; border-radius: 12px; flex: none;
  border: 1px solid var(--line); box-shadow: 0 20px 40px rgba(0, 0, 0, .5);
}
.added-info { flex: 1; min-width: 0; }
.added-label {
  font: 900 12px 'Orbitron', sans-serif; letter-spacing: 3px; color: var(--accent-2);
  margin-bottom: 6px;
}
.added-title { font: 700 24px 'Orbitron', sans-serif; margin: 0 0 4px; line-height: 1.2; }
.added-meta { color: var(--muted); font-size: 13px; margin-bottom: 18px; }
.added-list-prompt {
  font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); text-transform: uppercase;
  letter-spacing: .5px; margin-bottom: 10px;
}
.added-actions { margin-top: 20px; display: flex; justify-content: flex-end; }
.added-skip {
  background: none; border: none; color: var(--muted); font: 600 13px 'Rajdhani', sans-serif;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.added-skip:hover { color: var(--text-2); }
.added-close {
  position: absolute; top: 14px; right: 16px; z-index: 3;
  background: none; border: none; color: var(--muted); font-size: 20px; cursor: pointer; line-height: 1;
}
.added-close:hover { color: var(--text); }

@media (max-width: 640px) {
  .added-content { flex-direction: column; text-align: center; padding: 28px 24px; }
  .added-cover { width: 130px; }
  .added-list-prompt ~ .chip-row { justify-content: center; }
  .added-actions { justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════
   Page d'intro (tâche #48) — écran par défaut pour un visiteur sans
   session, avant le formulaire de connexion (#login-overlay ci-dessous).
   Portée depuis docs/mockups/mockup-landing.html — relire ce fichier
   avant toute modification notable plutôt que de retravailler de mémoire.
   ═══════════════════════════════════════════════════════════════════ */
.landing-overlay {
  position: fixed; inset: 0; z-index: 250;
  display: flex; flex-direction: column;
  background: var(--bg);
}
.landing-overlay.hidden { display: none; }
/* Scroll déplacé ici depuis .landing-overlay (retour de Tim, 2026-08-21 :
   .intro-nav ne touchait pas le bord droit) — .landing-overlay reste
   position:fixed;inset:0 sans overflow propre, donc .intro-nav (flex:none,
   hors de cette zone) garde toujours la largeur réelle du viewport ; seul
   .landing-scroll a sa propre barre de défilement, invisible sur du
   contenu centré (hero/features/footer). min-height:0 nécessaire : sans
   ça un enfant flex avec overflow ne se contraint pas à la hauteur
   disponible et grandit sans jamais défiler. */
.landing-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }

/* Fond flouté (jaquette Helldivers 2, cf. app.js) façon page store
   Steam/PS Store/Epic plutôt qu'un simple dégradé plat. */
.bg-blur { position: fixed; inset: 0; z-index: -1; overflow: hidden; }
.bg-blur img {
  position: absolute; inset: -10%; width: 120%; height: 120%; object-fit: cover;
  filter: blur(38px) saturate(1.5) brightness(.75);
  transform: scale(1.1);
}
.bg-blur::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11,13,22,.35) 0%, rgba(11,13,22,.65) 55%, var(--bg) 100%),
    radial-gradient(60% 50% at 50% 15%, rgba(124,92,255,.12), transparent 70%);
}

.intro-nav {
  position: relative; z-index: 1; flex: none;
  background: linear-gradient(180deg, rgba(21, 26, 44, .92), rgba(21, 26, 44, .78));
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(124, 92, 255, .3);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .35);
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 40px;
}
.intro-cta {
  background: linear-gradient(120deg, var(--accent), var(--accent-2));
  color: #0b0d16; border: none; border-radius: 10px;
  font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase;
  padding: 10px 22px; cursor: pointer; transition: transform .18s, box-shadow .18s;
}
.intro-cta:hover { transform: translateY(-1px); box-shadow: 0 10px 26px rgba(124, 92, 255, .4); }
.intro-cta.ghost {
  background: linear-gradient(120deg, rgba(124, 92, 255, .22), rgba(0, 229, 195, .12));
  border: 1px solid rgba(124, 92, 255, .55); color: var(--text);
  box-shadow: 0 0 16px rgba(124, 92, 255, .18);
}
.intro-cta.ghost:hover { border-color: var(--accent-2); box-shadow: 0 0 20px rgba(0, 229, 195, .3); }

.hero { position: relative; text-align: center; padding: 60px 24px 40px; overflow: hidden; }
.hero::before {
  content: ''; position: absolute; inset: -20% -10% auto -10%; height: 500px;
  background: radial-gradient(60% 60% at 50% 0%, rgba(124, 92, 255, .28), transparent 70%);
  pointer-events: none;
}
.hero-eyebrow {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase;
  letter-spacing: 2.5px; margin-bottom: 18px;
}
.hero-eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2); box-shadow: 0 0 10px var(--accent-2); animation: chrono-pulse 1.8s ease-in-out infinite; }
.hero h1 {
  position: relative; font: 900 clamp(34px, 6vw, 68px) 'Orbitron', sans-serif; line-height: 1.05;
  letter-spacing: 1px; margin: 0 0 18px;
  background: linear-gradient(100deg, var(--text) 10%, var(--accent-2) 40%, var(--accent) 60%, var(--text) 90%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: title-shimmer 10s ease-in-out infinite;
}
@keyframes title-shimmer { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
.hero p.lede {
  position: relative; max-width: 620px; margin: 0 auto 30px; color: var(--text-2);
  font: 500 17px 'Rajdhani', sans-serif; line-height: 1.6;
}
.hero-actions { position: relative; display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.intro-cta.big { padding: 14px 30px; font-size: 14.5px; }
.hero-note { position: relative; color: var(--muted); font-size: 12px; margin-top: 10px; }

/* Chrono live — symbolise le suivi en continu, pas une vraie donnée. */
.live-chrono {
  position: relative; display: inline-flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 36px auto 0; padding: 18px 34px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(0, 229, 195, .35); border-radius: 18px;
  box-shadow: 0 0 40px rgba(0, 229, 195, .12);
}
.live-chrono-label {
  display: flex; align-items: center; gap: 7px;
  color: var(--accent-2); font: 700 10.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 2px;
}
.live-chrono-value {
  font: 800 clamp(28px, 5vw, 44px) 'Orbitron', sans-serif; letter-spacing: 2px;
  color: var(--text); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 22px rgba(0, 229, 195, .35);
}
.live-chrono-sub { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; }

/* ─── Révélation au scroll (retour de Tim, réf. melius.com) — un élément
   apparaît en fondu + léger glissement vers le haut au moment où il entre
   dans l'écran, une seule fois (IntersectionObserver, voir initLandingPage()
   dans app.js). --i (posé au cas par cas) décale légèrement chaque élément
   d'un même groupe pour un effet de cascade. ─────────────────────────── */
.reveal {
  opacity: 0; transform: translateY(28px);
  transition: opacity .7s cubic-bezier(.2, .8, .3, 1), transform .7s cubic-bezier(.2, .8, .3, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* "Mur vivant" — remplace le tourniquet 3D. Jaquettes dispersées à des
   positions fixes (collage), chacune avec deux couches : .living-tile-slot
   (positionnement + révélation continue au scroll) et .living-tile à
   l'intérieur (respiration + étiquette de stat) — séparées parce qu'un seul
   élément ne peut pas porter à la fois une transition d'entrée et une
   animation de respiration sur le même transform sans que l'une écrase
   l'autre. */
.living-wall {
  position: relative; width: 100%; max-width: 1180px; height: 640px;
  margin: 56px auto 0; padding: 0 24px;
}
.living-tile-slot {
  position: absolute; aspect-ratio: 3 / 4;
  opacity: 0; transform: translateY(34px);
  transition: opacity .6s cubic-bezier(.2, .8, .3, 1), transform .6s cubic-bezier(.2, .8, .3, 1);
  transition-delay: calc(var(--i, 0) * 55ms);
}
.living-tile-slot.is-visible { opacity: 1; transform: none; }
.living-tile {
  position: relative; width: 100%; height: 100%;
  border-radius: 12px; overflow: hidden; border: 1px solid var(--line);
  background: var(--bg-2); box-shadow: 0 18px 40px rgba(0, 0, 0, .55);
  animation: tile-breathe var(--dur, 7s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
  transition: transform .25s, box-shadow .25s, border-color .25s;
  cursor: default;
}
.living-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.living-tile-fallback {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  font-family: 'Orbitron', sans-serif; font-size: 18px; color: rgba(139, 147, 184, .5);
  background: repeating-linear-gradient(45deg, rgba(124, 92, 255, .08) 0 10px, transparent 10px 20px), var(--bg-2);
}
@keyframes tile-breathe {
  0%, 100% { transform: translateY(0) rotate(var(--rot, 0deg)); }
  50% { transform: translateY(-14px) rotate(var(--rot, 0deg)); }
}
.living-tile:hover {
  transform: translateY(-8px) rotate(0deg) scale(1.07) !important;
  border-color: rgba(124, 92, 255, .7); z-index: 20 !important;
  box-shadow: 0 20px 46px rgba(0, 0, 0, .6), 0 0 34px rgba(124, 92, 255, .45);
}
.living-tile-label {
  position: absolute; left: 7px; right: 7px; bottom: 7px;
  background: rgba(5, 6, 12, .78); backdrop-filter: blur(6px);
  border: 1px solid rgba(124, 92, 255, .4); border-radius: 8px;
  padding: 5px 8px; pointer-events: none;
  font: 700 10px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.35;
  opacity: 0; transform: translateY(5px);
  animation: label-reveal var(--label-dur, 12s) ease-in-out infinite;
  animation-delay: var(--label-delay, 2s);
}
.living-tile-label .stat { display: block; color: var(--accent-2); font-weight: 800; font-size: 10.5px; margin-top: 1px; }
@keyframes label-reveal {
  0%, 60% { opacity: 0; transform: translateY(5px); }
  68%, 84% { opacity: 1; transform: translateY(0); }
  94%, 100% { opacity: 0; transform: translateY(5px); }
}
@media (prefers-reduced-motion: reduce) {
  .living-tile, .living-tile-label { animation: none; }
  .living-tile-slot { opacity: 1; transform: none; }
}
.reel-caption {
  text-align: center; color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: 1.6px; margin-top: 8px;
}

.platforms-row { display: flex; align-items: center; justify-content: center; gap: 28px; flex-wrap: wrap; padding: 46px 24px 10px; }
.platform-pill {
  display: flex; align-items: center; gap: 8px;
  color: var(--muted); font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .5px;
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px;
}
.platform-pill b { color: var(--text); }
.platform-pill.steam { border-color: rgba(102, 192, 244, .35); }
.platform-pill.psn { border-color: rgba(74, 127, 255, .4); }
.platform-pill.ea { border-color: rgba(255, 71, 71, .35); }
.platform-pill.ubisoft { border-color: rgba(148, 157, 240, .4); }
.platform-pill.plus { border-style: dashed; }

/* ─── « Tout ce que fait TYG », en quinconce (2026-10-03, mockup
   docs/mockups/mockup-landing-fonctionnalites.html) — remplace les cartes
   épinglées et la frise de la roadmap. Une rangée « entre » (.in) quand elle a
   dépassé les deux tiers de l'écran ; chaque animation part de là
   (initLandingFeatures() dans app.js). Rien avec « réduire les animations ». ─── */
.lf { padding: 20px 0 10px; }
.lf-head { text-align: center; padding: 50px 24px 20px; }
.lf-eyebrow { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; letter-spacing: 2px; text-transform: uppercase; }
.lf-head h2 { font: 900 clamp(24px, 3.4vw, 36px) 'Orbitron', sans-serif; margin: 10px 0 8px; letter-spacing: 1px; }
.lf-head p { color: var(--text-2); font: 500 16px 'Rajdhani', sans-serif; margin: 0 auto; max-width: 620px; }
.lf-rows { max-width: 1080px; margin: 0 auto; padding: 10px 28px 40px; }
.lf-row { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 54px; align-items: center; padding: 46px 0; }
.lf-row.flip .lf-screen { order: 2; }
.lf-row .lf-screen { opacity: 0; transform: translateX(-36px); transition: opacity .9s ease, transform .9s ease; }
.lf-row.flip .lf-screen { transform: translateX(36px); }
.lf-row .lf-text { opacity: 0; transform: translateY(18px); transition: opacity .9s ease .25s, transform .9s ease .25s; }
.lf-row.in .lf-screen, .lf-row.in .lf-text { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .lf-row .lf-screen, .lf-row .lf-text { transition: none; } }
.lf-screen { border-radius: 20px; border: 1px solid rgba(124, 92, 255, .35); padding: 22px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel)); box-shadow: 0 30px 80px rgba(0, 0, 0, .45), 0 0 60px rgba(124, 92, 255, .12); overflow: hidden; }
.lf-num { font: 700 13px 'Orbitron', sans-serif; color: var(--accent-2); letter-spacing: 2px; }
.lf-text h3 { font: 800 clamp(20px, 2.4vw, 27px) 'Orbitron', sans-serif; margin: 8px 0 10px; letter-spacing: .5px; line-height: 1.2; }
.lf-text p { color: var(--text-2); font: 500 16.5px/1.55 'Rajdhani', sans-serif; margin: 0 0 14px; }
.lf-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.lf-tags span { font: 700 12.5px 'Rajdhani', sans-serif; color: var(--text-2); padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg-2); }
@media (max-width: 860px) {
  .lf-row, .lf-row.flip { grid-template-columns: 1fr; gap: 18px; padding: 28px 0; }
  .lf-row.flip .lf-screen { order: 0; }
}

/* Les écrans */
.sc-title { font: 700 12px 'Orbitron', sans-serif; letter-spacing: 1.4px; color: var(--muted); margin-bottom: 12px; text-transform: uppercase; }
.sc-pills { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.sc-pill { font: 700 12px 'Rajdhani', sans-serif; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); }
.sc-pill.steam { color: var(--steam); border-color: rgba(102, 192, 244, .5); }
.sc-pill.psn { color: var(--psn); border-color: rgba(74, 127, 255, .55); }
.sc-pill.man { color: var(--accent-2); border-color: rgba(0, 229, 195, .45); }
.sc-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.sc-card { border-radius: 10px; overflow: hidden; background: var(--bg-2); border: 1px solid var(--line); }
.sc-card img { width: 100%; aspect-ratio: 3/4; object-fit: cover; display: block; }
.sc-card div { padding: 6px 8px 8px; font: 700 12px 'Rajdhani', sans-serif; }
.sc-card small { display: block; color: var(--muted); font-weight: 600; font-size: 11px; }
.sc-chrono { margin-top: 14px; display: flex; align-items: center; gap: 10px; border: 1px solid rgba(0, 229, 195, .4); border-radius: 12px; padding: 10px 12px; background: rgba(0, 229, 195, .06); }
.sc-chrono b { font: 800 20px 'Orbitron', sans-serif; color: var(--accent-2); }
.sc-chrono span { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.sc-game { display: flex; gap: 14px; align-items: center; margin-bottom: 16px; }
.sc-game img { width: 64px; border-radius: 8px; }
.sc-game b { font: 800 16px 'Rajdhani', sans-serif; display: block; }
.sc-game span { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; }
.sc-bar { margin-bottom: 12px; }
.sc-bar .l { display: flex; justify-content: space-between; font: 700 13px 'Rajdhani', sans-serif; color: var(--text-2); margin-bottom: 4px; }
.sc-bar .t { position: relative; height: 8px; border-radius: 4px; background: var(--bg-2); }
.sc-bar .t i { position: absolute; inset: 0 auto 0 0; border-radius: 4px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.sc-bar .t i.gold { background: linear-gradient(90deg, rgba(255, 185, 56, .6), var(--gold)); }
.sc-bar .t s { position: absolute; top: -4px; width: 3px; height: 16px; background: var(--accent-2); border-radius: 1px; box-shadow: 0 0 6px rgba(0, 229, 195, .6); }
.sc-mile { display: inline-flex; gap: 6px; align-items: center; font: 700 12.5px 'Rajdhani', sans-serif; padding: 4px 10px; border-radius: 999px; border: 1px solid rgba(0, 229, 195, .45); color: var(--text); margin-top: 6px; }
.sc-troph { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.sc-troph img { width: 54px; }
.sc-troph b { font: 800 26px 'Orbitron', sans-serif; }
.sc-troph span { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; display: block; }
.sc-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; background: var(--bg-2); border: 1px solid var(--line); margin-bottom: 7px; font: 700 13px 'Rajdhani', sans-serif; }
.sc-row .ic { width: 28px; height: 28px; border-radius: 6px; display: grid; place-items: center; background: rgba(124, 92, 255, .2); flex: none; }
.sc-row .n { flex: 1; min-width: 0; }
.sc-row .n small { display: block; color: var(--muted); font-weight: 600; font-size: 11.5px; }
.sc-row .g { color: var(--accent-2); font-size: 12px; }
.sc-row .m { color: var(--gold); font-size: 11px; letter-spacing: .8px; text-transform: uppercase; }
.sc-goal { border-radius: 14px; border: 1px solid rgba(0, 229, 195, .45); padding: 14px; background: linear-gradient(160deg, rgba(0, 229, 195, .08), transparent); display: flex; gap: 12px; }
.sc-goal img { width: 70px; border-radius: 8px; }
.sc-goal .k { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; }
.sc-goal b { display: block; font: 800 16px 'Rajdhani', sans-serif; margin: 2px 0 6px; }
.sc-goal .badge { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; }
.sc-next { margin-top: 12px; display: inline-block; font: 800 13px 'Rajdhani', sans-serif; padding: 7px 14px; border-radius: 999px; border: 1px solid rgba(0, 229, 195, .55); }
.sc-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.sc-kpis div { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.sc-kpis b { display: block; font: 800 17px 'Orbitron', sans-serif; }
.sc-kpis span { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; }
.sc-two { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.sc-mini { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 10px; }
.sc-mini .h { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 6px; }
.sc-bars { display: flex; align-items: flex-end; gap: 3px; height: 54px; }
.sc-bars i { flex: 1; border-radius: 3px 3px 0 0; background: linear-gradient(var(--accent-2), var(--accent)); }
.sc-bars i.dim { opacity: .35; }
.sc-heat { display: grid; grid-template-columns: repeat(26, 1fr); gap: 2px; }
.sc-heat i { aspect-ratio: 1; border-radius: 2px; background: rgba(120, 140, 255, .14); }
.sc-heat i.a { background: rgba(0, 229, 195, .35); } .sc-heat i.b { background: rgba(0, 229, 195, .65); } .sc-heat i.c { background: var(--accent-2); }
.sc-recs { display: flex; flex-wrap: wrap; gap: 6px; }
.sc-rec { font: 700 12px 'Rajdhani', sans-serif; padding: 4px 9px; border-radius: 8px; background: var(--bg-2); border: 1px solid var(--line); color: var(--text-2); }
.sc-rec b { color: var(--text); font-family: 'Orbitron', sans-serif; font-size: 11.5px; margin-right: 3px; }
.sc-rec.gold b { color: var(--gold); }
.sc-genres { display: flex; height: 10px; border-radius: 5px; overflow: hidden; margin: 2px 0 6px; }
.sc-genres i:nth-child(1) { background: var(--accent); } .sc-genres i:nth-child(2) { background: var(--accent-2); } .sc-genres i:nth-child(3) { background: var(--gold); } .sc-genres i:nth-child(4) { background: var(--psn); } .sc-genres i:nth-child(5) { background: var(--line); }
.sc-glegend { color: var(--text-2); font: 600 11.5px 'Rajdhani', sans-serif; }
.sc-hl { border-radius: 12px; border: 1px solid rgba(124, 92, 255, .5); padding: 11px 13px; background: linear-gradient(160deg, rgba(124, 92, 255, .14), transparent); }
.sc-hl-k { color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; }
.sc-hl b { display: block; font: 800 15px 'Rajdhani', sans-serif; margin: 3px 0 2px; }
.sc-hl small { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.sc-maj { font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--gold); border: 1px solid rgba(255, 185, 56, .45); border-radius: 6px; padding: 1px 6px; flex: none; }
.sc-deals { display: flex; gap: 8px; align-items: center; }
.sc-dl { position: relative; width: 46px; flex: none; }
.sc-dl img { width: 46px; aspect-ratio: 3/4; object-fit: cover; border-radius: 6px; display: block; border: 1px solid var(--line); }
.sc-dl em { position: absolute; left: 50%; bottom: -6px; transform: translateX(-50%); font: 800 10.5px 'Rajdhani', sans-serif; font-style: normal; color: #0b0d16; background: var(--accent-2); border-radius: 5px; padding: 0 4px; white-space: nowrap; }
.sc-dl.more { width: auto; color: var(--text-2); font: 700 12px 'Rajdhani', sans-serif; padding-left: 4px; }
.sc-news { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sc-deal { border-radius: 10px; overflow: hidden; border: 1px solid var(--line); background: var(--bg-2); }
.sc-deal img { width: 100%; aspect-ratio: 16/9; object-fit: cover; display: block; }
.sc-deal div { padding: 6px 8px; font: 700 12.5px 'Rajdhani', sans-serif; display: flex; justify-content: space-between; }
.sc-deal em { font-style: normal; color: #0b0d16; background: var(--accent-2); border-radius: 6px; padding: 0 6px; }
.sc-vs .who { display: flex; justify-content: space-between; font: 800 14px 'Rajdhani', sans-serif; margin-bottom: 10px; }
.sc-vs .who span:last-child { color: var(--accent-2); }
.sc-friends { display: grid; gap: 7px; margin-bottom: 10px; }
.sc-fr { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; background: var(--bg-2); border: 1px solid var(--line); }
.sc-fr .av { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font: 800 13px 'Orbitron', sans-serif; color: #0b0d16; background: linear-gradient(135deg, var(--accent), var(--accent-2)); flex: none; }
.sc-fr .av.b { background: linear-gradient(135deg, var(--gold), var(--accent)); }
.sc-fr div { flex: 1; min-width: 0; }
.sc-fr b { font: 800 13.5px 'Rajdhani', sans-serif; display: block; }
.sc-fr small { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.sc-fr .code { color: var(--text-2); font: 700 12px 'Rajdhani', sans-serif; }
.sc-tabs, .sc-filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.sc-tabs span, .sc-filters span { font: 700 11.5px 'Rajdhani', sans-serif; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); color: var(--text-2); }
.sc-tabs span.on { border-color: rgba(124, 92, 255, .6); color: var(--text); background: rgba(124, 92, 255, .15); }
.sc-filters span.on { border-color: rgba(0, 229, 195, .55); color: var(--text); }
.sc-notif { border: 1px solid rgba(255, 185, 56, .45); background: rgba(255, 185, 56, .08); border-radius: 10px; padding: 8px 12px; font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); }
.sc-notif b { color: var(--text); }
.sc-j { font: 800 13px 'Orbitron', sans-serif; color: var(--gold); }
.sc-prices { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 12px; }
.sc-price { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.sc-price b { font: 800 13.5px 'Rajdhani', sans-serif; }
.sc-meta { font: 800 13px 'Orbitron', sans-serif; color: #0b0d16; background: #6c3; border-radius: 6px; padding: 1px 7px; }
.sc-cmp { border: 1px solid var(--line); border-radius: 10px; background: var(--bg-2); padding: 4px 10px; }
.sc-cmp-h, .sc-cmp-r { display: grid; grid-template-columns: 1fr 44px 52px; align-items: center; gap: 6px; }
.sc-cmp-h { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; padding: 4px 0; text-align: center; }
.sc-cmp-h span:last-child { color: var(--accent-2); }
.sc-cmp-r { border-top: 1px solid var(--line); padding: 6px 0; font: 700 12.5px 'Rajdhani', sans-serif; }
.sc-cmp-r small { display: block; color: var(--muted); font-weight: 600; font-size: 11px; }
.sc-cmp-r i { font-style: normal; text-align: center; font-weight: 800; }
.sc-cmp-r i.ok { color: var(--accent-2); } .sc-cmp-r i.no { color: var(--muted); }
.sc-invite { margin-top: 10px; color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif; }
.sc-invite b { color: var(--accent-2); font-family: 'Orbitron', sans-serif; font-size: 11.5px; letter-spacing: 1px; }
.sc-two .sc-mail { margin-top: 0; }
.sc-mail { margin-top: 14px; border-radius: 12px; border: 1px solid var(--line); background: #0b0d16; padding: 12px 14px; font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); }
.sc-mail b { color: var(--text); display: block; font-size: 14px; margin-bottom: 2px; }


/* ── Animations (à l'entrée de chaque rangée ; rien avec « réduire les animations ») ── */
.sc-bar .t i { width: 0; transition: width 1.8s cubic-bezier(.2, .7, .2, 1) calc(.8s + var(--k, 0) * .35s); }
.in .sc-bar .t i { width: var(--w); }
.sc-bar .t s { left: var(--l); opacity: 0; transform: scaleY(.2); transition: opacity .6s 2.9s, transform .6s 2.9s; }
.in .sc-bar .t s { opacity: 1; transform: none; }
.sc-bars i { height: 0; transition: height 1.4s cubic-bezier(.2, .7, .2, 1) calc(.8s + var(--k, 0) * .09s); }
.in .sc-bars i { height: var(--h); }
.sc-genres i { width: 0; transition: width 1.2s ease calc(1.4s + var(--k, 0) * .25s); }
.in .sc-genres i { width: var(--w); }
.sc-anim { opacity: 0; transform: translateY(10px); transition: opacity .7s ease calc(.6s + var(--k, 0) * .16s), transform .7s ease calc(.6s + var(--k, 0) * .16s); }
.in .sc-anim { opacity: 1; transform: none; }
.sc-heat i.a, .sc-heat i.b, .sc-heat i.c { opacity: 0; transition: opacity .5s ease var(--d, 0s); }
.in .sc-heat i { opacity: 1; }
.sc-late { opacity: 0; transition: opacity .7s 2.4s; }
.in .sc-late { opacity: 1; }
.in .sc-glow { animation: sc-glow 2.6s ease-in-out 3.2s infinite; }
@keyframes sc-glow { 0%, 100% { box-shadow: none; } 50% { box-shadow: 0 0 0 3px rgba(0, 229, 195, .2), 0 0 22px rgba(0, 229, 195, .35); } }
.sc-drop { opacity: 0; transform: translateY(-12px); transition: opacity .7s .8s, transform .7s .8s; }
.in .sc-drop { opacity: 1; transform: none; }
.in .sc-bell { display: inline-block; animation: sc-ring 1.4s ease 1.7s 2; transform-origin: 50% 0; }
@keyframes sc-ring { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(16deg); } 40% { transform: rotate(-14deg); } 60% { transform: rotate(9deg); } 80% { transform: rotate(-5deg); } }
.sc-pop { display: inline-block; transform: scale(0); transition: transform .45s cubic-bezier(.3, 1.6, .5, 1) calc(2.2s + var(--k, 0) * .6s); }
.in .sc-pop { transform: none; }
/* Les sujets se superposent dans la même cellule de grille : le cadre prend la
   hauteur du plus long (un vrai titre tient parfois sur deux lignes). */
.sc-hl { position: relative; display: grid; }
.sc-hl-i { grid-area: 1 / 1; padding-right: 26px; opacity: 0; transform: translateY(6px); transition: opacity .5s, transform .5s; }
.sc-hl-i.on { opacity: 1; transform: none; }
.sc-hl-dots { position: absolute; right: 12px; top: 10px; display: flex; gap: 4px; }
.sc-hl-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--line); }
.sc-hl-dots i.on { background: var(--accent-2); }
.sc-cd { font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
  .sc-bar .t i, .sc-bars i, .sc-genres i, .sc-anim, .sc-heat i, .sc-late, .sc-drop, .sc-pop, .sc-bar .t s, .sc-hl-i { transition: none !important; }
  .in .sc-glow, .in .sc-bell { animation: none !important; }
}
/* Mention « en direct » sous les chapitres 6 et 7, affichée seulement une fois
   les vraies données chargées : le reste de la page est un profil de démo. */
.lf-live { margin-top: 12px; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; display: flex; align-items: center; gap: 7px; }
.lf-live[hidden] { display: none; }
.lf-live .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2); box-shadow: 0 0 8px var(--accent-2); }
.sc-hl-i b, .sc-row .n { overflow-wrap: anywhere; }
@media (max-width: 600px) {
  .lf-rows { padding: 0 16px 20px; }
  .lf-screen { padding: 16px; }
  .sc-cards { gap: 7px; }
  .sc-kpis { grid-template-columns: repeat(2, 1fr); }
  .sc-two { grid-template-columns: 1fr; }
  .sc-prices { grid-template-columns: 1fr 1fr; }
}
.hero-note b { color: var(--text-2); }

/* ─── CTA final "stylé" (retour de Tim) — reprend le vocabulaire déjà posé
   par le hero pour faire un vrai bookend : même halo radial (turquoise
   plutôt que violet), même titre à dégradé animé (title-shimmer, déjà
   défini pour le h1 du hero), même pastille "live" (chrono-pulse, déjà
   défini). Le bouton gagne un halo flou qui respire doucement. ────────── */
.footer-cta { position: relative; text-align: center; padding: 100px 24px 90px; overflow: hidden; }
.footer-cta::before {
  content: ''; position: absolute; inset: -30% -10% auto -10%; height: 480px;
  background: radial-gradient(60% 60% at 50% 30%, rgba(0, 229, 195, .22), transparent 70%);
  pointer-events: none;
}
.footer-cta-eyebrow {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase;
  letter-spacing: 2.5px; margin-bottom: 18px;
}
.footer-cta-eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2); box-shadow: 0 0 10px var(--accent-2); animation: chrono-pulse 1.8s ease-in-out infinite; }
.footer-cta h2 {
  position: relative; font: 900 clamp(28px, 4.5vw, 46px) 'Orbitron', sans-serif; margin: 0 0 14px; letter-spacing: .5px;
  background: linear-gradient(100deg, var(--text) 10%, var(--accent-2) 40%, var(--accent) 60%, var(--text) 90%);
  background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: title-shimmer 10s ease-in-out infinite;
}
.footer-cta p { position: relative; color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; margin-bottom: 32px; }
.footer-cta-btn-wrap { position: relative; display: inline-block; }
.footer-cta-btn-wrap::before {
  content: ''; position: absolute; inset: -14px; border-radius: 18px;
  background: linear-gradient(120deg, var(--accent), var(--accent-2));
  filter: blur(20px); opacity: .4; z-index: -1;
  animation: cta-glow-pulse 2.6s ease-in-out infinite;
}
@keyframes cta-glow-pulse { 0%, 100% { opacity: .3; transform: scale(1); } 50% { opacity: .55; transform: scale(1.08); } }
.footer-cta-note { position: relative; color: var(--muted); font-size: 12px; margin-top: 16px; }
@media (prefers-reduced-motion: reduce) {
  .footer-cta h2 { animation: none; background-position: 0% 50%; }
  .footer-cta-btn-wrap::before { animation: none; opacity: .4; }
}

@media (max-width: 700px) {
  .intro-nav { padding: 18px 20px; gap: 10px; }
  /* `.logo { order: 2 }` (barre du haut de l'app, sous 700 px) passait aussi le
     logo de la landing à droite du bouton, et il débordait de l'écran. */
  .intro-nav .logo { order: 0; font-size: 15px; letter-spacing: 1px; }
}
/* Avec le badge « Beta », le logo ne laisse plus la place au bouton sur un
   téléphone de 375 px. */
@media (max-width: 420px) {
  .intro-nav { padding: 16px 14px; }
  .intro-nav .logo { font-size: 13px; letter-spacing: .5px; gap: .35em; }
}
@media (max-width: 900px) {
  .living-wall { height: 900px; }
}

/* ─── Connexion (Supabase Auth, email + mot de passe) ────────────────── */
.login-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
}
.login-box {
  width: min(420px, 90vw); text-align: center;
  padding: 36px 32px; background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35); border-radius: 20px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
}
.login-box .logo { margin-bottom: 16px; }
.login-hint { color: var(--text-2); font-size: 12.5px; line-height: 1.5; margin: 0 0 18px; }
/* Champs pleine largeur, texte aligné à gauche (retour de Tim, 2026-08-08) :
   avec le texte centré, la ligne email (pleine largeur) et la ligne mot de
   passe (autrefois partagée avec le bouton, donc plus étroite) ne
   centraient pas au même endroit — décalage visible entre les deux champs. */
.login-box .edit-input-row { margin-bottom: 10px; }
.login-box .edit-input-row input { text-align: left; padding: 10px 14px; font-size: 14px; }
.login-submit {
  display: block; width: 100%; margin-top: 4px; padding: 11px 14px;
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border: none;
  border-radius: 8px; font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: uppercase;
  cursor: pointer; transition: filter .15s;
}
.login-submit:hover { filter: brightness(1.08); }
.login-toggle {
  display: block; width: 100%; margin-top: 14px; padding: 0;
  background: none; border: none; color: var(--accent); font-size: 12.5px;
  cursor: pointer;
}
.login-toggle:hover { text-decoration: underline; }
.login-status { color: var(--muted); font-size: 12px; margin-top: 12px; min-height: 1em; }

/* ─── Modal générique (remplace alert()/confirm() natifs, 2026-08-03) ───
   z-index au-dessus de tous les autres overlays (peut s'ouvrir par-dessus la
   modale d'ajout de jeu ou le panneau détail). */
/* ─── Popup de synchronisation à la demande (tâche #21, retour de Tim,
   2026-08-08) — déclenché juste après avoir lié Steam/PSN, voir
   showSyncPopup() dans app.js. z-index au-dessus du guide d'onboarding
   (600) : la liaison peut se faire pendant l'étape 1 du guide. ───────── */
.sync-overlay {
  position: fixed; inset: 0; z-index: 650;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .75); backdrop-filter: blur(8px);
}
.sync-box {
  width: min(360px, 90vw); padding: 32px 28px; text-align: center;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35); border-radius: 16px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
}
.sync-box .loading-pulse { margin: 0 auto 18px; }
.sync-title { font: 700 15px 'Orbitron', sans-serif; color: var(--text); margin-bottom: 8px; }
.sync-text { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; line-height: 1.5; margin-bottom: 18px; }

/* ─── Écran d'accueil du guide (tâche #55, retour de Tim, 2026-08-08) —
   affiché sur le dashboard (même vide) à la première connexion, propose de
   partir sur "connecter une plateforme" ou "ajouter un jeu à la main"
   plutôt que d'imposer l'un des deux. z-index sous le guide (600) puisque
   startTour() la ferme avant d'ouvrir #tour-veil. ─────────────────────── */
.tour-welcome-overlay {
  position: fixed; inset: 0; z-index: 590;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .75); backdrop-filter: blur(8px);
}
.tour-welcome-box {
  width: min(360px, 90vw); padding: 32px 28px; text-align: center;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35); border-radius: 16px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
  display: flex; flex-direction: column; gap: 10px;
}
.tour-welcome-box .logo { margin-bottom: 6px; }
.tour-welcome-box h3 { font: 700 17px 'Orbitron', sans-serif; color: var(--text); margin-bottom: 2px; }
.tour-welcome-box p { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; line-height: 1.5; margin-bottom: 8px; }
.tour-welcome-box .chip { padding: 10px 14px; }
/* Onboarding v2 (mockup mockup-onboarding-2.html) : l'ami qui a invité, et
   Steam / PlayStation côte à côte. */
.tw-friend { display: flex; align-items: center; gap: 10px; border: 1px solid rgba(0, 229, 195, .4); background: rgba(0, 229, 195, .06); border-radius: 12px; padding: 9px 12px; margin: 4px 0 4px; text-align: left; }
.tw-friend.hidden { display: none; }
.tw-friend .av { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font: 800 13px 'Orbitron', sans-serif; color: #0b0d16; background: linear-gradient(135deg, var(--accent), var(--accent-2)); flex: none; }
.tw-friend span { color: var(--text-2); font: 600 13.5px 'Rajdhani', sans-serif; line-height: 1.4; }
.tw-friend b { color: var(--text); }
.tw-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tw-pick .chip { margin: 0; }
.tw-or { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin: 2px 0; }

/* ─── Guide d'onboarding (tâche #55, retour de Tim, 2026-08-08) ───────
   Un seul élément avec un box-shadow géant = trou lumineux dans le voile
   sombre, pas besoin de SVG mask. z-index au-dessus du tiroir latéral
   (401) — l'étape "Leaderboards" ouvre le tiroir et le met en évidence
   par-dessus. pointer-events:none sur le voile : la démo n'a pas besoin de
   bloquer les clics sous-jacents, seule la bulle (pointer-events:auto)
   doit rester cliquable. */
.tour-veil { position: fixed; inset: 0; z-index: 600; pointer-events: none; }
.tour-highlight {
  position: absolute; border-radius: 10px;
  box-shadow: 0 0 0 9999px rgba(5, 6, 12, .78);
  transition: top .35s cubic-bezier(.2, .8, .3, 1), left .35s cubic-bezier(.2, .8, .3, 1),
              width .35s cubic-bezier(.2, .8, .3, 1), height .35s cubic-bezier(.2, .8, .3, 1);
  outline: 2px solid var(--accent-2);
  outline-offset: 4px;
}
.tour-tooltip {
  position: absolute; max-width: 300px; pointer-events: auto;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .45); border-radius: 14px;
  padding: 16px 18px; box-shadow: 0 25px 60px rgba(0, 0, 0, .55);
  transition: top .35s cubic-bezier(.2, .8, .3, 1), left .35s cubic-bezier(.2, .8, .3, 1);
}
.tour-tooltip h4 { font: 700 13px 'Orbitron', sans-serif; color: var(--accent-2); letter-spacing: .3px; margin-bottom: 8px; }
.tour-tooltip p { font: 500 13px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.5; margin-bottom: 14px; }
.tour-error {
  color: var(--danger); font: 600 12px 'Rajdhani', sans-serif; line-height: 1.4;
  margin: -6px 0 14px; padding: 6px 10px;
  border: 1px solid rgba(255, 84, 112, .4); border-radius: 6px; background: rgba(255, 84, 112, .08);
}
.tour-tooltip-foot { display: flex; justify-content: space-between; align-items: center; }
.tour-step-count { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .3px; }
.tour-actions { display: flex; gap: 8px; align-items: center; }
.tour-actions .chip { padding: 5px 12px; font-size: 11.5px; }
.tour-skip { background: none; border: none; color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; cursor: pointer; text-decoration: underline; }
.tour-skip:hover { color: var(--text); }

.modal-overlay {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .65);
  backdrop-filter: blur(8px);
  animation: fade .2s both;
}
.modal-box {
  width: min(420px, 90vw);
  padding: 26px 28px;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35);
  border-radius: 16px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
}
.modal-message { margin: 0 0 20px; color: var(--text); font: 500 14px 'Rajdhani', sans-serif; line-height: 1.5; }
.modal-message p { margin: 0; }
.modal-message a { color: var(--accent-2); }
.modal-message a:hover { text-decoration: underline; }

/* Variante visuelle "fusion" : jaquette source -> flèche -> jaquette cible */
.modal-merge-visual { display: flex; align-items: flex-start; justify-content: center; gap: 14px; margin-bottom: 16px; }
.modal-merge-cover-col { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100px; }
.modal-merge-cover {
  width: 90px; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel);
}
.modal-merge-cover.cover-fallback { display: flex; align-items: center; justify-content: center; font-size: 13px; color: var(--muted); }
.modal-merge-label {
  font: 600 11px 'Rajdhani', sans-serif; text-align: center; color: var(--muted); line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.modal-merge-arrow { font-size: 22px; color: var(--accent-2); flex: none; margin-top: 32px; }
.modal-merge-text { margin: 0; color: var(--text); font: 500 13px 'Rajdhani', sans-serif; line-height: 1.5; text-align: center; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* ─── Ajout manuel de jeu (tâche #31) ─────────────────────────────────── */
.add-game-overlay {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .55);
  backdrop-filter: blur(20px);
  animation: fade .3s both;
}
/* #unmatched-search-overlay ("Autre", mockup mockup-unmatched-games.html)
   s'ouvre PAR-DESSUS #unmatched-overlay (.review-overlay, z-index 310) — le
   z-index 120 hérité de .add-game-overlay le laissait caché derrière (repéré
   par Tim, 2026-08-10). */
#unmatched-search-overlay { z-index: 320; }
.add-game-box {
  position: relative;
  width: min(520px, 92vw);
  padding: 32px;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .35);
  border-radius: 20px;
  box-shadow: 0 40px 100px rgba(0, 0, 0, .5), 0 0 60px rgba(124, 92, 255, .12);
}
.add-game-box h2 { margin: 0 0 8px; font: 700 20px 'Orbitron', sans-serif; }
.add-game-hint { color: var(--text-2); font-size: 12px; line-height: 1.5; margin: 0 0 18px; }
.add-game-box .edit-row { margin-bottom: 14px; }
.add-game-results { display: flex; flex-direction: column; gap: 6px; max-height: 340px; overflow-y: auto; margin-top: 10px; }
.add-game-result {
  display: flex; align-items: center; gap: 10px; text-align: left;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 6px 12px 6px 6px; cursor: pointer;
  transition: border-color .15s;
}
.add-game-result:hover { border-color: var(--accent); }
.add-game-result-cover {
  width: 40px; height: 54px; flex: none; object-fit: cover; border-radius: 5px;
  background: var(--panel);
}
.add-game-result-cover.cover-fallback { display: flex; align-items: center; justify-content: center; font-size: 11px; }
.add-game-result-info { min-width: 0; }
.add-game-result-name {
  font: 600 13px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.add-game-result-date { color: var(--muted); font-size: 11px; margin-top: 2px; }

/* ── Changer la jaquette (mockup mockup-choisir-jaquette.html, 2026-09-15) ── */
.cover-actions { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.cover-change-btn { display: inline-flex; align-items: center; gap: 6px; }
.cover-reset-link { background: none; border: 0; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.cover-reset-link:hover { color: var(--text); }
.cover-box { width: min(760px, 94vw); max-height: 92vh; overflow-y: auto; }
.cover-box .add-game-hint { margin-bottom: 14px; }
.cover-now { display: flex; align-items: center; gap: 12px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px 8px 8px; margin-bottom: 14px; }
.cover-now img { width: 44px; aspect-ratio: 3/4; object-fit: cover; border-radius: 5px; background: var(--panel); }
.cover-now .lbl { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; }
.cover-now .val { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.cover-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.cover-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 12px; padding: 4px; }
.cover-grid:empty { display: none; }
/* Le défilement est sur le conteneur, pas sur une grille : l'onglet par défaut
   en empile deux quand le jeu a des visuels de boutique (mockup
   mockup-jaquette-depuis-plateformes.html, 2026-09-16). */
.cover-scroll { max-height: 440px; overflow-y: auto; }
.cover-scroll:empty { display: none; }
.cover-group + .cover-group { margin-top: 18px; }
.cover-group-head { display: flex; align-items: baseline; gap: 8px; margin: 0 0 8px 4px; flex-wrap: wrap; }
.cover-group-head h4 { font: 700 11.5px 'Orbitron', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--text); margin: 0; }
.cover-group-head span { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.cover-opt { position: relative; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; color: var(--text); }
.cover-opt img { display: block; width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: 10px; border: 2px solid var(--line); transition: border-color .15s, transform .15s; background: var(--bg-2); }
.cover-opt:hover img { border-color: rgba(124,92,255,.6); transform: translateY(-2px); }
.cover-opt.selected img { border-color: var(--accent-2); box-shadow: 0 0 0 3px rgba(0,229,195,.25); }
.cover-opt.current { cursor: default; }
.cover-opt.current img { opacity: .55; }
.cover-opt.current:hover img { border-color: var(--line); transform: none; }
.cover-opt .tick { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%; background: var(--accent-2); color: #0b0d16; font: 900 13px/22px 'Rajdhani', sans-serif; text-align: center; }
.cover-opt .flag { position: absolute; top: 6px; left: 6px; background: rgba(11,13,22,.85); border: 1px solid var(--line); border-radius: 6px; color: var(--text-2); font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: uppercase; padding: 1px 6px; }
.cover-opt .flag.steam { color: var(--steam); border-color: rgba(102,192,244,.4); }
.cover-opt .name { font: 700 12.5px 'Rajdhani', sans-serif; margin-top: 6px; line-height: 1.2; }
.cover-opt .meta { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.cover-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.cover-foot .note { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.cover-foot .actions { display: flex; gap: 8px; margin-left: auto; }
.cover-foot .chip.primary:disabled { opacity: .45; cursor: default; }
.link-preview { display: flex; gap: 16px; align-items: flex-start; margin-top: 6px; flex-wrap: wrap; }
.link-preview img { width: 150px; aspect-ratio: 3/4; object-fit: cover; border-radius: 10px; border: 2px solid var(--accent-2); }
.link-preview > div { flex: 1; min-width: 200px; }
.link-preview p { color: var(--text-2); font: 500 13px/1.5 'Rajdhani', sans-serif; margin: 0 0 8px; }
.link-preview .ok { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; }
.link-preview .ok.err { color: var(--danger); }
/* Modal "Chercher une alternative"/"Non identifiés" uniquement (retour de
   Tim, 2026-08-28) — signale quelle version a une vraie référence de temps
   IGDB, pour ne pas cliquer à l'aveugle sur chaque résultat. */
.add-game-result-ttb {
  color: var(--accent-2); font: 700 10.5px 'Rajdhani', sans-serif;
  letter-spacing: .4px; text-transform: uppercase; margin-top: 3px;
}
.add-game-status { color: var(--muted); font-size: 12px; margin-top: 10px; min-height: 1em; }

/* ═══════════════════════════════════════════════════════════════════
   Page "Leaderboards" (tâche #41) — classement temps de jeu, podium
   platines, vue d'ensemble trophées PSN.
   ═══════════════════════════════════════════════════════════════════ */
.an-section { padding: 26px 32px 4px; }
.an-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.an-head .section-title { border: none; margin: 0; padding: 0; }
.an-sub { color: var(--text-2); font-size: 12.5px; margin: 4px 0 6px; }

/* Podium — 3 dernières platines, 1er au centre et plus haut. */
.podium { display: flex; align-items: flex-end; justify-content: center; gap: 22px; padding: 18px 0 6px; flex-wrap: wrap; }
.podium-item { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 148px; }
.podium-item.rank-1 { order: 2; }
.podium-item.rank-2 { order: 1; }
.podium-item.rank-3 { order: 3; }
.podium-cover-wrap { position: relative; width: 96px; aspect-ratio: 3/4; }
.podium-item.rank-1 .podium-cover-wrap { width: 116px; }
.podium-cover {
  width: 100%; height: 100%; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line); box-shadow: 0 14px 30px rgba(0, 0, 0, .5);
}
.podium-medal-icon {
  position: absolute; top: -12px; right: -12px; width: 44px; height: auto; z-index: 2;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .6)) drop-shadow(0 0 10px rgba(0, 229, 195, .55)) drop-shadow(0 0 16px rgba(124, 92, 255, .35));
}
.podium-name { font: 700 12.5px 'Rajdhani', sans-serif; text-align: center; line-height: 1.25; }
.podium-date { font: 600 10.5px 'Rajdhani', sans-serif; color: var(--muted); }
.podium-base {
  width: 100%; border-radius: 8px 8px 0 0; text-align: center;
  font: 800 20px 'Orbitron', sans-serif; color: #0b0d16; padding: 10px 0;
}
.rank-1 .podium-base { height: 64px; background: linear-gradient(180deg, #ffe08a, var(--gold)); }
.rank-2 .podium-base { height: 44px; background: linear-gradient(180deg, #e9ecf7, #b9c2ee); }
.rank-3 .podium-base { height: 30px; background: linear-gradient(180deg, #e2b083, #c98a4f); }

/* Classement temps de jeu — liste de lignes avec barre relative. */
.leaderboard-list { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.lb-row {
  display: flex; align-items: center; gap: 14px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 12px; padding: 9px 16px;
}
.lb-rank { font: 800 15px 'Orbitron', sans-serif; color: var(--muted); width: 22px; text-align: center; flex: none; }
.lb-rank.top { color: var(--gold); }
.lb-cover { width: 34px; aspect-ratio: 3/4; border-radius: 5px; flex: none; background: var(--bg-2); border: 1px solid var(--line); overflow: hidden; }
.lb-info { flex: 1; min-width: 0; }
.lb-name { font: 700 13.5px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-bar { position: relative; height: 6px; border-radius: 3px; background: var(--bg-2); border: 1px solid var(--line); margin-top: 5px; overflow: hidden; }
.lb-bar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.lb-hours { font: 700 14px 'Orbitron', sans-serif; flex: none; width: 68px; text-align: right; }

/* ─── Leaderboards plus complet (2026-09-15, mockup
   docs/mockups/mockup-leaderboards-complet.html) ─────────────────────── */
.lb-link-btn { background: none; border: none; color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; cursor: pointer; padding: 0; }
.lb-link-btn:hover { text-decoration: underline; }

/* 1. Ligne cliquable + dépliage du temps de jeu d'un jeu */
.lb-row.lb-clickable { cursor: pointer; transition: border-color .15s; }
.lb-row.lb-clickable:hover { border-color: rgba(0, 229, 195, .45); }
.lb-row.lb-clickable:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.lb-row.open { border-color: var(--accent-2); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.lb-chev { color: var(--muted); font-size: 12px; width: 14px; flex: none; transition: transform .2s; }
.lb-row.open .lb-chev { transform: rotate(180deg); color: var(--accent-2); }
.lb-expand {
  margin-top: -9px; border: 1px solid var(--accent-2); border-top: none;
  border-radius: 0 0 12px 12px; background: var(--bg-2); padding: 14px 18px 16px;
}
.lbx-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.lbx-big { font: 800 22px 'Orbitron', sans-serif; }
.lbx-big small { font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); margin-left: 4px; }
.lbx-sub { color: var(--text-2); font-size: 13px; margin-top: 2px; }
.lbx-chart { display: flex; align-items: flex-end; gap: 4px; height: 120px; margin-top: 16px; }
.lbx-col { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; position: relative; }
.lbx-stack { display: flex; flex-direction: column-reverse; width: 100%; border-radius: 3px 3px 0 0; overflow: hidden; }
.lbx-stack i { display: block; min-height: 1px; }
.lbx-stack i.psn { background: linear-gradient(180deg, #00e5c3, #7c5cff); }
.lbx-stack i.steam { background: var(--steam); }
.lbx-stack i.other { background: var(--muted); }
.lbx-col:hover .lbx-stack { box-shadow: 0 0 12px rgba(0, 229, 195, .6); }
.lbx-col .lbx-tip { display: none; left: 50%; top: -6px; }
.lbx-col:hover .lbx-tip { display: block; }
/* Trou sans aucune date : bande à peine visible, période en infobulle. */
.lbx-gap {
  position: relative; height: 100%; min-width: 0; border-radius: 3px;
  background: repeating-linear-gradient(135deg, rgba(139,147,184,.035) 0 5px, transparent 5px 10px);
  border-bottom: 1px dashed rgba(139,147,184,.28);
}
.lbx-gap .lbx-tip { display: none; left: 50%; top: 40%; }
.lbx-gap:hover { background: repeating-linear-gradient(135deg, rgba(139,147,184,.09) 0 5px, transparent 5px 10px); }
.lbx-gap:hover .lbx-tip { display: block; }
.lbx-axis { display: flex; gap: 4px; margin-top: 5px; color: var(--muted); font: 600 10px 'Rajdhani', sans-serif; }
.lbx-axis span { flex: 1; min-width: 0; text-align: center; white-space: nowrap; overflow: visible; }
.lbx-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.lbx-legend { display: flex; gap: 6px 14px; flex-wrap: wrap; color: var(--muted); font-size: 12px; }
.lbx-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.lbx-legend i.psn { background: linear-gradient(#00e5c3, #7c5cff); }
.lbx-legend i.steam { background: var(--steam); }
.lbx-legend i.other { background: var(--muted); }
.lbx-gran .chip { padding: 4px 10px; font-size: 11.5px; }

/* 2. Classement complet */
.lb-all { margin-top: 12px; }
.lb-all-btn {
  width: 100%; background: var(--panel); border: 1px dashed rgba(120,140,255,.3); border-radius: 12px;
  color: var(--text-2); font: 700 13px 'Rajdhani', sans-serif; padding: 11px; cursor: pointer;
}
.lb-all-btn:hover { border-color: var(--accent-2); color: var(--text); }
.lb-all-btn.lb-all-more { margin-top: 10px; }
.lb-all-tools { display: flex; gap: 10px; align-items: center; margin: 4px 0 4px; flex-wrap: wrap; }
.lb-filter {
  flex: 1; min-width: 200px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font: 600 13px 'Rajdhani', sans-serif; padding: 8px 12px;
}
.lb-count { color: var(--muted); font-size: 12px; }
.lb-rank.small { font-size: 12.5px; width: 30px; }
.lb-row.compact { padding: 6px 16px; }
.lb-row.compact .lb-cover { width: 26px; }

/* 3. Cartes plateforme cliquables + liste des jeux et de leurs trophées */
.platform-trophy-grid { align-items: start; } /* 4. « Afficher plus » n'étire pas les voisines */
.ptc.lb-ptc-clickable { cursor: pointer; transition: border-color .15s; }
.ptc.lb-ptc-clickable:hover { border-color: rgba(0, 229, 195, .45); }
.ptc.lb-ptc-clickable:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.ptc.selected { border-color: var(--accent-2); box-shadow: 0 0 0 1px var(--accent-2) inset; }
.ptc-cta { display: flex; justify-content: space-between; align-items: center; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; }
.ptc-cta span:last-child { font-size: 15px; }
#near-complete-more { margin-top: 2px; }

.tg-panel { margin-top: 16px; background: linear-gradient(160deg, var(--panel-2), var(--panel)); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; }
.tg-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.tg-seg { display: inline-flex; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 3px; }
.tg-seg button { background: none; border: none; color: var(--muted); font: 700 12.5px 'Rajdhani', sans-serif; padding: 6px 12px; border-radius: 7px; cursor: pointer; }
.tg-seg button.on { background: var(--panel-2); color: var(--text); box-shadow: 0 0 0 1px var(--line); }
.tg-head, .tg-row { display: grid; grid-template-columns: 30px minmax(0, 1fr) 210px 150px 20px; gap: 12px; align-items: center; }
.tg-head { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; padding: 14px 8px 6px; border-bottom: 1px solid var(--line); }
.tg-row { padding: 9px 8px; border-bottom: 1px solid var(--line); cursor: pointer; border-radius: 8px; }
.tg-row:hover { background: rgba(124, 92, 255, .08); }
.tg-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
/* Jeu platiné : le même contour néon tournant que les cartes platinées de la
   grille (.card.platinum, --angle et platinum-ring-spin partagés). */
/* Plus fin et plus doux que sur les cartes (retour de Tim : « que ça pète pas
   aux yeux ») — une liste en aligne plusieurs les unes sous les autres. */
.tg-row.platinum { position: relative; margin: 5px 0; border-bottom-color: transparent; box-shadow: 0 0 10px rgba(0, 229, 195, .08); }
.tg-row.platinum::before {
  content: ''; position: absolute; inset: 0; border-radius: 8px;
  padding: 1px; pointer-events: none; opacity: .65;
  background: conic-gradient(from var(--angle), var(--accent), var(--accent-2), var(--gold), var(--accent-2), var(--accent));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: platinum-ring-spin 4s linear infinite;
}
.tg-row.platinum:hover { box-shadow: 0 0 16px rgba(0, 229, 195, .2); }
.tg-row.platinum:hover::before { opacity: 1; }
.tg-game { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tg-game img, .tg-nocover { width: 28px; aspect-ratio: 3/4; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); flex: none; background: var(--bg-2); }
.tg-name { font: 700 13.5px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tg-plat { color: var(--muted); font-size: 11.5px; }
.tg-medals { display: flex; gap: 10px; font: 700 12.5px 'Orbitron', sans-serif; }
.tg-medals span { display: inline-flex; align-items: center; gap: 3px; min-width: 34px; }
.tg-medals span.zero { opacity: .3; }
.tg-medals img { width: 16px; }
.tg-steam { font: 700 13px 'Orbitron', sans-serif; }
.tg-steam small { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.tg-prog { display: flex; align-items: center; gap: 8px; }
.tg-prog .ptc-bar { flex: 1; margin: 0; }
.tg-prog b { font: 700 12px 'Orbitron', sans-serif; color: var(--accent-2); width: 38px; text-align: right; }
.tg-prog b.full { color: var(--gold); }
.tg-go { color: var(--muted); }
.tg-hint { color: var(--muted); font-size: 12px; margin: 10px 0 0; }
@media (max-width: 760px) {
  .tg-head { display: none; }
  .tg-row { grid-template-columns: 24px minmax(0, 1fr) 16px; row-gap: 6px; }
  .tg-row .tg-medals, .tg-row .tg-steam, .tg-row .tg-prog { grid-column: 2 / 3; }
  .lbx-gap { font-size: 9px; }
  .lbx-chart { gap: 2px; }
}

/* Détail par plateforme — PSN (bronze/argent/or/platine), Steam à venir. */
.platform-trophy-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; margin-top: 14px; }
.ptc {
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px;
}
.ptc-head { display: flex; align-items: center; gap: 10px; font: 700 14px 'Orbitron', sans-serif; margin-bottom: 14px; }
.ptc-note { color: var(--muted); font-size: 11.5px; }
/* Barre Steam avec compte + % au bout, plutôt qu'un anneau redondant avec
   celui de PSN (retour de Tim, 2026-08-07) — réutilisée pour l'agrégat
   Leaderboards ET le résumé par jeu (tâche #24). */
.ptc-bar { height: 7px; border-radius: 4px; background: var(--bg-2); border: 1px solid var(--line); margin: 10px 0 4px; position: relative; overflow: hidden; }
.ptc-bar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 4px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.steam-bar-row { display: flex; align-items: center; gap: 14px; padding: 4px 0; }
.steam-bar-row .steam-bar { flex: 1; height: 10px; margin: 0; }
.steam-bar-value { flex: none; font: 800 16px 'Orbitron', sans-serif; color: var(--text); white-space: nowrap; }
.steam-bar-pct { color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; }

/* Rangée de médailles PSN (réutilisée depuis le panneau détail par jeu). */
.trophy-ps-icons { display: flex; gap: 12px; }
.trophy-ps-icon { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.trophy-ps-icon img { width: 44px; height: auto; filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .5)); }
.trophy-ps-icon .cnt { font: 800 13px 'Orbitron', sans-serif; color: var(--text); }
.trophy-ps-icon.zero { opacity: .4; }

/* Top 3 jeux presque à 100% — remplit l'espace libre à droite de la grille
   "Détail par plateforme" (tâche #24). */
.top-pct-list { margin-top: 4px; display: flex; flex-direction: column; gap: 8px; }
.top-pct-row { display: flex; align-items: center; gap: 8px; font: 600 13px 'Rajdhani', sans-serif; }
.tpr-rank { color: var(--muted); font: 800 13px 'Orbitron', sans-serif; width: 16px; flex: none; }
.tpr-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tpr-platform { color: var(--muted); font-weight: 600; flex: none; }
.tpr-pct { font: 700 13px 'Orbitron', sans-serif; flex: none; color: var(--accent-2); }

/* ═══════════════════════════════════════════════════════════════════
   Page Profil (tâche #21) — portée depuis docs/mockups/mockup-profile.html
   ═══════════════════════════════════════════════════════════════════ */
.profile-identity { display: flex; align-items: center; gap: 16px; }
.profile-avatar-wrap { position: relative; flex: none; }
.profile-avatar-lg {
  width: 64px; height: 64px; border-radius: 50%; flex: none;
  background: linear-gradient(140deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font: 800 24px 'Orbitron', sans-serif; color: #0b0d16;
  box-shadow: 0 0 20px rgba(124, 92, 255, .4);
  overflow: hidden;
}
.profile-avatar-lg img { width: 100%; height: 100%; object-fit: cover; }
.profile-avatar-edit {
  position: absolute; bottom: -2px; right: -2px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--text); font-size: 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all .2s;
}
.profile-avatar-edit:hover { border-color: var(--accent); color: var(--accent-2); }
.profile-username { font: 800 19px 'Orbitron', sans-serif; letter-spacing: .3px; color: var(--text); }
.profile-email { font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 3px; }
.profile-since { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .3px; margin-top: 2px; }
/* ═══════════════════════════════════════════════════════════════════
   Page Profil en rubriques (mockup docs/mockups/mockup-profil-rubriques.html,
   piste 2, validée par Tim le 2026-10-05) : un sommaire qui montre l'état de
   chaque rubrique, puis une rubrique à la fois.
   ═══════════════════════════════════════════════════════════════════ */
.pf-page { max-width: 820px; margin: 0 auto; padding-bottom: 40px; }   /* centrée : une colonne de réglages, pas une page pleine largeur */
.pf-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
.pf-head .section-title { flex: 1; border: none; margin: 0; padding: 0; }
.pf-head-btn {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; padding: 6px 13px; cursor: pointer; transition: all .18s;
}
.pf-head-btn:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.pf-head-btn .ico { width: 15px; height: 15px; margin: 0; color: var(--accent-2); }
.pf-head-lbl { margin-left: 6px; }

/* Sommaire */
.pf-ident {
  display: flex; align-items: center; gap: 16px; width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
  padding: 18px 20px; background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); transition: border-color .18s;
}
.pf-ident:hover { border-color: rgba(124, 92, 255, .45); }
.pf-ident-av {
  width: 48px; height: 48px; border-radius: 50%; flex: none; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg, var(--accent), var(--accent-2));
  font: 800 18px 'Orbitron', sans-serif; color: #0b0d16;
}
.pf-ident-av img { width: 100%; height: 100%; object-fit: cover; }
.pf-ident-txt { flex: 1; min-width: 0; }
.pf-ident-txt .nm { display: block; font: 800 18px 'Orbitron', sans-serif; letter-spacing: .3px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-ident-txt .meta { display: block; font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 3px; }
.pf-group { font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted); margin: 20px 4px 8px; }
.pf-list { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.pf-row {
  display: flex; align-items: center; gap: 14px; width: 100%; padding: 14px 18px;
  background: none; border: 0; color: inherit; text-align: left; font: inherit; cursor: pointer; transition: background .16s;
}
.pf-row + .pf-row { border-top: 1px solid var(--line); }
.pf-row:hover { background: rgba(124, 92, 255, .07); }
.pf-row-ic {
  width: 36px; height: 36px; flex: none; border-radius: 10px; display: grid; place-items: center;
  color: var(--accent-2); background: rgba(124, 92, 255, .12); border: 1px solid rgba(124, 92, 255, .3);
}
.pf-row-ic .ico { width: 18px; height: 18px; margin: 0; }
.pf-row-txt { flex: 1; min-width: 0; }
.pf-row-txt .t { display: block; font: 700 15.5px 'Rajdhani', sans-serif; color: var(--text); }
.pf-row-txt .s { display: block; font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-row-txt .s:empty { display: none; }
.pf-row-txt .s b { color: var(--text-2); font-weight: 700; }
.pf-ok { color: var(--accent-2); }
.pf-warn { color: var(--gold); }
.pf-bad { color: var(--danger); }
.pf-go { width: 18px; height: 18px; flex: none; color: var(--muted); }
.pf-ident:focus-visible, .pf-row:focus-visible, .pf-back:focus-visible, .pf-link:focus-visible, .pf-logout:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* Centré et en rouge (demande de Tim, 2026-10-05) : c'est le seul « Se déconnecter » de l'app. */
.pf-logout {
  display: flex; align-items: center; justify-content: center; margin: 26px auto 0; cursor: pointer;
  background: none; border: 1px solid rgba(255, 84, 112, .45); border-radius: 999px; padding: 9px 26px;
  color: var(--danger); font: 700 14px 'Rajdhani', sans-serif; letter-spacing: .3px; transition: background .18s, border-color .18s;
}
.pf-logout:hover { background: rgba(255, 84, 112, .1); border-color: var(--danger); }

/* Une rubrique */
.pf-back { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; padding: 0; margin-bottom: 12px; color: var(--muted); font: 700 14px 'Rajdhani', sans-serif; cursor: pointer; }
.pf-back:hover { color: var(--text); }
.pf-back .ico { width: 16px; height: 16px; margin: 0; }
.pf-rb-title { font: 700 17px 'Orbitron', sans-serif; letter-spacing: .8px; margin: 0; color: var(--text); }
.pf-rb-sub { color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; margin: 4px 0 14px; }
.pf-card { background: linear-gradient(160deg, var(--panel-2), var(--panel)); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.pf-card + .pf-card { margin-top: 12px; }
.pf-card.danger { border-color: rgba(255, 84, 112, .35); background: var(--panel); }
.pf-card .fr-toggle-row:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.pf-card .fr-toggle-text .d { font-size: 13px; }
.pf-card .chip.danger { border-color: rgba(255, 84, 112, .5); color: var(--danger); }
.pf-field { margin-top: 16px; }
.pf-field > label { display: block; font: 700 14px 'Rajdhani', sans-serif; color: var(--text); margin-bottom: 6px; }
.pf-field .edit-input-row { max-width: 420px; }
.pf-hint { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; line-height: 1.5; margin: 8px 0 0; }
.pf-hint-sep { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.pf-link { background: none; border: 0; padding: 0; cursor: pointer; color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; }
.pf-link.danger { color: var(--danger); }
.pf-shared { margin-top: 12px; }
.pf-shared summary { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; list-style: none; }
.pf-shared summary::-webkit-details-marker { display: none; }
.pf-caret { width: 14px; height: 14px; margin: 0; transition: transform .15s; }
.pf-shared[open] .pf-caret { transform: rotate(90deg); }
.pf-invite-link { margin: 6px 0 0; font: 600 12.5px 'Rajdhani', sans-serif; color: var(--muted); overflow-wrap: anywhere; }
.pf-invite-link code { color: var(--text-2); }
/* Une ligne de réglage : libellé + valeur à gauche, actions à droite. */
.pf-line { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
.pf-line + .pf-line, .pf-extra + .pf-line, .login-status + .pf-line, .login-status + .pf-mfa, .pf-line + .pf-mfa { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.pf-line .lt { flex: 1; min-width: 180px; }
.pf-line .t { display: flex; align-items: center; gap: 8px; font: 700 14.5px 'Rajdhani', sans-serif; color: var(--text); }
.pf-line .v { font: 600 13.5px 'Rajdhani', sans-serif; color: var(--text-2); margin-top: 2px; line-height: 1.45; }
.pf-line .t .ico { width: 18px; height: 18px; margin: 0; }
.pf-plat { display: inline-flex; }
.pf-plat.steam { color: var(--steam); }
.pf-plat.psn { color: var(--psn); }
.pf-danger-t { color: var(--danger) !important; }
.pf-extra { display: grid; gap: 8px; max-width: 440px; margin-top: 12px; }
.pf-card .login-status:empty { display: none; }
.pf-card .login-status { margin-top: 8px; }

@media (max-width: 700px) {
  .pf-page { padding-left: 16px; padding-right: 16px; }
  .pf-head-lbl { display: none; }   /* le guide en icône seule : l'en-tête tient sur une ligne */
  .pf-head .section-title { font-size: 17px; }
  .pf-ident { padding: 14px 16px; }
  .pf-ident-txt .nm { font-size: 16px; }
  .pf-row { padding: 13px 14px; }
  .pf-card { padding: 16px; }
  .pf-card .lg-cards { grid-template-columns: 1fr; }
}

/* ── Pied de page (retour de Tim, mockup validé docs/mockups/mockup-footer.html,
   inspiré de docs/HLTB bottom pane.png et docs/PS_Timetracker_bottom pane.png) */
.site-footer {
  border-top: 1px solid var(--line); margin-top: 40px;
  /* padding-bottom hérite de l'ancien padding-bottom:80px de body (retiré) —
     la clairière pour .timer-widget/.bulk-bar (position:fixed, bottom:20px)
     doit rester quelque part, mais en couleur de fond du footer plutôt qu'en
     bande vide après lui, sinon la bannière "ne prend pas tout le bas"
     (retour de Tim). */
  padding: 28px 32px 100px; background: var(--bg-2);
}
.site-footer-grid {
  display: grid; grid-template-columns: 1.3fr 1.7fr 1fr; gap: 28px;
  width: 100%;
}
.site-footer h4 {
  font: 700 13px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--text); margin: 0 0 10px;
}
.site-footer-brand { font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: 19px; letter-spacing: 1.5px; color: var(--text); margin-bottom: 8px; }
.site-footer-brand .accent { color: var(--accent); }
.site-footer p { color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; line-height: 1.6; margin: 0 0 6px; }
.site-footer a { color: var(--accent-2); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
.site-footer-links { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
/* Bouton plutôt que <a href="#"> pour "Changelog & roadmap" — navigation
   SPA (switchView), pas un vrai lien ; même style que les <a> du footer. */
.site-footer-link {
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  color: var(--accent-2); font: 500 14px 'Rajdhani', sans-serif; text-decoration: none;
}
.site-footer-link:hover { text-decoration: underline; }
.site-footer a { font-size: 14px; }
.site-footer-bottom {
  width: 100%; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
  color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; text-align: center; letter-spacing: .3px;
}
@media (max-width: 760px) {
  .site-footer { padding-left: 16px; padding-right: 16px; }
  .site-footer-grid { grid-template-columns: 1fr; gap: 18px; }
}

/* ── Changelog & Roadmap, en overlay (retour de Tim, 2026-08-09, mockup
   validé docs/mockups/mockup-info-overlay.html) ───────────────────────
   Même mécanique que .detail (panneau jeu) : fond flouté plein écran,
   boîte centrée avec défilement interne, fermeture au clic dehors ou à
   Échap (voir wireInfoOverlay() dans app.js). Contenu écrit et tenu à
   jour à la main, comme le journal docs/journal/ — pas de source
   dynamique derrière. */
.info-overlay {
  position: fixed; inset: 0; z-index: 310;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .55); backdrop-filter: blur(20px);
  animation: fade .3s both;
}
.info-overlay-inner {
  width: min(760px, 92vw); max-height: min(820px, 88vh);
  overflow-y: auto;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .3); border-radius: 20px;
  padding: 32px 36px 36px;
  /* PAS `both` (bug 2026-08-28, écran ultra-large) : un fill-mode qui tient
     `forwards` garde l'animation "en effet" indéfiniment, donc son `transform`
     (même `none` en keyframe finale — Chrome le calcule en `matrix(1,0,0,1,0,0)`
     tant que l'animation reste active) fait de cet élément un bloc de
     confinement permanent pour ses descendants `position:fixed`. #info-tabs,
     enfant direct pour la mécanique sticky mobile (voir plus bas), se
     retrouvait alors positionné depuis CETTE boîte plutôt que le viewport —
     ses 400px de décalage calculés sortaient de la largeur du panneau (760px)
     et se faisaient couper par cet `overflow-y:auto`, invisibles. Sans
     `both`, l'animation cesse d'être "en effet" à .32s et redonne la main aux
     styles de base (opacity/transform non déclarés ici = 1/none par défaut,
     identiques à la keyframe finale — aucun changement visuel).*/
  animation: modal-in .32s cubic-bezier(.2, .8, .3, 1);
  position: relative;
}
.info-overlay-close {
  position: absolute; top: 18px; right: 18px; z-index: 2;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: 16px; width: 32px; height: 32px; cursor: pointer;
  transition: all .2s;
}
.info-overlay-close:hover { color: var(--text); border-color: var(--accent); }
/* .an-section a son propre padding horizontal de 32px, pensé pour la
   pleine largeur du dashboard — inutile ici, .info-overlay-inner a déjà
   son padding. */
.info-overlay-inner .an-section { padding-left: 0; padding-right: 0; }

/* ── Onglets Guide/Changelog/Roadmap — barre du haut, collée au défilement,
   ✕ à droite (retour de Tim, 2026-09-28, mockup
   docs/mockups/mockup-onglets-haut-final.html). Même barre et même style
   d'onglet que la fiche d'un jeu (.tabs-bar, plus haut) ; remplace les 3
   boutons flottants à droite du panneau (2026-08-18) et leurs deux replis
   (rangée sous 1140 px, resserrée sous 400 px). Un seul onglet visible à la
   fois — Guide au démarrage (voir openInfoOverlay() dans app.js). ────────── */
.info-bar { top: -32px; margin: -32px -36px 24px; padding: 0 16px 0 36px; border-radius: 20px 20px 0 0; }
.info-bar .info-overlay-close { position: static; flex: none; }
.info-tab-icon { font-size: 15px; }

.info-pane { display: none; }
.info-pane.active { display: block; }

@media (max-width: 600px) {
  .info-bar { padding: 0 12px 0 20px; }
  .info-bar .tb-tabs { gap: 18px; }
  .info-tab-icon { display: none; }
}

/* ── Popup "jeux non identifiés" (mockup mockup-unmatched-games.html, retour
   de Tim) — même mécanique que .info-overlay : fond flouté, boîte centrée,
   fermeture au clic dehors/✕/Échap (voir wireUnmatchedOverlay() dans app.js).
   Chaque ligne propose une suggestion IGDB (recherche sur le nom simplifié),
   jamais appliquée automatiquement. ───────────────────────────────────── */
.review-overlay {
  position: fixed; inset: 0; z-index: 310;
  display: flex; align-items: center; justify-content: center;
  background: rgba(5, 6, 12, .55); backdrop-filter: blur(20px);
  animation: fade .3s both;
}
.review-inner {
  width: min(600px, 92vw); max-height: min(640px, 85vh); overflow-y: auto;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .3); border-radius: 20px;
  padding: 30px 32px 26px; position: relative;
  animation: modal-in .32s cubic-bezier(.2, .8, .3, 1) both;
}
.review-close {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: 16px; width: 32px; height: 32px; cursor: pointer;
  transition: all .2s;
}
.review-close:hover { color: var(--text); border-color: var(--accent); }
.review-inner h2 { font: 700 18px 'Orbitron', sans-serif; color: var(--text); margin: 0 0 8px; padding-right: 30px; }
.review-sub { color: var(--muted); font: 500 13px 'Rajdhani', sans-serif; line-height: 1.5; margin: 0 0 20px; }
.review-list { display: flex; flex-direction: column; gap: 10px; }
.review-row {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px;
}
.review-row-raw {
  display: flex; align-items: center; gap: 7px;
  color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-bottom: 8px;
}
.review-row-raw .platform-ic { font-size: 12px; }
.review-row-suggestion { display: flex; align-items: center; gap: 10px; }
.review-row-cover { width: 32px; height: 45px; border-radius: 4px; object-fit: cover; flex: none; background: var(--panel); }
.review-row-cover-empty {
  width: 32px; height: 45px; border-radius: 4px; flex: none;
  background: var(--panel); border: 1px dashed var(--line);
  display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 14px;
}
.review-row-name { flex: 1; min-width: 0; font: 700 13.5px 'Rajdhani', sans-serif; color: var(--text); }
.review-row-name .none { color: var(--muted); font-weight: 500; font-style: italic; }
.review-row-actions { flex: none; display: flex; gap: 6px; }
.review-row-actions button {
  background: none; border: 1px solid var(--line); border-radius: 7px;
  color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; letter-spacing: .2px;
  padding: 6px 9px; cursor: pointer; transition: all .15s; white-space: nowrap;
}
.review-row-actions button:hover { color: var(--text); border-color: var(--accent); }
.review-confirm-btn {
  background: linear-gradient(120deg, var(--accent), var(--accent-2)) !important;
  color: #0b0d16 !important; border: none !important; font-weight: 700 !important;
}
.review-confirm-btn:hover { filter: brightness(1.08); }
.review-row-actions .review-ignore-btn:hover { color: var(--danger); border-color: var(--danger); }
.review-footnote { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; margin-top: 16px; font-style: italic; }

/* ── Onglets du panneau "À revoir" (esquisse t4, mockup
   mockup-review-panel.html, retour de Tim 2026-08-20) — même recette que les
   anciennes colonnes flottantes de la fiche et du menu Info (toutes deux
   passées en barre du haut le 2026-09-28 ; celle-ci est restée telle quelle) :
   .review-with-tabs met .review-inner et les boutons dans une même rangée
   flex centrée, pour que les boutons suivent le panneau quelle que soit la
   largeur de fenêtre (repris directement en flexbox, sans repasser par le
   calcul en pixels fixes qui avait envoyé les boutons hors-écran la
   première fois qu'on l'a tenté sur le panneau détail). Seuil de repli à
   900px : ce panneau (600px) est plus étroit que la fiche d'un jeu
   (jusqu'à 1680px) mais un peu plus large que le menu Info (760px). ───── */
.review-with-tabs { display: flex; align-items: center; gap: 20px; max-width: 100%; }
.review-tabs-floating { flex: none; display: flex; flex-direction: column; gap: 10px; }
.review-tab-btn {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  background: var(--panel-2); border: 1px solid rgba(124, 92, 255, .4); border-radius: 999px;
  color: var(--muted); font: 700 12px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: uppercase;
  padding: 9px 16px; cursor: pointer;
  box-shadow: 0 10px 24px rgba(0, 0, 0, .4), 0 0 18px rgba(124, 92, 255, .15);
  transition: all .2s;
}
.review-tab-btn:hover { color: var(--text); border-color: rgba(124, 92, 255, .7); }
.review-tab-btn.active {
  background: linear-gradient(120deg, rgba(124, 92, 255, .3), rgba(0, 229, 195, .15));
  border-color: var(--accent); color: var(--text);
}
.review-tab-count { background: rgba(124, 92, 255, .25); border-radius: 999px; padding: 1px 7px; font-size: 10.5px; }
@media (max-width: 900px) {
  .review-with-tabs { flex-direction: column; gap: 0; }
  .review-tabs-floating {
    flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 8px; order: -1;
    background: var(--panel-2); padding: 10px 16px; margin-bottom: 14px;
    border-bottom: 1px solid var(--line); width: 100%; border-radius: 20px 20px 0 0;
  }
  .review-tab-btn { padding: 6px 12px; font-size: 10.5px; box-shadow: none; }
}
.review-pane { display: none; }
.review-pane.active { display: block; }
/* Ligne "référence aberrante" : le chiffre en cause, mis en avant. */
.review-row-stat { color: var(--gold); font-weight: 700; }
/* Ligne "doublon potentiel" : les 2 jeux en cause l'un sous l'autre dans la
   même .review-row (plutôt qu'un côte-à-côte qui écraserait les jaquettes
   sur 600px de large). */
.review-row-dup + .review-row-dup { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }

.changelog-list { margin-top: 4px; }
.changelog-date {
  color: var(--muted); font: 700 11px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: 1.6px;
  margin: 20px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.changelog-date:first-child { margin-top: 4px; }
.changelog-entry {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 7px 0; font: 500 13.5px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.5;
}
.changelog-tag {
  flex: none; width: 86px; text-align: center;
  margin-top: 1px; border-radius: 999px; font: 700 10px 'Rajdhani', sans-serif;
  letter-spacing: .6px; text-transform: uppercase; padding: 3px 9px; border: 1px solid;
}
.changelog-tag.new { color: var(--accent-2); border-color: rgba(0, 229, 195, .5); background: rgba(0, 229, 195, .08); }
.changelog-tag.improve { color: var(--accent); border-color: rgba(124, 92, 255, .5); background: rgba(124, 92, 255, .08); }
.changelog-tag.fix { color: #b9c2ee; border-color: rgba(148, 157, 240, .4); background: rgba(148, 157, 240, .08); }
.changelog-note { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; margin-top: 16px; font-style: italic; }

.roadmap-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin-top: 4px;
}
.roadmap-item {
  display: flex; align-items: center; gap: 14px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px;
}
.roadmap-icon {
  width: 38px; height: 38px; flex: none; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
  background: rgba(124, 92, 255, .12); border: 1px solid rgba(124, 92, 255, .3);
}
.roadmap-title { font: 700 13.5px 'Rajdhani', sans-serif; color: var(--text); }
.roadmap-desc { font: 500 12px 'Rajdhani', sans-serif; color: var(--text-2); margin-top: 2px; line-height: 1.4; }

/* ═══════════════════════════════════════════════════════════════════
   Résumé + liste détaillée des trophées/succès par jeu (tâche #24) —
   panneau détail, onglet Aperçu (résumé) + onglet Trophées (liste).
   ═══════════════════════════════════════════════════════════════════ */
.trophy-ps-card { display: flex; align-items: center; justify-content: flex-start; gap: 22px; flex-wrap: wrap; padding: 6px 0; }
.trophy-ps-top { display: flex; align-items: center; gap: 10px; flex: none; }
.trophy-ps-count { text-align: center; }
.trophy-ps-count .n { font: 800 17px 'Orbitron', sans-serif; color: var(--text); }
.trophy-ps-count .l { color: var(--muted); font: 600 8.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .6px; margin-top: 1px; white-space: nowrap; }
.trophy-ps-ring { position: relative; width: 48px; height: 48px; flex: none; }
.trophy-ps-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
/* Carte PSN de la page Leaderboards : centrée (contrairement au résumé par
   jeu, aligné à gauche dans une colonne étroite) et un peu plus grande —
   retour de Tim, 2026-08-07. La règle .ptc .trophy-ps-card{justify-content}
   manquait entièrement jusqu'ici (jamais ajoutée malgré le commentaire qui
   la présumait déjà là), d'où le rendu non centré signalé. */
.ptc .trophy-ps-card { justify-content: center; padding: 14px 0; }
.ptc .trophy-ps-icon img { width: 52px; }
.ptc .trophy-ps-ring { width: 58px; height: 58px; }
.ptc .trophy-ps-count .n { font-size: 19px; }
.trophy-ps-ring .pct {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font: 800 10px 'Orbitron', sans-serif; color: var(--text);
}
.trophy-platform-label {
  color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: 1.4px; margin: 12px 0 6px;
}
.trophy-platform-label:first-child { margin-top: 0; }

.trophy-list { display: flex; flex-direction: column; margin-top: 6px; }
.trophy-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--line); }
.trophy-row:last-child { border-bottom: none; }
.trophy-row.not-earned { opacity: .42; }
.trophy-row .tr-icon { width: 38px; height: 38px; flex: none; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.trophy-row .tr-icon img { width: 38px; height: 38px; object-fit: cover; border-radius: 5px; }
/* Icône indisponible chez la plateforme (constaté sur Wardogs le 2026-09-20 :
   Steam publie une adresse morte) : carré neutre plutôt qu'une image cassée.
   Le repli est posé à l'affichage, jamais en base — si l'adresse remarche, la
   vraie icône revient d'elle-même. */
.trophy-row .tr-icon-fallback { display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 5px; background: var(--bg-2);
  border: 1px solid var(--line); font-size: 17px; color: var(--muted); }
.trophy-row .tr-tier-icon { width: 20px; height: auto; flex: none; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .5)); }
.trophy-row .tr-name { flex: 1; min-width: 0; font: 600 13px 'Rajdhani', sans-serif; }
.trophy-row .tr-date { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; flex: none; }
.trophy-row .tr-rarity { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; flex: none; width: 46px; text-align: right; }
.trophy-row.with-desc { align-items: flex-start; }
.trophy-row.with-desc .tr-icon { margin-top: 1px; }
/* Palier et date centrés verticalement sur la ligne, le nom et la description
   restant en haut (demande de Tim, 2026-09-28, mockup
   mockup-guide-powerpyx-page.html) — ils étaient calés en haut avec eux. */
.trophy-row.with-desc .tr-tier-icon,
.trophy-row.with-desc .tr-date { align-self: center; }
.tr-name-col { flex: 1; min-width: 0; }
.tr-desc { color: var(--text-2); font: 600 11px 'Rajdhani', sans-serif; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Guide PowerPyx (PlayStation, 2026-09-28) — mockups
   mockup-guide-powerpyx-page.html (liens), mockup-platine-powerpyx-final.html
   (bloc Platine, bandeau, étiquette, alerte) et mockup-guide-bouton-placement.html
   (bouton dans le bloc, variante 2). ─────────────────────────────────────── */
.tro-guide-btn {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 6px 12px; border-radius: 999px; border: 1px solid rgba(124, 92, 255, .55);
  background: rgba(124, 92, 255, .10); color: var(--text); text-decoration: none;
  font: 700 12.5px 'Rajdhani', sans-serif; letter-spacing: .3px;
}
.tro-guide-btn:hover { background: rgba(124, 92, 255, .22); }

/* Un trophée non obtenu reste délavé, mais pas son lien « Guide ↗ » ni son
   étiquette « manquable » : une opacité posée sur la ligne s'appliquerait à
   eux aussi, sans moyen de l'annuler dessous — on délave donc ses éléments un
   par un. */
.trophy-row.not-earned:is(.has-guide, .is-missable) { opacity: 1; }
.trophy-row.not-earned:is(.has-guide, .is-missable) :is(.tr-icon, .tr-name, .tr-desc, .tr-tier-icon, .tr-date) { opacity: .42; }
.tr-guide {
  flex: none; align-self: center; color: var(--accent); text-decoration: none;
  font: 700 11.5px 'Rajdhani', sans-serif; padding: 3px 7px; border-radius: 6px; border: 1px solid transparent;
}
/* Largeur fixe partagée avec l'emplacement vide des lignes sans lien, pour que
   palier et date restent en colonne. */
.tr-guide, .tr-guide-slot { width: 58px; box-sizing: border-box; text-align: center; }
.tr-guide-slot { flex: none; }
.tr-guide:hover { border-color: rgba(124, 92, 255, .5); background: rgba(124, 92, 255, .10); }

/* Étiquette « manquable » à côté du nom (seulement sur ce qui reste à faire). */
.tr-name-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.tr-name-line .tr-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mis-tag {
  flex: none; padding: 0 6px; border-radius: 5px;
  border: 1px solid rgba(255, 185, 56, .55); color: var(--gold);
  font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase;
}

/* Source d'une donnée tierce, à côté de son libellé (« · PowerPyx »). */
.src { color: var(--muted); font: 600 10.5px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: uppercase; }

/* Barre « platine » dans la référence IGDB : une plage (borne basse → borne
   haute) sur la même échelle que les repères ; « 300+ » se prolonge en dégradé. */
.ttb-row.plat > span:first-child { color: var(--gold); }
.ttb-row-fill.range { background: linear-gradient(90deg, rgba(255, 185, 56, .55), var(--gold)); }
.ttb-row-fill.range.open::after {
  content: ''; position: absolute; right: -10px; top: 0; bottom: 0; width: 10px;
  background: linear-gradient(90deg, var(--gold), transparent);
}

/* Bloc « 🏆 Platine » en tête de l'onglet Trophées, bouton du guide en haut à droite. */
.plat-guide { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.plat-guide .hint { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; }
/* Jeu Steam sans version PlayStation : le bouton du guide seul, à droite. */
.steam-guide { display: flex; justify-content: flex-end; margin: 0 0 10px; }
.plat-empty { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin: -6px 0 6px; }
.plat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; margin: 0 0 12px; }
.plat-tile { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 10px 8px; text-align: center; }
.plat-tile .v { font: 700 16px 'Orbitron', sans-serif; color: var(--text); white-space: nowrap; }
.plat-tile .v.plat-warn { color: var(--gold); }
.plat-tile .l { color: var(--muted); font: 600 10.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .8px; margin-top: 3px; }
@media (max-width: 520px) { .plat-tiles { grid-template-columns: repeat(2, 1fr); } }

.missables { border: 1px solid rgba(255, 185, 56, .35); background: rgba(255, 185, 56, .06); border-radius: 12px; padding: 10px 12px; margin: 4px 0; }
.missables summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; font: 700 13px 'Rajdhani', sans-serif; color: var(--text); }
.missables summary::-webkit-details-marker { display: none; }
.missables summary .count { color: var(--gold); }
.missables summary .done { color: var(--muted); font-weight: 600; }
.missables summary .chev { margin-left: auto; color: var(--muted); transition: transform .2s; }
.missables[open] summary .chev { transform: rotate(180deg); }
.mis-list { margin-top: 8px; display: flex; flex-direction: column; }
.mis-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; border-top: 1px dashed var(--line); font: 600 13px 'Rajdhani', sans-serif; }
.mis-row .st { width: 18px; text-align: center; flex: none; }
.mis-row .st img { width: 16px; height: auto; display: block; margin: 0 auto; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .5)); }
.mis-row.ok { color: var(--muted); }
.mis-row.ok .name { text-decoration: line-through; text-decoration-color: rgba(139, 147, 184, .5); }
.mis-row .name { flex: 1; min-width: 0; }
.mis-row a { color: var(--accent); text-decoration: none; font: 700 11.5px 'Rajdhani', sans-serif; }
.mis-row.mis-more { color: var(--muted); font-weight: 600; font-size: 12px; }

/* Bandeau « N trophées manquables à faire » dans « Trophées & succès » (Aperçu). */
.mis-banner {
  display: flex; align-items: center; gap: 10px; cursor: pointer; text-decoration: none;
  margin: 6px 0 10px; padding: 8px 12px; border-radius: 10px;
  border: 1px solid rgba(255, 185, 56, .35); background: rgba(255, 185, 56, .07);
  color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif;
}
.mis-banner:hover { background: rgba(255, 185, 56, .13); }
.mis-banner:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.mis-banner .mis-ico, .mis-banner b { color: var(--gold); }
.mis-banner .go { margin-left: auto; color: var(--accent); font-weight: 700; white-space: nowrap; }
.info-underline { border-bottom: 1px dotted var(--muted); cursor: help; }

/* Lien "Voir le détail complet" (résumé Aperçu -> onglet Trophées) — jamais
   stylé jusqu'ici (oublié à l'implémentation, rendu en lien bleu par défaut
   du navigateur), repéré par Tim en comparant au mockup (accent-2 néon). */
.trophy-goto {
  display: inline-block; margin-top: 8px; color: var(--accent-2);
  font: 700 12px 'Rajdhani', sans-serif; text-decoration: none; cursor: pointer;
}
.trophy-goto:hover { text-decoration: underline; }

/* ── Trophées PSN par groupe (2026-09-30, mockup mockup-trophees-par-groupe.html,
   variante A) : jeu principal puis contenus ajoutés, une section repliable
   chacun, sa progression dans l'en-tête. Le @media reste APRÈS ces règles. ── */
.tg-note { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; margin: 2px 0 12px; }
.tg-note b { color: var(--text); }
/* Icône de groupe : carrée sur PS5 (512 px), en bandeau sur PS4 (320×176) —
   hauteur fixe, largeur selon l'image, jamais recadrée. */
.tg-icon { height: 40px; width: auto; max-width: 73px; border-radius: 8px; flex: none;
  border: 1px solid var(--line); background: var(--bg-2); }
.tg-tag { display: inline-block; padding: 1px 7px; border-radius: 6px; vertical-align: 2px; margin-left: 6px;
  font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; }
.tg-tag.main { border: 1px solid rgba(255, 185, 56, .55); color: var(--gold); }
.tg-tag.off { border: 1px solid var(--line); color: var(--muted); }
.tg-prog { display: flex; align-items: center; gap: 10px; flex: none; }
.tg-frac { font: 700 13px 'Orbitron', sans-serif; color: var(--text); white-space: nowrap; }
.tg-frac small { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-left: 2px; }
.tg-bar { width: 90px; height: 6px; border-radius: 999px; background: var(--bg); overflow: hidden; }
.tg-bar > i { display: block; height: 100%; border-radius: inherit; background: var(--accent-2); }
.tg-bar.main > i { background: linear-gradient(90deg, rgba(255, 185, 56, .6), var(--gold)); }
.tg-tiers { display: flex; gap: 7px; }
.tg-tiers span { display: inline-flex; align-items: center; gap: 2px; color: var(--muted); font: 700 11.5px 'Rajdhani', sans-serif; }
.tg-tiers img { width: 13px; height: auto; }
.tg-section { border: 1px solid var(--line); border-radius: 12px; background: rgba(18, 21, 35, .55); margin-bottom: 10px; }
.tg-section.main { border-color: rgba(255, 185, 56, .28); }
.tg-section > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 12px; }
.tg-section > summary::-webkit-details-marker { display: none; }
.tg-section > summary:hover { background: rgba(124, 92, 255, .07); }
.tg-section > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tg-title { flex: 1; min-width: 0; }
.tg-name { font: 700 15px 'Rajdhani', sans-serif; color: var(--text); white-space: normal; line-height: 1.25; }
.tg-sub { margin-top: 3px; }
.tg-chev { color: var(--muted); transition: transform .2s; flex: none; }
.tg-section[open] .tg-chev { transform: rotate(180deg); }
.tg-section .trophy-list { padding: 0 10px 8px; }
/* Étroit : icône | nom (sur deux lignes si besoin) | chevron, puis la
   progression sur toute la largeur. */
@media (max-width: 560px) {
  .tg-section > summary { display: grid; grid-template-columns: auto 1fr auto; column-gap: 10px; row-gap: 8px; }
  .tg-section > summary:not(:has(.tg-icon)) { grid-template-columns: 1fr auto; }
  .tg-icon { height: 32px; max-width: 58px; }
  .tg-prog { grid-column: 1 / -1; grid-row: 2; }
  .tg-bar { flex: 1; }
}

/* ── Section "Mises à jour" (tâche P1 patch notes, panneau détail — mockup
   validé docs/mockups/mockup-patch-notes.html, retour de Tim 2026-08-31).
   Un seul traitement, toujours identique (pas de phrase "depuis ta dernière
   partie" — la v1 avait 3 formulations selon la précision de la session
   connue, jugée confuse). Repris tel quel du mockup, classes identiques.
   Vit désormais dans l'onglet "🗞 Actualité" (2026-09-09), pas dans Aperçu —
   voir la section "Presse" juste en dessous. ── */
.patch-notes-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.patch-notes-head h3 { margin: 0; }
.patch-notes-count {
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16;
  font: 800 11px 'Orbitron', sans-serif; padding: 3px 10px; border-radius: 999px; flex: none;
}
.patch-note-item { padding: 12px 0; border-top: 1px solid var(--line); }
.patch-note-item:first-of-type { border-top: none; padding-top: 10px; }
.patch-note-item-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.patch-note-title { color: var(--text); font: 700 14px 'Rajdhani', sans-serif; }
.patch-note-date { color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.patch-note-excerpt { color: var(--text-2); font-size: 13px; line-height: 1.5; margin: 6px 0 8px; }
.patch-note-link { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; text-decoration: none; }
.patch-note-link:hover { text-decoration: underline; }
/* Grosse mise à jour (mockup validé docs/mockups/mockup-grosses-maj.html,
   2026-09-25) — le type d'événement que l'éditeur pose sur son annonce
   Steam (14 = majeure, game_patch_notes.steam_event_type). Chip en contour
   turquoise plutôt qu'en fond plein : plus visible qu'un .editor-promo-tag
   en --muted (c'est un signal positif), moins criard que .nf-new en fond
   plein, qui garde son rôle de "pas encore vu". Comme .editor-promo-tag,
   ça ne masque rien et ne remonte rien — le tri reste neutre.
   Le liseré (variante B, choisie par Tim) permet de repérer la ligne en
   balayant la liste sans lire les chips : ~1 majeure pour 15 annonces
   mesurées, il reste donc rare. */
.pn-major-tag {
  display: inline-block; margin-left: 8px; font: 800 9.5px 'Orbitron', sans-serif;
  letter-spacing: .6px; text-transform: uppercase; color: var(--accent-2);
  border: 1px solid rgba(0,229,195,.45); border-radius: 999px; padding: 2px 8px;
  vertical-align: 1px;
}
.patch-note-item.pn-major {
  border-left: 2px solid var(--accent-2); padding-left: 11px;
  background: linear-gradient(90deg, rgba(0,229,195,.055), transparent 45%);
}
/* "Dernière grosse mise à jour" (option C) : la fiche ne montre que les 3
   dernières annonces, or une saison peut dater de plusieurs mois — celle
   d'ARC Raiders avait 5 mois et six petites mises à jour derrière elle.
   Épinglée en 4e ligne, et seulement si aucune des 3 n'est déjà majeure. */
.pn-pinned-label {
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 -2px;
}

/* ── Section "Annonces éditeur" (mockup validé
   docs/mockups/mockup-editor-announcements.html, retour de Tim
   2026-09-10) — ce que le tri patch notes écarte côté Steam (ni tag
   patchnotes, ni repli mots-clés) mais reste récent (~4 mois côté
   backend, ingest_patch_notes). Gabarit visuel proche de .patch-note-*
   (même famille "officiel développeur"), compteur --muted comme "Presse"
   plutôt que le badge dégradé des Mises à jour — ce n'est pas un patch.
   .editor-promo-tag ne masque rien (retour de Tim : "ça garde le tri
   neutre") — juste un repère visuel calculé côté backend
   (is_promo, backend/patch_notes.py:_FALLBACK_EXCLUDE_RE). */
.editor-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.editor-head h3 { margin: 0; }
.editor-count { color: var(--muted); font: 700 12px 'Rajdhani', sans-serif; }
.editor-item { padding: 12px 0; border-top: 1px solid var(--line); }
.editor-item:first-of-type { border-top: none; padding-top: 10px; }
.editor-item-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.editor-title { color: var(--text); font: 700 14px 'Rajdhani', sans-serif; }
.editor-meta { color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.editor-link { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; text-decoration: none; }
.editor-link:hover { text-decoration: underline; }
.editor-promo-tag {
  display: inline-block; margin-left: 8px; font: 700 9.5px 'Rajdhani', sans-serif;
  letter-spacing: .4px; text-transform: uppercase; color: var(--muted);
  border: 1px dashed var(--line); border-radius: 999px; padding: 1px 7px;
}
/* "Montrer plus" (retour de Tim : "ça fait beaucoup quand il y a plus de
   3 annonces") — 3 items visibles par défaut (EDITOR_ANNOUNCEMENTS_VISIBLE,
   app.js), le reste masqué jusqu'au clic (.editor-item-extra-visible
   ajoutée/retirée en JS). .wl-load-more réutilisé tel quel pour le
   bouton, déjà en prod pour "Charger plus" sur la Wishlist Steam. */
.editor-item-extra { display: none; }
.editor-item-extra.editor-item-extra-visible { display: block; }
.editor-more-row { display: flex; justify-content: center; margin-top: 4px; }

/* ── Section "Presse" (tâche P2 actualité, panneau détail — mockup validé
   docs/mockups/mockup-game-news-onglet-dedie.html, retour de Tim
   2026-09-09). "Mises à jour" + "Presse" partagent désormais leur propre
   onglet "🗞 Actualité" (2e position) plutôt que de vivre dans Aperçu —
   retour de Tim : "Aperçu commence à être bien chargé et n'est plus
   vraiment un aperçu". Classes .patch-note-* réutilisées telles quelles
   pour "Mises à jour" (structure identique), .news-*/.press-* ci-dessous
   pour "Presse" (vignette en plus, compteur discret --muted plutôt que le
   badge dégradé des Mises à jour — source tierce, pas l'officiel du
   développeur). ── */
.press-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.press-head h3 { margin: 0; }
.press-count { color: var(--muted); font: 700 12px 'Rajdhani', sans-serif; }
.news-item { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid var(--line); }
.news-item:first-of-type { border-top: none; padding-top: 10px; }
.news-thumb { width: 72px; height: 72px; border-radius: 8px; object-fit: cover; flex: none; background: var(--bg-2); }
.news-body { min-width: 0; flex: 1; }
.news-item-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.news-title { color: var(--text); font: 700 14px 'Rajdhani', sans-serif; }
.news-meta { color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.news-excerpt { color: var(--text-2); font-size: 13px; line-height: 1.5; margin: 4px 0 6px; }
.news-link { color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; text-decoration: none; }
.news-link:hover { text-decoration: underline; }

@media (max-width: 700px) {
  .topbar, .kpi-group, main, .an-section, .last-synced-note { padding-left: 16px; padding-right: 16px; }
  .filters-card { margin-left: 16px; margin-right: 16px; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
}

/* ─── Carte « Démarrage » (checklist persistante, mockup validé
   docs/mockups/mockup-setup-checklist.html, retour de Tim 2026-08-10) ──
   Complète le guide d'onboarding (#55) plutôt que de le remplacer : le tour
   est one-shot et transitoire, cette carte reste tant qu'il manque quelque
   chose. Elle n'est pilotée par aucun flag "déjà vu" — son contenu est
   DÉRIVÉ de l'état réel du compte (comptes liés, jeu manuel existant), donc
   elle revient d'elle-même si une liaison saute. Seuls "Plus tard" et
   "Masquer" sont mémorisés (user_metadata, voir renderSetupCard).

   Même moule que .filters-card (marge 32px, dégradé panel-2 → panel, radius
   var(--radius)) pour se poser au-dessus des KPI sans ressembler à un corps
   étranger. Bordure accent plutôt que --line : c'est la seule carte du
   dashboard qui demande une action. */
.setup-card {
  margin: 14px 32px 4px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124, 92, 255, .38); border-radius: var(--radius);
  box-shadow: 0 0 30px rgba(124, 92, 255, .07);
  overflow: hidden;
}
.setup-head {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 18px;
}
.setup-title {
  font: 700 14px 'Orbitron', sans-serif; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--text); display: flex; align-items: center; gap: 8px;
}
/* Compteur + barre : la barre porte l'information, le compteur la chiffre.
   Volontairement fine — ce n'est pas un KPI, ça ne doit pas concurrencer les
   tuiles juste en dessous. */
.setup-progress { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 160px; max-width: 320px; }
.setup-progress-bar { flex: 1; height: 5px; border-radius: 999px; background: rgba(120, 140, 255, .16); overflow: hidden; }
.setup-progress-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .45s cubic-bezier(.2,.8,.3,1);
}
.setup-count { color: var(--muted); font: 700 12px 'Rajdhani', sans-serif; letter-spacing: .5px; white-space: nowrap; }
.setup-head-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.setup-linkbtn {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .3px; text-decoration: underline;
  padding: 4px 6px;
}
.setup-linkbtn:hover { color: var(--text); }
.setup-toggle {
  background: none; border: 1px solid var(--line); border-radius: 8px; cursor: pointer;
  color: var(--muted); width: 26px; height: 26px; line-height: 1; font-size: 12px;
  transition: transform .25s, color .18s, border-color .18s;
}
.setup-toggle:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.setup-card.collapsed .setup-toggle { transform: rotate(-90deg); }
.setup-card.collapsed .setup-body { display: none; }

.setup-body { padding: 0 18px 6px; }
.setup-group { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; margin: 12px 0 2px; padding-top: 10px; border-top: 1px solid var(--line); }
.setup-step {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
/* Pastille d'état — trois formes distinctes à l'œil sans lire :
   ✓ plein (fait) · cercle numéroté (à faire) · tiret creux (passé). */
.setup-marker {
  flex: none; width: 24px; height: 24px; border-radius: 50%; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  font: 800 11px 'Rajdhani', sans-serif; letter-spacing: 0;
  border: 1.5px solid rgba(139, 147, 184, .4); color: var(--muted); background: transparent;
}
.setup-step.todo .setup-marker { border-color: rgba(124, 92, 255, .55); color: var(--accent); }
.setup-step.done .setup-marker {
  border-color: transparent; color: #0b0d16;
  background: linear-gradient(120deg, var(--accent-2), #45f0d6);
}
.setup-step.skipped .setup-marker { border-style: dashed; }

.setup-step-body { flex: 1; min-width: 0; }
.setup-step-title { font: 700 14.5px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.3; }
.setup-step.done .setup-step-title,
.setup-step.skipped .setup-step-title { color: var(--muted); }
.setup-step-desc { color: var(--text-2); font: 500 12.5px 'Rajdhani', sans-serif; line-height: 1.5; margin-top: 3px; }
/* Résultat concret une fois l'étape faite — c'est ce qui rend la ligne barrée
   utile plutôt que décorative. */
.setup-step-result { color: var(--accent-2); font: 600 12.5px 'Rajdhani', sans-serif; margin-top: 3px; }
.setup-step-warn { color: var(--gold); font: 600 12px 'Rajdhani', sans-serif; margin-top: 4px; }

.setup-step-actions { display: flex; align-items: center; gap: 8px; flex: none; padding-top: 2px; }
.setup-step-actions .chip { padding: 6px 13px; font-size: 12px; }
.setup-step.todo .setup-step-actions .chip.primary {
  background: linear-gradient(120deg, var(--accent), var(--accent-2));
  color: #0b0d16; border-color: transparent; font-weight: 700;
}
.setup-skip {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font: 600 11.5px 'Rajdhani', sans-serif; text-decoration: underline; padding: 4px;
}
.setup-skip:hover { color: var(--text); }

.setup-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 10px 18px 14px; border-top: 1px solid var(--line);
}
.setup-foot-note { color: var(--muted); font: 500 12px 'Rajdhani', sans-serif; }

/* État final : la carte ne disparaît pas d'un coup, elle se réduit à une
   bande de confirmation qu'on ferme soi-même. */
.setup-card.complete .setup-body, .setup-card.complete .setup-foot { display: none; }
.setup-card.complete { border-color: rgba(0, 229, 195, .4); }
.setup-done-strip { display: none; align-items: center; gap: 12px; padding: 14px 18px; flex-wrap: wrap; }
.setup-card.complete .setup-done-strip { display: flex; }
.setup-card.complete .setup-head { display: none; }
.setup-done-strip .setup-title { color: var(--accent-2); }

/* 700px et non les 720px du mockup : c'est le point de rupture déjà utilisé
   par .topbar/.kpi-group/.filters-card. À 720 la carte serait passée à 16px
   de marge pendant que tout le reste était encore à 32px. */
@media (max-width: 700px) {
  .setup-card { margin-left: 16px; margin-right: 16px; }
  .setup-step { flex-wrap: wrap; }
  .setup-step-actions { width: 100%; padding-left: 36px; }
}

/* ─── Section Guide de l'overlay Info (mockup validé
   docs/mockups/mockup-guide.html, retour de Tim 2026-08-10) ───────────
   Format "page unique qui défile" repris du Help center de Steep
   (référence Mobbin) plutôt qu'un centre d'aide avec recherche et base
   d'articles — hors d'échelle pour une app perso. Trois sections, une
   rangée d'ancres en chips, rien de plus.

   Les tailles/graisses/couleurs de texte ci-dessous ne sont PAS celles du
   reste de l'overlay : retour de Tim, "la font grise un peu terne". Le
   --muted (#8b93b8) tombait à 5,27:1 de contraste sur --panel-2, ce qui
   passe AA mais fatigue en Rajdhani (police étroite et maigre) sur
   plusieurs lignes. #c5cdec + graisse 600 + 13,5px monte à 10,08:1.
   --muted reste le bon choix pour un libellé secondaire ; il ne l'était
   pas pour du texte qu'on demande vraiment de lire. */
.guide-nav { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 4px; }
.guide-nav .chip { text-decoration: none; display: inline-block; }

.guide-h {
  font: 700 12px 'Orbitron', sans-serif; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--accent-2); margin: 26px 0 10px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.guide-p { font: 500 14px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.7; margin-bottom: 10px; }
.guide-p strong { color: var(--accent-2); font-weight: 700; }
/* Plus de couleur ici : .an-sub est passée à --text-2 globalement, cet
   ancien éclaircissement local rendrait maintenant le sous-titre du Guide
   PLUS SOMBRE que partout ailleurs. Seule la taille reste spécifique. */
#guide-section .an-sub { font-size: 13px; }

/* Une carte par voie de liaison — même moule que .roadmap-item (icône
   carrée à gauche, titre + texte à droite) pour rester dans le langage
   visuel de l'overlay. */
.guide-card {
  display: flex; align-items: flex-start; gap: 14px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 10px;
}
.guide-card-icon {
  width: 38px; height: 38px; flex: none; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
  background: rgba(124, 92, 255, .12); border: 1px solid rgba(124, 92, 255, .3);
}
.guide-card.steam .guide-card-icon { background: rgba(102, 192, 244, .12); border-color: rgba(102, 192, 244, .35); }
.guide-card.psn .guide-card-icon { background: rgba(74, 127, 255, .12); border-color: rgba(74, 127, 255, .35); }
.guide-card-title { font: 700 13.5px 'Rajdhani', sans-serif; color: var(--text); margin-bottom: 3px; }
.guide-card-desc { font: 600 13.5px 'Rajdhani', sans-serif; color: #c5cdec; line-height: 1.65; }
.guide-card-warn { color: var(--gold); font: 600 12.5px 'Rajdhani', sans-serif; margin-top: 6px; line-height: 1.55; }

/* Les limites : filet gauche ambré plutôt qu'une carte pleine — ça doit se
   lire comme une mise en garde honnête, pas comme une erreur (rouge) ni
   comme une fonctionnalité (violet). Réutilisé tel quel dans la modale de
   liaison PSN (voir showPsnLinkModal dans app.js). */
.guide-limit {
  border-left: 3px solid rgba(255, 185, 56, .55);
  background: rgba(255, 185, 56, .05);
  border-radius: 0 10px 10px 0;
  padding: 12px 16px; margin-bottom: 10px;
}
.guide-limit-title { font: 700 13.5px 'Rajdhani', sans-serif; color: var(--gold); margin-bottom: 4px; }
.guide-limit-desc { font: 600 13.5px 'Rajdhani', sans-serif; color: #c5cdec; line-height: 1.65; }
.guide-limit-desc strong { color: var(--text); font-weight: 700; }

/* Bloc "mention" — ni une limite (ambre) ni une carte de plateforme : une
   information de contexte. Filet violet discret, pour qu'il ne se lise pas
   comme un quatrième avertissement d'affilée. */
.guide-note {
  border-left: 3px solid rgba(124, 92, 255, .5);
  background: rgba(124, 92, 255, .05);
  border-radius: 0 10px 10px 0;
  padding: 12px 16px; margin-bottom: 10px;
}
.guide-note-title { font: 700 13.5px 'Rajdhani', sans-serif; color: var(--accent-2); margin-bottom: 6px; }
.guide-note-desc p { font: 600 13.5px 'Rajdhani', sans-serif; color: #c5cdec; line-height: 1.65; }
.guide-note-desc p + p { margin-top: 8px; }
.guide-note-desc strong { color: var(--text); font-weight: 700; }

@media (max-width: 700px) {
  .guide-card { flex-wrap: wrap; }
}

/* ─── Toasts (mockup docs/mockups/mockup-toasts.html, validé par Tim
   2026-08-18) ── remplacent les alert() natifs. Le "top" de base ci-dessous
   n'est qu'un repli — positionToastStack() (app.js) le recale à chaque
   toast et à chaque redimensionnement, .topbar n'étant pas position:fixed
   et sa hauteur variant fortement sur mobile. ─────────────────────────── */
.toast-stack {
  position: fixed; top: 74px; right: 20px; z-index: 800;
  display: flex; flex-direction: column; gap: 10px;
  width: min(380px, calc(100vw - 40px));
  pointer-events: none;
}
.toast {
  pointer-events: auto; position: relative; overflow: hidden;
  display: flex; align-items: flex-start; gap: 12px;
  background: linear-gradient(200deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: 12px; padding: 12px 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
  animation: toast-in .28s cubic-bezier(.2, .8, .3, 1) both;
}
@keyframes toast-in {
  from { opacity: 0; transform: translateX(24px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
.toast.leaving { animation: toast-out .22s ease-in both; }
@keyframes toast-out {
  to { opacity: 0; transform: translateX(24px) scale(.97); }
}

/* Trois variantes = trois couleurs déjà au vocabulaire du projet. Le filet
   gauche porte la couleur, pas le fond : un fond teinté sur 4 toasts
   empilés devient une bouillie. */
.toast.success { border-left-color: var(--accent-2); }
.toast.error   { border-left-color: var(--danger); }
.toast.info    { border-left-color: var(--accent); }

.toast-icon { flex: none; font-size: 15px; line-height: 1.4; }
.toast.success .toast-icon { color: var(--accent-2); }
.toast.error .toast-icon { color: var(--danger); }
.toast.info .toast-icon { color: var(--accent); }
/* Alerte « manquables » (2026-09-28, mockup mockup-platine-powerpyx-final.html) :
   même carte, filet doré, jamais effacée seule — voir showNextMissableAlert(). */
.toast.missable { border-left-color: var(--gold); }
.toast.missable .toast-icon { color: var(--gold); }
.toast.missable .toast-title { color: var(--gold); }
.mis-alert-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.mis-alert-cover { width: 34px; aspect-ratio: 3/4; object-fit: cover; border-radius: 5px; border: 1px solid var(--line); flex: none; }
.mis-alert-game { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1px; }
.mis-alert-names { margin-top: 6px; color: var(--text); font: 600 12.5px 'Rajdhani', sans-serif; line-height: 1.45; }
.mis-alert-names span { color: var(--muted); }
.mis-alert-actions { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.mis-alert-count { margin-right: auto; color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; }

.toast-body { flex: 1; min-width: 0; }
.toast-title { font: 700 13.5px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.3; }
.toast-text { font: 600 12.5px 'Rajdhani', sans-serif; color: var(--text-2); line-height: 1.5; margin-top: 2px; }

/* Le message technique brut n'est pas jeté, juste replié : Tim doit pouvoir
   diagnostiquer sans rouvrir la console, l'utilisateur ne doit pas lire
   "duplicate key value violates unique constraint". */
.toast-detail-btn {
  background: none; border: none; padding: 0; margin-top: 6px; cursor: pointer;
  color: var(--muted); font: 600 11px 'Rajdhani', sans-serif;
  text-transform: uppercase; letter-spacing: .6px; text-decoration: underline;
}
.toast-detail-btn:hover { color: var(--text-2); }
.toast-detail {
  display: none; margin-top: 6px; padding: 7px 9px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 7px;
  font: 500 11px ui-monospace, monospace; color: var(--muted);
  line-height: 1.45; word-break: break-word;
}
.toast.open-detail .toast-detail { display: block; }

.toast-close {
  flex: none; background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: 13px; line-height: 1; padding: 2px 4px;
}
.toast-close:hover { color: var(--text); }

/* Barre de vie : rend l'auto-disparition prévisible au lieu de subie.
   Absente sur les erreurs, qui ne disparaissent jamais toutes seules. */
.toast-life {
  position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  transform-origin: left; background: currentColor; opacity: .5;
}
.toast.success .toast-life { color: var(--accent-2); animation: toast-life 4s linear both; }
.toast.info .toast-life { color: var(--accent); animation: toast-life 5s linear both; }
@keyframes toast-life { to { transform: scaleX(0); } }

@media (max-width: 700px) {
  /* "top" géré en JS (positionToastStack) — .topbar n'est pas fixe et sa
     hauteur varie trop pour un chiffre codé en dur ici. */
  .toast-stack { right: 10px; left: 10px; width: auto; }
}

/* ─── Cibles tactiles mobile (audit d'interface, 2026-08-18) ───────────
   Repéré en mesurant les vraies dimensions rendues à 375px : 22 des 38
   éléments cliquables faisaient moins de 32px de haut (recommandation
   courante : 44px). Corrigé ICI, sur mobile seulement — desktop garde
   l'aspect compact existant, où la souris n'a pas ce problème.
   .chip peut grossir sans risque : chaque rangée de filtres a déjà
   flex-wrap:wrap, donc quelques px de plus par puce ajoutent une ligne de
   plus au pire, jamais un débordement. Pour les boutons-icône déjà à taille
   fixe (.setup-toggle, .cvp-delete-btn, .profile-avatar-edit)
   et les liens texte à padding minimal (.setup-linkbtn/.setup-skip/
   .filters-reset/.toast-detail-btn/.toast-close), la zone cliquable est
   agrandie directement plutôt que par un halo invisible — plus simple, et
   l'espace autour de chacun le permettait déjà à l'inspection.
   Volontairement écarté : .card-select (case de sélection multiple), 24px
   mais pas un vrai problème — vérifié dans app.js (renderGrid/
   toggleCardSelection), le clic est attaché à toute la `.card` (~168px),
   la case n'est qu'un indicatif visuel. ───────────────────────────────── */
@media (max-width: 700px) {
  .chip { padding: 10px 14px; }
  .setup-step-actions .chip { padding: 10px 13px; } /* plus petit à la base (12px), même traitement */
  /* flex-shrink:0 : un bouton-icône dans un parent flex peut sinon être
     compressé sous sa largeur (mesuré sur l'ancien bouton du tiroir, 34px
     pour width:38px). */
  .setup-toggle { width: 34px; height: 34px; flex-shrink: 0; }
  .cvp-delete-btn { width: 32px; height: 32px; flex-shrink: 0; }
  .profile-avatar-edit { width: 32px; height: 32px; flex-shrink: 0; }
  /* 8px/9px de padding compensé ne suffisaient pas tout à fait (mesuré :
     30-31px selon la police, pas 32) — remonté de 1px pour repasser la
     barre avec un peu de marge plutôt que pile dessus. */
  .setup-linkbtn, .setup-skip, .filters-reset, .toast-detail-btn {
    padding: 9px 6px; margin: -9px -6px; /* n'affecte pas la mise en page environnante */
  }
  .toast-close { padding: 10px; margin: -10px; }
}

/* --- Anneau de focus clavier (audit d'interface, accessibilite, 2026-08-18)
   .card et .section-title/.filters-title ont recu tabindex="0"+role="button"
   en JS (voir renderGrid/wireCollapsibleSections/wireFiltersCollapse dans
   app.js) -- sans indication visuelle du focus, naviguer au clavier laisse
   l'utilisateur sans repere de "ou" il se trouve. :focus-visible plutot que
   :focus : l'anneau n'apparait qu'a la navigation clavier, jamais sur un
   simple clic souris (comportement natif des navigateurs modernes). ------ */
.card:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 3px;
}
.section-title[role="button"]:focus-visible,
.filters-title:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ─── Topbar mobile compacte (audit d'interface, mockup
   mockup-mobile-topbar.html option A, validée par Tim, 2026-08-18) ─────────
   223-270px sur 2 à 4 lignes (le texte des .chip et le mot-symbole forçaient
   le retour à la ligne) ramenés à ~100px sur 2 lignes fixes : icônes en
   rangée 1 (menu, logo compact, + Ajouter, ▶ Démarrer, profil), recherche
   pleine largeur en rangée 2. Recherche reste toujours visible — aucun
   changement de modèle d'interaction, seulement plus dense. DOM inchangé
   (mêmes #add-game-btn/#start-session-btn/#search déjà câblés en JS) :
   la rangée 2 est obtenue avec `order` + flex-basis:100%, pas une
   réorganisation du markup. */
@media (max-width: 700px) {
  .topbar { padding-top: 12px; padding-bottom: 10px; gap: 8px; }
  .logo { order: 2; }
  .topbar-actions { order: 3; gap: 8px; }
  .search { order: 4; flex: 1 1 100%; max-width: none; min-width: 0; }
  /* Rares/masqués par défaut (sync-indicator, jeux non identifiés) : pas de
     place dédiée en rangée 1, retombent sur leur propre ligne le temps
     qu'ils sont actifs plutôt que de faire déborder les icônes — accepté
     dans le mockup vu leur fréquence. */
  .unmatched-indicator { order: 5; flex: 1 1 100%; }
  /* .topbar-nav est déjà display:none par défaut (règle plus haut) — reste
     .topbar-spacer, un simple flex:1 qui sinon se retrouverait en tête de
     rangée (order:0 par défaut, avant menu-btn/logo/etc. ci-dessus) et
     casserait la mise en page mobile existante. */
  .topbar-spacer { display: none; }

  /* Les deux .chip d'action perdent déjà leur libellé visuel sur tous les
     écrans (.chip-icon-only, règle plus haut, désormais aussi sur desktop
     — retour de Tim) ; le libellé passe en visually-hidden (pas
     display:none) pour que le nom accessible reste identique, sans
     dupliquer via aria-label. */
  .chip-label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
}

/* ─── Onglets Jeux/KPIs, KPIs empilés, filtres en icônes (mobile, mockup
   mockup-mobile-kpis-filtres.html v3, validé par Tim, 2026-08-19) ─────────
   8 tuiles KPI + carte filtres entièrement dépliée avant le premier jeu,
   remplacé par : deux onglets pilule "Jeux" (par défaut)/"KPIs" — les KPIs
   ne poussent plus la grille vers le bas, ils vivent dans leur propre
   onglet — et la carte filtres réduite à 5 icônes (36×36, même gabarit que
   .topbar-actions .chip) au lieu du bloc de chips toujours visible. Rien de
   tout ceci n'existe sur desktop : .view-tabs est display:none par défaut,
   et les sélecteurs mobile-only ci-dessous ne matchent que sous 700px. */
.view-tabs { display: none; }
@media (max-width: 700px) {
  .view-tabs { display: flex; gap: 8px; margin: 12px 16px 4px; }
  .view-tab {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
    color: var(--muted); font: 700 12.5px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: uppercase;
    padding: 10px; cursor: pointer; transition: all .18s;
  }
  .view-tab.active {
    background: linear-gradient(120deg, rgba(124, 92, 255, .3), rgba(0, 229, 195, .15));
    border-color: var(--accent); color: var(--text);
  }

  /* "Jeux" actif par défaut au premier rendu : KPIs masqués, filtres+grille
     visibles. body.mobile-kpis-active (posé par wireMobileViewTabs()) fait
     l'inverse. .setup-card (au-dessus) n'est délibérément pas concerné —
     elle reste visible quel que soit l'onglet, ce n'est ni un KPI ni une
     partie de la liste de jeux. */
  #view-overview > .kpi-group { display: none; }
  body.mobile-kpis-active #view-overview > .kpi-group { display: block; }
  /* .filters-card et main (avec .view-toggle-row) ne sont plus enfants
     directs de #view-overview depuis la colonne desktop (.dashboard-layout,
     plus bas) — descendant simple plutôt que ">", .dashboard-main regroupe
     .view-toggle-row et main donc il suffit de le masquer une fois. */
  body.mobile-kpis-active #view-overview .filters-card,
  body.mobile-kpis-active #view-overview .dashboard-main { display: none; }


  /* Carte filtres réduite à une rangée d'icônes centrée. Chaque bouton
     garde son comportement JS existant (wireFiltersCollapse/
     wireConfigureViewPanel/wireToggleAllSections/#selection-mode-btn) —
     seul le libellé texte passe en .chip-label (visually-hidden, définie
     plus haut) au profit de l'icône déjà utilisée. */
  .filters-card-head { justify-content: center; }
  .filters-view-controls { justify-content: center; gap: 8px; }
  .sort-wrap { display: none; }
  .filters-title {
    position: relative;
    width: 36px; height: 36px; flex: none; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border-radius: 10px;
  }
  .filters-title .st-chevron { display: none; }
  .filters-title .active-count {
    position: absolute; top: -6px; right: -8px; margin: 0;
  }
  .filters-view-controls .chip {
    width: 36px; height: 36px; flex: none; padding: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 15px;
  }
  .filters-reset { font-size: 10.5px; padding: 4px 6px; }

  /* "Configurer la vue" ne s'ouvre plus collé à sa petite icône déclenchante
     (retour de Tim, 2026-08-21 : "le panneau ne s'affiche pas au centre de
     l'écran") — desktop l'ancre en `position:absolute` sous le bouton, ce
     qui marchait tant que #configure-view-btn était un vrai chip large,
     mais un carré de 36px au milieu d'une rangée d'icônes centrée n'offre
     plus de repère fiable ; le panneau (320px) déborde selon l'endroit où
     l'icône tombe dans la rangée. Recentré en `position:fixed` sur le
     viewport plutôt que sur le bouton. z-index au-dessus de la feuille
     filtres (200) : les deux peuvent s'ouvrir depuis la même rangée
     d'icônes, ⚙️ doit rester joignable même si 🔎 est déjà ouvert. */
  .configure-view-panel {
    position: fixed; top: 50%; left: 50%; right: auto;
    transform: translate(-50%, -50%);
    width: min(320px, calc(100vw - 32px));
    max-height: 80vh; overflow-y: auto;
    z-index: 210;
  }

  /* Équivalent mobile de .sort-wrap (<select id="sort"> cachée juste
     au-dessus, toujours la source de vérité — voir wireMobileSortPanel()). */
  .mobile-sort-wrap { display: block; position: relative; }
  .mobile-sort-panel { min-width: 180px; padding: 6px; }
  .sort-opt-btn {
    display: block; width: 100%; text-align: left;
    background: none; border: none; border-radius: 8px; padding: 8px 10px; cursor: pointer;
    color: var(--muted); font: 600 13px 'Rajdhani', sans-serif;
  }
  .sort-opt-btn:hover { background: rgba(124, 92, 255, .1); color: var(--text); }
  .sort-opt-btn.active { color: var(--accent-2); font-weight: 700; }

  /* Feuille plein écran pour .filter-groups (Plateforme/Statut/Tags/
     Visibilité), déclenchée par #filters-title-toggle (wireFiltersCollapse,
     branche mobile). .filters-card devient elle-même l'overlay plutôt que
     d'en dupliquer un nouveau — évite de sortir .filter-groups de son
     parent. !important nécessaire : le repli desktop (.collapsed, plus
     haut) pose des styles inline (max-height/opacity) via animateMaxHeight,
     plus spécifiques qu'une règle externe. */
  .filter-groups { display: none; }
  .filters-card.mobile-sheet-open {
    position: fixed; inset: 0; z-index: 200; margin: 0; border-radius: 0;
    overflow-y: auto; padding-bottom: 60px;
    background: rgba(5, 6, 12, .97);
  }
  .filters-card.mobile-sheet-open .filter-groups {
    display: block !important; max-height: none !important; opacity: 1 !important; margin-top: 14px !important;
  }
}

/* ─── Colonne filtres épinglée + KPIs compacts, desktop (mockup
   mockup-desktop-kpis-filtres.html option B, validée par Tim, 2026-08-24)
   ───────────────────────────────────────────────────────────────────────
   .filters-card passait d'une carte toujours dépliée au-dessus de la
   grille à une colonne fixe à gauche (façon Steam/OpenSea/Literal),
   épinglée au scroll ("où que tu sois dans le scroll", retour de Tim) —
   plus besoin de replier/déplier pour voir la grille. DOM inchangé :
   #platform-filters/#status-filters/etc. restent les mêmes éléments
   #chip/data-value déjà câblés dans wireControls() (délégation sur
   .chip-row[data-filter], indifférente à la présentation visuelle) —
   uniquement du CSS ajouté ici, zéro ligne d'app.js touchée pour ce
   chantier. Tri/Configurer la vue/Tout replier/Sélectionner/Réinitialiser
   (.filters-view-controls) déplacés au-dessus de la grille dans
   #dashboard-toolbar (retour de Tim, 2026-08-24 : "au-dessus des
   cartes") — un JS de repositionnement (wireResponsiveToolbarPlacement,
   app.js) les fait migrer entre .filters-card-head (mobile, groupés avec
   l'icône entonnoir en une seule rangée) et #dashboard-toolbar (desktop),
   parce que #sort (natif) ne peut pas exister deux fois pour un simple
   repli CSS/`order`. */
@media (min-width: 701px) {
  .dashboard-layout { display: flex; gap: 24px; align-items: flex-start; }
  .dashboard-main { flex: 1; min-width: 0; }

  .filters-card {
    flex: none; width: 260px;
    position: sticky; top: 20px; max-height: calc(100vh - 40px); overflow-y: auto;
  }
  /* .dashboard-toolbar-row aligne #dashboard-toolbar et .view-toggle-row sur
     la même ligne (retour de Tim : "à la même hauteur que Grille/Liste") —
     .view-toggle-row garde son margin d'origine (20px 0) pensé pour être
     seul sur sa ligne, donc remis à 0 ici pour ne pas désaligner. */
  /* padding 0 32px : la même marge que le <main> des sections juste dessous —
     sans elle, tri et Grille / Liste débordaient de 32 px de chaque côté du
     bord des sections et de la carte d'objectif (retour de Tim, 2026-10-03). */
  .dashboard-toolbar-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 20px 0 16px; padding: 0 32px; }
  .dashboard-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .dashboard-toolbar-row .view-toggle-row { margin: 0; flex: none; }
  .filters-view-controls { justify-content: flex-start; }

  /* Rangées de chips -> liste de facettes empilée (une option par ligne,
     pleine largeur) — plus lisible dans une colonne de 260px qu'une
     rangée qui s'enroule sur elle-même. */
  .filter-groups .chip-row { flex-direction: column; align-items: stretch; gap: 4px; }
  .filter-groups .chip { text-align: left; border-radius: 8px; padding: 7px 10px; }

  /* Le panneau tags (min-width 320px, pensé pour flotter au-dessus d'une
     carte pleine largeur) déborderait d'une colonne de 260px — passé en
     bloc inline sous le bouton plutôt qu'en popover flottant. Sélecteur
     par id : plus spécifique que .dropdown-panel, pas besoin d'!important. */
  #tag-filter-panel { position: static; width: 100%; min-width: 0; margin-top: 6px; box-shadow: none; }

  /* .configure-view-panel ancrée à right:0/320px de large déborde hors
     écran à gauche une fois #configure-view-btn dans une colonne de 260px
     (même défaut que le bug mobile "ne s'affiche pas au centre" — trouvé
     en vérifiant en direct, pas dans le mockup). Même correctif : centré
     sur le viewport plutôt que sur le bouton. */
  .configure-view-panel {
    position: fixed; top: 50%; left: 50%; right: auto;
    transform: translate(-50%, -50%);
    width: min(320px, calc(100vw - 32px));
    max-height: 80vh; overflow-y: auto;
    z-index: 210;
  }

}

/* ─── Recherche en loupe + panneau ancré, dès 701px (mockup
   mockup-desktop-topbar-nav.html, retour de Tim) ─────────────────────────
   Redonne une vraie boîte à .topbar-search/.search-panel (display:contents
   par défaut, règle plus haut) : le bouton loupe apparaît, le panneau se
   positionne en absolu sous lui et reste fermé tant que .open n'est pas
   posée par wireSearchPanel() (app.js). */
@media (min-width: 701px) {
  .topbar-search { position: relative; display: block; }
  .search-icon-btn {
    position: relative; width: 38px; height: 38px; border-radius: 50%; flex: none;
    background: var(--panel); border: 1px solid var(--line); color: var(--text-2);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; transition: border-color .18s, color .18s;
  }
  .search-icon-btn:hover { border-color: var(--accent); color: var(--text); }
  .search-icon-btn svg { width: 17px; height: 17px; }
  /* Recherche active mais panneau refermé : anneau plutôt qu'un badge à
     chiffre (une recherche texte n'a pas de "compte" à afficher, juste un
     état on/off) — même famille visuelle que .chip.active. Sans lui, rien
     ne dirait pourquoi la grille reste filtrée une fois le panneau fermé. */
  .search-icon-btn.has-value {
    border-color: var(--accent); color: var(--text);
    box-shadow: 0 0 0 3px rgba(124, 92, 255, .18);
  }
  .search-panel {
    display: none; position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
    width: 300px; max-width: 90vw;
    background: linear-gradient(160deg, var(--panel-2), var(--panel));
    border: 1px solid var(--accent); border-radius: 14px;
    padding: 10px; box-shadow: 0 30px 60px rgba(0, 0, 0, .5);
    animation: fade .15s both;
  }
  .search-panel.open { display: block; }
  .search-panel .search { width: 100%; max-width: none; min-width: 0; }
}

/* ─── Bascule nav texte / hamburger à 761px (mockup
   mockup-desktop-topbar-nav.html, retour de Tim : "en dessous ~760px ça
   fait trop chenit") ───────────────────────────────────────────────────
   Seuil indépendant des 700px déjà utilisés pour la mise en page mobile
   générale (KPIs empilés, grille 1 colonne, etc.) — entre 701px et 760px
   ces règles-là restent actives (colonne de filtres sticky comprise),
   seule la nav bascule vers le hamburger existant. Rien d'autre ne change
   à ce seuil : la loupe et les icônes d'action (bloc 701px ci-dessus)
   étaient déjà assez compactes, elles ne faisaient pas partie du "chenit"
   signalé. */
@media (min-width: 761px) {
  .topbar-nav { display: flex; }
}

/* ═══════════════════════════════════════════════════════════════════
   Wishlist (tâche #29, mockup validé docs/mockups/mockup-wishlist.html)
   ═══════════════════════════════════════════════════════════════════ */
.wl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 18px; margin-top: 6px; }

.wl-card {
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column; transition: border-color .2s, transform .2s;
}
.wl-card:hover { border-color: rgba(124, 92, 255, .5); transform: translateY(-3px); }
.wl-cover { position: relative; width: 100%; aspect-ratio: 3/4; overflow: hidden; background: var(--bg-2); }
.wl-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wl-countdown {
  position: absolute; top: 10px; left: 10px;
  background: rgba(11, 13, 22, .82); backdrop-filter: blur(4px);
  border: 1px solid rgba(124, 92, 255, .5); border-radius: 999px;
  padding: 5px 12px; font: 700 12px 'Rajdhani', sans-serif; letter-spacing: .4px;
  color: var(--accent-2); text-transform: uppercase;
}
.wl-countdown.soon { color: var(--gold); border-color: rgba(255, 185, 56, .5); }
.wl-remove {
  position: absolute; top: 10px; right: 10px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(11, 13, 22, .82); border: 1px solid var(--line); color: var(--muted);
  display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 13px;
}
.wl-remove:hover { color: var(--danger); border-color: var(--danger); }
/* Déplacer un jeu importé vers « Ajoutés à la main » (mockup
   mockup-wishlist-deplacer-vers-mes-ajouts.html, 2026-09-16) : bandeau
   LIBELLÉ au survol, jamais une icône seule — retour de Tim sur une
   première version avec une flèche « ↑ » : « elle sort de nulle part ». */
.wl-move-bar {
  position: absolute; left: 0; right: 0; bottom: 0; width: 100%; padding: 9px 10px; border: 0;
  background: linear-gradient(to top, rgba(11, 13, 22, .94), rgba(11, 13, 22, .72) 70%, transparent);
  color: var(--text); cursor: pointer; text-align: center;
  font: 700 12px 'Rajdhani', sans-serif; letter-spacing: .3px;
  transform: translateY(100%); transition: transform .16s;
}
.wl-card:hover .wl-move-bar, .wl-card:focus-within .wl-move-bar { transform: translateY(0); }
.wl-move-bar:hover { color: var(--accent-2); }
/* Le déplacement se voit sur la carte elle-même (pas de toast : les succès
   restent limités aux quatre gestes validés au mockup des toasts). */
.wl-card.just-moved .wl-cover { box-shadow: 0 0 0 2px var(--accent-2); }
.wl-detail-move {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin-top: 10px; padding: 10px 12px; background: var(--bg-2);
  border: 1px solid var(--line); border-radius: 10px;
}
.wl-detail-move .txt { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.wl-detail-move .txt b { color: var(--text); }
.wl-detail-move .done { color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; }
.wl-body { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.wl-name { font: 700 14.5px 'Rajdhani', sans-serif; line-height: 1.25; }
.wl-date { color: var(--muted); font-size: 12px; }
.wl-hype { color: var(--muted); font-size: 12px; margin-top: auto; padding-top: 8px; display: flex; align-items: center; gap: 5px; }
.wl-add-btn {
  margin-top: 8px; width: 100%; background: none; border: 1px solid rgba(124, 92, 255, .4);
  border-radius: 8px; color: var(--accent-2); font: 700 11.5px 'Rajdhani', sans-serif;
  letter-spacing: .5px; text-transform: uppercase; padding: 7px; cursor: pointer; transition: all .18s;
}
.wl-add-btn:hover { background: rgba(124, 92, 255, .12); border-color: var(--accent); }
.wl-add-btn:disabled { opacity: .5; cursor: default; }

.wl-empty {
  grid-column: 1 / -1; text-align: center; padding: 50px 20px; color: var(--muted);
  border: 1px dashed var(--line); border-radius: var(--radius); font-size: 14px;
}

.wl-platform-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.wl-platform-filters .chip { padding: 7px 14px; font-size: 12px; }
.wl-platform-filters .chip.active {
  background: linear-gradient(120deg, rgba(124, 92, 255, .3), rgba(0, 229, 195, .15));
  border-color: var(--accent); color: var(--text);
}

.wl-list { display: flex; flex-direction: column; gap: 8px; }
.wl-row {
  display: flex; align-items: center; gap: 14px; padding: 10px 16px 10px 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  transition: border-color .18s;
}
.wl-row:hover { border-color: rgba(124, 92, 255, .5); }
.wl-row-cover { width: 42px; height: 56px; border-radius: 5px; object-fit: cover; flex: none; background: var(--bg-2); }
.wl-row-main { flex: 1; min-width: 0; }
.wl-row-name { font: 700 14px 'Rajdhani', sans-serif; margin-bottom: 3px; }
.wl-row-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); }
.wl-row-plats { display: flex; gap: 5px; flex-wrap: wrap; }
.wl-plat-tag {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 5px;
  padding: 1px 6px; font-size: 10px; letter-spacing: .3px; color: var(--text-2);
}
.wl-row-hype { color: var(--muted); font-size: 11.5px; flex: none; }
.wl-row-add {
  flex: none; background: none; border: 1px solid rgba(124, 92, 255, .4); border-radius: 8px;
  color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .4px;
  text-transform: uppercase; padding: 7px 12px; cursor: pointer; transition: all .18s;
}
.wl-row-add:hover { background: rgba(124, 92, 255, .12); border-color: var(--accent); }
.wl-row-add:disabled { opacity: .5; cursor: default; }
.wl-load-more {
  display: block; margin: 18px auto 0; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; color: var(--text-2); font: 700 12.5px 'Rajdhani', sans-serif;
  letter-spacing: .5px; text-transform: uppercase; padding: 10px 26px; cursor: pointer;
}
.wl-load-more:hover { border-color: var(--accent); color: var(--text); }
.wl-load-more:disabled { opacity: .5; cursor: default; }
.wl-load-more.hidden { display: none; }

/* Revenir à la première page sans recharger (retour de Tim, 2026-08-31 :
   "après plusieurs Charger plus, un moyen de revenir à l'état initial ?")
   — discret par rapport à "Charger plus", n'apparaît que si plus d'une
   page a été chargée. Recadre depuis le cache déjà en mémoire, aucun
   aller-retour réseau. */
.wl-load-more-row { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 18px; }
.wl-load-more-row .wl-load-more { margin: 0; }
.wl-collapse-more {
  background: none; border: none; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif;
  letter-spacing: .4px; text-transform: uppercase; cursor: pointer; padding: 10px 4px;
}
.wl-collapse-more:hover { color: var(--text); text-decoration: underline; }
.wl-collapse-more.hidden { display: none; }

/* Cartes/lignes cliquables (retour de Tim 2026-08-31 : clic n'importe où
   ouvre l'écran de détail) — .wl-card/.wl-row deviennent des cibles de clic
   au clavier via tabindex="0" role="button" (règle du 2026-08-18, voir
   CLAUDE.md) : anneau de focus sur :focus-visible seulement, jamais :focus. */
.wl-card, .wl-row { cursor: pointer; }
.wl-card:focus-visible, .wl-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

/* Badge sidebar (retour de Tim 2026-08-31) : nombre de jeux de la wishlist
   à J-5 ou moins — .lbl { flex:1 } (déjà générique) pousse ce badge en bout
   de ligne sans rien toucher au CSS existant du lien. */
.sidebar-badge {
  background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16;
  font: 800 11px 'Orbitron', sans-serif; padding: 2px 8px; border-radius: 999px; flex: none;
}
.sidebar-badge.hidden { display: none; }

/* ── Carrousel "Tendances du moment", façon Steam (mockup-wishlist.html,
   retour de Tim 2026-08-31) — remplace l'ancienne grille .wl-grid pour
   cette section. Artwork IGDB (1080p) plutôt que la jaquette, plus
   cinématique en pleine largeur. Autoplay 6s, relancé à chaque interaction
   manuelle (flèche/point) plutôt que de continuer sous les doigts.
   Déjà pleine largeur viewport (`#view-wishlist` est un frère de `<main>`,
   pas un enfant — le `padding:10px 32px` de `main` ne s'applique jamais
   ici ; chaque `.an-section` de la page pose son propre padding). "Élargir"
   une 2e fois (retour de Tim, 2026-08-31, "façon Disney+ ou HBO, que ça
   prenne pas mal de place") — au-delà de la hauteur (min(56vh,560px) ->
   min(72vh,760px)), la typo/les contrôles remontent avec, sinon un bandeau
   plus haut avec le même texte/les mêmes boutons de taille identique se
   serait juste retrouvé avec plus de vide en bas façon zoom d'image raté. */
.wl-carousel { position: relative; width: 100%; height: min(72vh, 760px); min-height: 480px; overflow: hidden; }
.wl-carousel-track { position: relative; width: 100%; height: 100%; }
.wl-slide {
  position: absolute; inset: 0; display: flex; align-items: flex-end;
  background-size: cover; background-position: center 30%;
  opacity: 0; transition: opacity .5s ease; pointer-events: none;
}
.wl-slide.active { opacity: 1; pointer-events: auto; }
.wl-slide::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(0deg, var(--bg) 0%, rgba(11,13,22,.55) 45%, rgba(11,13,22,.15) 100%),
              linear-gradient(90deg, rgba(11,13,22,.75) 0%, transparent 55%);
}
.wl-slide-content { position: relative; z-index: 1; padding: 0 56px 56px; max-width: 720px; }
.wl-slide-badge {
  display: inline-flex; align-items: center; gap: 7px; background: rgba(124,92,255,.25);
  border: 1px solid var(--accent); border-radius: 999px; padding: 5px 14px;
  font: 700 12px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: uppercase; margin-bottom: 14px;
}
.wl-slide-title { font: 900 44px 'Orbitron', sans-serif; letter-spacing: .5px; margin: 0 0 10px; text-shadow: 0 2px 12px rgba(0,0,0,.6); }
.wl-slide-meta { color: var(--text-2); font-size: 15px; margin-bottom: 20px; display: flex; gap: 18px; flex-wrap: wrap; }
.wl-slide-actions { display: flex; gap: 12px; }
.wl-slide-actions .chip { padding: 13px 24px; font-size: 14px; }
.wl-slide-actions .chip:disabled { opacity: .6; cursor: default; }

.wl-carousel-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 46px; height: 46px; border-radius: 50%; background: rgba(11,13,22,.6);
  border: 1px solid var(--line); color: var(--text); display: flex; align-items: center;
  justify-content: center; cursor: pointer; font-size: 20px; backdrop-filter: blur(4px);
}
.wl-carousel-arrow:hover { border-color: var(--accent); background: rgba(11,13,22,.85); }
.wl-carousel-arrow.prev { left: 26px; }
.wl-carousel-arrow.next { right: 26px; }
.wl-carousel-dots { position: absolute; bottom: 24px; right: 56px; z-index: 2; display: flex; gap: 9px; }
.wl-carousel-dot {
  width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,.3); cursor: pointer;
  transition: all .2s; border: none; padding: 0;
}
.wl-carousel-dot.active { background: var(--accent-2); width: 26px; border-radius: 4px; }

/* ── Modal de détail unique, réutilisé partout (grille wishlist, carrousel,
   ligne "À venir", carte "Jeux du moment", notif de sortie, résumé) — un
   seul gabarit rempli à la demande par openWishlistDetail(), jamais un
   écran par jeu. ── */
.wl-detail-overlay {
  position: fixed; inset: 0; z-index: 500; display: none; align-items: center; justify-content: center;
  background: rgba(5,6,12,.7); backdrop-filter: blur(10px); padding: 30px;
}
.wl-detail-overlay.open { display: flex; }
.wl-detail-box {
  /* Élargi de 760px (retour de Tim, 2026-08-31 : "moins serré") — la
     bande-annonce et la galerie de captures avaient peu de place pour
     respirer sur un écran large. */
  width: min(960px, 92vw); max-height: 88vh; overflow-y: auto;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124,92,255,.3); border-radius: 20px; position: relative;
}
.wl-detail-close {
  position: absolute; top: 16px; right: 16px; z-index: 2; width: 32px; height: 32px; border-radius: 8px;
  background: rgba(11,13,22,.6); border: 1px solid var(--line); color: var(--muted);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.wl-detail-hero {
  width: 100%; aspect-ratio: 16/7; background-size: cover; background-position: center;
  border-radius: 20px 20px 0 0; position: relative; background-color: var(--bg-2);
}
.wl-detail-hero::after {
  content: ''; position: absolute; inset: 0; border-radius: 20px 20px 0 0;
  background: linear-gradient(0deg, var(--panel) 0%, transparent 60%);
}
.wl-detail-body { padding: 4px 32px 32px; }
.wl-detail-title { font: 900 24px 'Orbitron', sans-serif; margin: 0 0 6px; }
.wl-detail-meta { display: flex; gap: 18px; color: var(--text-2); font-size: 13.5px; flex-wrap: wrap; }
.wl-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.wl-detail-head-main { min-width: 0; }
.wl-detail-plats { display: flex; gap: 14px; align-items: center; flex: none; color: var(--text); }
.wl-detail-plats:empty { display: none; }
.wl-plat-logo { display: inline-flex; width: 30px; height: 30px; align-items: center; justify-content: center; opacity: .9; }
.wl-plat-logo:hover { opacity: 1; }
.wl-plat-logo-svg { width: 100%; height: 100%; }
.wl-plat-logo.pc { width: 24px; height: 24px; }
@media (max-width: 560px) {
  .wl-detail-head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .wl-plat-logo { width: 26px; height: 26px; }
  .wl-plat-logo.pc { width: 21px; height: 21px; }
}
.wl-detail-h3 {
  font: 700 12px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--muted); margin: 22px 0 10px;
}
.wl-detail-h3.hidden { display: none; }
.wl-shots-row.hidden, .wl-trailer.hidden, .wl-buy-row.hidden { display: none; }
.wl-shots-row { position: relative; }
.wl-shots {
  display: flex; gap: 10px; overflow-x: auto; scroll-behavior: smooth;
  scrollbar-width: none; -ms-overflow-style: none;
}
.wl-shots::-webkit-scrollbar { display: none; }
.wl-shots img { height: 110px; border-radius: 8px; flex: none; cursor: zoom-in; }
.wl-shots-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 32px; height: 32px; border-radius: 50%; background: rgba(11,13,22,.75);
  border: 1px solid var(--line); color: var(--text); display: flex; align-items: center;
  justify-content: center; cursor: pointer; font-size: 16px; backdrop-filter: blur(3px);
}
.wl-shots-arrow:hover { border-color: var(--accent); background: rgba(11,13,22,.9); }
.wl-shots-arrow.prev { left: -6px; }
.wl-shots-arrow.next { right: -6px; }
.wl-trailer { position: relative; width: 100%; aspect-ratio: 16/9; border-radius: 12px; overflow: hidden; background: var(--bg-2); }
.wl-trailer iframe { width: 100%; height: 100%; border: 0; }
.wl-buy-row { display: flex; gap: 10px; flex-wrap: wrap; }
.wl-buy-link {
  display: flex; align-items: center; gap: 8px; background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 16px; color: var(--text); text-decoration: none;
  font: 700 13px 'Rajdhani', sans-serif; transition: all .18s;
}
.wl-buy-link:hover { border-color: var(--accent); background: rgba(124,92,255,.1); }
/* Vrais logos des stores (retour de Tim, 2026-08-31) — SVG inline pour
   Steam/PlayStation/Xbox (fill="currentColor", hérite du blanc cassé déjà
   posé par .wl-buy-link, sauf Steam recoloré en bleu de marque), <img> vers
   l'asset officiel pour Epic Games/GOG/Instant Gaming (déjà en couleur,
   rien à teinter). GOG a un fond blanc intégré à l'image — petit chip clair
   pour ne pas laisser un carré blanc flotter brut au milieu du bouton sombre. */
.wl-buy-logo-svg, .wl-buy-logo-img { width: 18px; height: 18px; flex: none; object-fit: contain; }
.wl-buy-link[href*="steampowered.com"] .wl-buy-logo-svg { color: var(--steam); }
.wl-buy-logo-img-chip { background: #fff; border-radius: 4px; padding: 2px; }
.wl-detail-cta { margin-top: 24px; }
.wl-detail-cta .chip:disabled { opacity: .6; cursor: default; }
.wl-detail-loading { color: var(--muted); font-size: 13px; }

/* Prix + Metacritic (enrichissement Steam Store, retour de Tim) —
   conditionnel : n'apparaît que si le jeu a une fiche Steam. Score
   Metacritic lui-même absent tant que le jeu n'est pas sorti. */
.wl-price-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.wl-price {
  font: 900 20px 'Orbitron', sans-serif; color: var(--accent-2);
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 16px;
}
.wl-metacritic {
  display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text);
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 14px;
  font: 700 13px 'Rajdhani', sans-serif;
}
.wl-metacritic-score {
  width: 30px; height: 30px; border-radius: 5px; display: flex; align-items: center; justify-content: center;
  font: 800 14px 'Orbitron', sans-serif; color: #0b0d16; background: #6c3;
}

/* Avis Steam (retour de Tim, 2026-08-31) — comble les jeux sortis sans fiche
   Metacritic (cas S.T.A.L.K.E.R. 2). % en évidence façon Metacritic/prix,
   description ("plutôt positives") en --muted : c'est un libellé annexe au
   pourcentage, pas une phrase à lire. */
.wl-steam-reviews {
  display: flex; align-items: center; gap: 8px; color: var(--text);
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 14px;
  font: 700 13px 'Rajdhani', sans-serif;
}
.wl-steam-reviews-desc { color: var(--muted); font-weight: 600; }

/* Prix par boutique (idée de Tim, 2026-09-14, mockup
   mockup-wishlist-prix-ps-store.html) : une pastille par boutique qui a un
   prix — logo + nom, montant, et en promo l'ancien prix barré + le
   pourcentage (+ la fin de promo quand la boutique la donne, Sony oui, Steam
   non). Clic = fiche de la boutique. Remplace l'ancienne `.wl-price` sans nom. */
.sp-group { display: flex; gap: 10px; flex-wrap: wrap; }
.sp-chip {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; text-decoration: none;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 14px;
  transition: border-color .18s, background .18s;
}
.sp-chip:hover { border-color: var(--accent); background: rgba(124,92,255,.1); }
.sp-store { display: inline-flex; align-items: center; gap: 6px; align-self: center;
  color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; }
.sp-logo-svg { width: 16px; height: 16px; flex: none; }
.sp-chip.steam .sp-logo-svg { color: var(--steam); }
.sp-chip.ps .sp-logo-svg { color: var(--psn); width: 18px; }
.sp-amount { font: 900 18px 'Orbitron', sans-serif; color: var(--accent-2); }
.sp-was { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; text-decoration: line-through; }
.sp-off { color: var(--gold); background: rgba(255,185,56,.1); border: 1px solid rgba(255,185,56,.45);
  border-radius: 6px; padding: 1px 6px; font: 700 12px 'Rajdhani', sans-serif; align-self: center; }
.sp-until { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }

/* ── Lightbox (clic sur une vignette de la galerie de l'écran détail) ── */
.wl-lightbox {
  position: fixed; inset: 0; z-index: 520; display: none; align-items: center; justify-content: center;
  background: rgba(5,6,12,.9); backdrop-filter: blur(6px); padding: 40px;
}
.wl-lightbox.open { display: flex; }
.wl-lightbox img { max-width: 100%; max-height: 100%; border-radius: 10px; box-shadow: 0 20px 60px rgba(0,0,0,.6); }
.wl-lightbox-close {
  position: absolute; top: 24px; right: 24px; width: 38px; height: 38px; border-radius: 50%;
  background: rgba(11,13,22,.7); border: 1px solid var(--line); color: var(--text);
  display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 16px;
}
.wl-lightbox-close:hover { border-color: var(--accent); }
.wl-lightbox-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 46px; height: 46px; border-radius: 50%; background: rgba(11,13,22,.7);
  border: 1px solid var(--line); color: var(--text); display: flex; align-items: center;
  justify-content: center; cursor: pointer; font-size: 22px;
}
.wl-lightbox-arrow:hover { border-color: var(--accent); }
.wl-lightbox-arrow.prev { left: 24px; }
.wl-lightbox-arrow.next { right: 24px; }

/* ── Notification "sortie imminente" (retour de Tim : façon "Jeu terminé"
   mais qui apparaît/disparaît seule après ~5s — jamais un modal à fermer à
   la main comme .finish-overlay/.celebration-overlay, puisqu'elle peut se
   déclencher plusieurs jours de suite avant la sortie). Bannière, pas un
   plein écran : ne doit pas interrompre ce que fait l'utilisateur. ── */
.release-notif {
  position: fixed; top: 24px; left: 50%; z-index: 700; cursor: pointer;
  transform: translate(-50%, -140%); opacity: 0; pointer-events: none;
  transition: transform .5s cubic-bezier(.2,.8,.3,1), opacity .5s;
  display: flex; align-items: center; gap: 20px; border: none; text-align: left;
  background: radial-gradient(circle at 30% 30%, rgba(124,92,255,.35), rgba(11,13,22,.94) 75%);
  border-radius: 18px; padding: 18px 34px 18px 22px;
  box-shadow: 0 20px 60px rgba(0,0,0,.55), 0 0 40px rgba(124,92,255,.2);
  backdrop-filter: blur(10px);
}
.release-notif:hover { box-shadow: 0 20px 60px rgba(0,0,0,.55), 0 0 40px rgba(0,229,195,.25); }
.release-notif.show { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.release-notif-cover { width: 54px; height: 72px; border-radius: 8px; object-fit: cover; flex: none; border: 1px solid var(--line); }
.release-notif-body { display: flex; flex-direction: column; }
.release-notif-label { font: 800 11px 'Orbitron', sans-serif; letter-spacing: 3px; color: var(--gold); margin-bottom: 2px; }
.release-notif-countdown {
  font: 900 40px 'Orbitron', sans-serif; line-height: 1;
  background: linear-gradient(120deg, #fff, var(--accent-2), var(--gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.release-notif-game { font: 700 16px 'Rajdhani', sans-serif; color: var(--text); margin-top: 2px; }
.release-notif-more { font: 600 12.5px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 3px; }

/* ── Résumé (plusieurs jeux à J-5 ou moins à la fois) — une seule
   notification déclenche ce résumé plutôt que plusieurs notifs empilées
   (retour explicite de Tim : "pas trop lourd"). Clic sur une ligne ouvre
   ENSUITE le détail de ce jeu précis via le même gabarit ci-dessus. ── */
.wl-summary-box {
  width: min(480px, 100%); background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124,92,255,.3); border-radius: 20px; padding: 26px 26px 20px;
}
.wl-summary-title { font: 900 16px 'Orbitron', sans-serif; letter-spacing: 1px; margin: 0 0 4px; display: flex; align-items: center; gap: 8px; }
.wl-summary-sub { color: var(--muted); font-size: 12.5px; margin: 0 0 18px; }
.wl-summary-row {
  display: flex; align-items: center; gap: 14px; padding: 10px 12px; border-radius: 12px;
  cursor: pointer; transition: background .15s; width: 100%; background: none; border: none; text-align: left;
  color: var(--text); font-family: inherit;
}
.wl-summary-row:hover { background: var(--panel-2); }
.wl-summary-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.wl-summary-row + .wl-summary-row { margin-top: 4px; }
.wl-summary-cover { width: 42px; height: 56px; border-radius: 6px; object-fit: cover; flex: none; }
.wl-summary-name { font: 700 14.5px 'Rajdhani', sans-serif; }
.wl-summary-date { color: var(--muted); font-size: 12px; }
.wl-summary-countdown { margin-left: auto; font: 800 15px 'Orbitron', sans-serif; color: var(--gold); flex: none; }

/* ── Import wishlist Steam (mockup-wishlist-steam-import.html, retour de
   Tim 2026-08-31) ─────────────────────────────────────────────────────── */
.an-head-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.wl-import-btn {
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(102, 192, 244, .14); border: 1px solid rgba(102, 192, 244, .5);
  border-radius: 999px; color: var(--steam); font: 700 13px 'Rajdhani', sans-serif;
  letter-spacing: .5px; text-transform: uppercase; padding: 9px 18px 9px 14px; cursor: pointer;
  transition: all .18s;
}
.wl-import-btn:hover { background: rgba(102, 192, 244, .24); }
.wl-import-btn:disabled { opacity: .45; cursor: default; background: var(--panel); border-color: var(--line); color: var(--muted); }
.wl-import-btn .spin { animation: wl-spin 1s linear infinite; display: inline-block; }
@keyframes wl-spin { to { transform: rotate(360deg); } }

.wl-steam-hint { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12.5px; margin: -10px 0 16px; }
.wl-steam-hint a { color: var(--accent-2); text-decoration: none; }
.wl-steam-hint a:hover { text-decoration: underline; }
.wl-steam-hint.hidden { display: none; }

.wl-import-summary {
  display: flex; align-items: center; gap: 12px; background: rgba(0, 229, 195, .08);
  border: 1px solid rgba(0, 229, 195, .35); border-radius: 12px; padding: 12px 18px;
  margin: 0 0 20px; font-size: 13.5px; color: var(--text-2);
}
.wl-import-summary.hidden { display: none; }
.wl-import-summary .ic { font-size: 18px; flex: none; }
.wl-import-summary strong { color: var(--text); }
.wl-import-summary .unresolved { color: var(--muted); }

.wl-unresolved-block {
  background: rgba(255, 185, 56, .06); border: 1px solid rgba(255, 185, 56, .3);
  border-radius: 12px; padding: 14px 16px; margin: 0 0 20px;
}
.wl-unresolved-block.hidden { display: none; }
.wl-unresolved-head {
  display: flex; align-items: center; gap: 8px; font: 700 12.5px 'Rajdhani', sans-serif;
  letter-spacing: .4px; color: var(--gold); margin-bottom: 10px;
}
.wl-unresolved-row { display: flex; align-items: center; gap: 14px; padding: 8px 10px; border-radius: 10px; transition: background .15s; }
.wl-unresolved-row:hover { background: rgba(255, 255, 255, .03); }
.wl-unresolved-row + .wl-unresolved-row { margin-top: 2px; }
.wl-unresolved-thumb { width: 92px; height: 43px; border-radius: 6px; object-fit: cover; flex: none; background: var(--bg-2); }
.wl-unresolved-main { flex: 1; min-width: 0; }
.wl-unresolved-name { font: 700 14px 'Rajdhani', sans-serif; }
.wl-unresolved-sub { color: var(--muted); font-size: 11.5px; }
.wl-unresolved-identify {
  flex: none; background: none; border: 1px solid rgba(255, 185, 56, .5); border-radius: 8px;
  color: var(--gold); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .4px;
  text-transform: uppercase; padding: 7px 12px; cursor: pointer; transition: all .18s;
}
.wl-unresolved-identify:hover { background: rgba(255, 185, 56, .12); }
.wl-unresolved-ignore {
  flex: none; background: none; border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .4px;
  text-transform: uppercase; padding: 7px 12px; cursor: pointer; transition: all .18s;
}
.wl-unresolved-ignore:hover { color: var(--text); border-color: var(--text-2); }
/* Deux boutons au lieu d'un : sur un écran étroit, le nom du jeu se retrouvait
   écrasé en colonne de trois mots — la ligne passe alors sur deux rangées. */
@media (max-width: 560px) {
  .wl-unresolved-row { flex-wrap: wrap; }
  .wl-unresolved-main { flex: 1 1 calc(100% - 106px); }
  .wl-unresolved-identify, .wl-unresolved-ignore { margin-top: 4px; }
}

/* Jeux sortis de la wishlist Steam, proposés au retrait après un réimport
   (mockup mockup-wishlist-import-retraits.html, 2026-09-16). */
.wl-gone-block {
  background: rgba(255, 84, 112, .06); border: 1px solid rgba(255, 84, 112, .3);
  border-radius: 12px; padding: 14px 16px; margin: 0 0 20px;
}
.wl-gone-block.hidden { display: none; }
.wl-gone-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.wl-gone-title { font: 700 12.5px 'Rajdhani', sans-serif; letter-spacing: .4px; color: var(--danger); }
.wl-gone-sub { color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif; margin: -4px 0 10px; }
.wl-gone-names { display: flex; flex-wrap: wrap; gap: 6px; }
.wl-gone-chip {
  display: inline-flex; align-items: center; gap: 6px; background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 10px; color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif;
}
.wl-gone-chip.off { opacity: .4; text-decoration: line-through; }
.wl-gone-chip button { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 12px; padding: 0; }
.wl-gone-chip button:hover { color: var(--text); }
.wl-gone-remove {
  flex: none; background: none; border: 1px solid rgba(255, 84, 112, .5); border-radius: 8px;
  color: var(--danger); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .4px;
  text-transform: uppercase; padding: 7px 12px; cursor: pointer; transition: all .18s;
}
.wl-gone-remove:hover { background: rgba(255, 84, 112, .12); }

.wl-subsection-label {
  display: flex; align-items: center; gap: 8px; font: 700 12px 'Rajdhani', sans-serif;
  letter-spacing: 1.2px; text-transform: uppercase; color: var(--muted);
  margin: 22px 0 12px;
}
.wl-subsection-label.hidden { display: none; }
.wl-subsection-count { color: var(--muted); font-weight: 600; text-transform: none; letter-spacing: 0; }
.wl-subsection-label.steam { color: var(--steam); }
.wl-subsection-label.steam .wl-subsection-count { color: var(--steam); opacity: .75; }
.wl-steam-icon { width: 18px; height: 18px; flex: none; vertical-align: -3px; }

/* Repliable (retour de Tim, 2026-08-31) — même anneau de focus que les
   autres éléments non natifs rendus cliquables (.card, .section-title). */
.wl-subsection-label.steam { cursor: pointer; }
.wl-subsection-label.steam:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.wl-subsection-chevron { display: inline-block; transition: transform .18s; flex: none; }
.wl-subsection-label.collapsed .wl-subsection-chevron { transform: rotate(-90deg); }

/* ═══ Amis & comparaison (tâche #49, mockup docs/mockups/mockup-friends.html,
   validé par Tim le 2026-09-13) ═══════════════════════════════════════════
   Décisions : partage jeu par jeu SANS la curation (tags/listes/masqués),
   amitié = demande + acceptation, découverte par code ami uniquement, lien
   d'invitation = le code ami en URL, jamais de « il/elle » (le pseudo
   partout). Vocabulaire : .fr-* (page Amis, fiche, comparaison), .tro-*
   (détail des trophées d'un jeu joueur par joueur). ──────────────────── */

/* Avatars : même repli que renderSidebarProfile (initiale sur dégradé). */
.fr-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none; overflow: hidden;
  background: linear-gradient(140deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center;
  font: 800 17px 'Orbitron', sans-serif; color: #0b0d16;
}
.fr-avatar img { width: 100%; height: 100%; object-fit: cover; }
.fr-avatar.lg { width: 64px; height: 64px; font-size: 24px; box-shadow: 0 0 20px rgba(124, 92, 255, .4); }
.fr-avatar.sm { width: 28px; height: 28px; font-size: 11px; }

/* Code ami (pill), réutilisé sur Amis et Profil */
.fr-code-pill {
  display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--bg-2); border: 1px dashed rgba(124, 92, 255, .5); border-radius: 999px;
  padding: 6px 8px 6px 14px;
}
.fr-code-pill .lbl { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1.2px; }
.fr-code { font: 700 15px 'Orbitron', sans-serif; letter-spacing: 2px; color: var(--accent-2); }
.fr-code-pill .chip { padding: 4px 10px; font-size: 11.5px; }

/* Ajouter un ami : champ code + bouton */
.fr-add-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.fr-add-row input {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font: 700 15px 'Orbitron', sans-serif; letter-spacing: 2px; text-transform: uppercase;
  padding: 9px 14px; width: 220px; outline: none;
}
.fr-add-row input:focus { border-color: var(--accent); }
.fr-add-row input::placeholder { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; letter-spacing: .5px; text-transform: none; }

/* Demandes en attente */
.fr-requests { display: grid; gap: 10px; margin-top: 8px; }
.fr-request {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px;
}
.fr-request.outgoing { opacity: .75; }
.fr-request .who { flex: 1; min-width: 160px; }
.fr-request .name { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.fr-request .meta { color: var(--muted); font-size: 12px; margin-top: 1px; }
.fr-request .actions { display: flex; gap: 8px; }
.chip.secondary-danger { border-color: rgba(255, 84, 112, .5); color: var(--danger); }
.fr-count { color: var(--muted); font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .3px; text-transform: none; }
.fr-empty { color: var(--text-2); font: 500 13.5px 'Rajdhani', sans-serif; line-height: 1.6; margin-top: 12px; max-width: 560px; }

/* Cartes amis façon jaquettes : mosaïque des 4 jeux les plus joués + avatar
   + résumé (jeux · heures · platines) + dernier jeu lancé. */
.fr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; margin-top: 12px; }
.fr-card {
  position: relative; cursor: pointer; overflow: hidden;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: transform .18s, border-color .18s, box-shadow .18s;
}
.fr-card:hover { transform: translateY(-3px); border-color: rgba(124, 92, 255, .55); box-shadow: 0 10px 30px rgba(0, 0, 0, .35), 0 0 18px rgba(124, 92, 255, .18); }
.fr-card:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.fr-card-wall { display: grid; grid-template-columns: repeat(4, 1fr); height: 92px; background: var(--bg-2); }
.fr-card-wall img { width: 100%; height: 100%; object-fit: cover; opacity: .75; }
.fr-card-body { padding: 12px 14px 14px; }
/* Pastille à côté du pseudo, sous le mur de jaquettes (retour de Tim, 2026-09-15) —
   le mockup mockup-friends.html la faisait remonter sur le mur (margin-top négatif),
   où les jaquettes (opacity .75) la peignaient par-dessus. */
.fr-card-head { display: flex; align-items: center; gap: 10px; margin-left: -6px; }
.fr-card-head .fr-avatar { border: 3px solid var(--panel); box-shadow: 0 4px 14px rgba(0, 0, 0, .4); }
.fr-card-name { flex: 1; min-width: 0; font: 700 16px 'Rajdhani', sans-serif; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-card-stats { display: flex; gap: 14px; margin-top: 10px; }
.fr-card-stat .v { font: 700 16px 'Orbitron', sans-serif; color: var(--text); }
.fr-card-stat .l { color: var(--muted); font: 600 10.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1px; }
.fr-card-recent { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.fr-card-recent img { width: 22px; aspect-ratio: 3/4; border-radius: 3px; object-fit: cover; }
.fr-card-recent .t { flex: 1; min-width: 0; font: 600 12px 'Rajdhani', sans-serif; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-card-recent .d { color: var(--muted); font-size: 11px; white-space: nowrap; flex: none; }
.fr-card-common { position: absolute; z-index: 2; top: 8px; right: 8px; background: rgba(11, 13, 22, .75); backdrop-filter: blur(4px); border: 1px solid var(--line); border-radius: 999px; color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; padding: 2px 9px; }
/* Ami qui a coupé le partage (ou moi) : carte grisée, toujours listée. */
.fr-card.private .fr-card-wall { filter: grayscale(1); opacity: .4; }
.fr-card-private-note { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 10px; }

/* Fiche d'un ami */
.fr-back { background: none; border: none; color: var(--muted); font: 700 13px 'Rajdhani', sans-serif; cursor: pointer; padding: 0; margin-bottom: 10px; }
.fr-back:hover { color: var(--text); }
.fr-hero { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.fr-hero-name { font: 800 22px 'Orbitron', sans-serif; letter-spacing: .3px; color: var(--text); }
.fr-hero-sub { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin-top: 3px; }
.fr-hero .spacer { flex: 1; }
.fr-kpis { position: relative; }   /* ancre de l'infobulle plateformes (fiche ami) */

/* Split plateformes des KPIs Jeux/Jouées : barre empilée dans la tuile
   (même encombrement quel que soit le nombre de plateformes — 2ᵉ retour de
   Tim), détail en infobulle au survol/tap de chaque segment (3ᵉ retour). */
.fr-stat-bar { display: flex; gap: 2px; height: 6px; margin-top: 8px; border-radius: 3px; }
.fr-stat-bar i { display: block; min-width: 4px; background: var(--muted); opacity: .85; border-radius: 3px; cursor: pointer; transition: transform .12s, opacity .12s; } /* min-width : une plateforme à 1 jeu sur 441 restait à 0 px, impossible à survoler */
.fr-stat-bar i:hover, .fr-stat-bar i.active { opacity: 1; transform: scaleY(1.8); }
.fr-stat-bar .steam { background: var(--steam); }
.fr-stat-bar .psn { background: var(--psn); }
.fr-stat-bar .ea { background: var(--ea); }
.fr-stat-bar .ubisoft { background: var(--ubisoft); }

.fr-featured { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; margin-top: 10px; }
.fr-featured img { width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); background: var(--bg-2); }
.fr-featured .fh { color: var(--muted); font: 700 11.5px 'Rajdhani', sans-serif; text-align: center; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-featured .fh b { color: var(--text); font: 700 12px 'Orbitron', sans-serif; }

/* Activité récente façon profil Steam : jaquette + heures + barre de succès. */
.fr-activity { display: grid; gap: 10px; margin-top: 10px; }
.fr-act {
  display: flex; align-items: center; gap: 14px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px;
}
.fr-act .lb-cover { width: 40px; }
.fr-act .lb-cover img, .fr-cmp-row .lb-cover img, .tro-detail-head .lb-cover img { width: 100%; height: 100%; object-fit: cover; }
.fr-act .info { flex: 1; min-width: 0; }
.fr-act .lb-name { font-size: 14px; }
.fr-act .sub { color: var(--muted); font-size: 12px; margin-top: 2px; }
.fr-act .prog { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.fr-act .prog .lb-bar { flex: 1; margin: 0; max-width: 220px; }
.fr-act .prog .pl { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .8px; white-space: nowrap; }
.fr-act .prog .pv { font: 700 12px 'Orbitron', sans-serif; color: var(--text); white-space: nowrap; }
.fr-act .hrs { font: 700 15px 'Orbitron', sans-serif; text-align: right; flex: none; }
.fr-act .hrs small { display: block; color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-top: 2px; letter-spacing: .3px; }

/* Comparaison tête-à-tête façon PS : deux colonnes, gagnant en turquoise. */
.fr-cmp-head { display: flex; align-items: center; justify-content: flex-end; gap: 0; margin-top: 8px; }
.fr-cmp-who { display: flex; align-items: center; gap: 8px; width: 210px; justify-content: center; padding: 6px 0; }
.fr-cmp-who .n { font: 700 13px 'Rajdhani', sans-serif; color: var(--text); }
.fr-cmp-who .tr { color: var(--gold); font: 700 12px 'Orbitron', sans-serif; margin-left: 4px; }
.fr-cmp-who + .fr-cmp-who { border-left: 1px solid var(--line); }
.fr-cmp-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.fr-cmp-count { color: var(--muted); font: 700 12.5px 'Rajdhani', sans-serif; }
.fr-cmp-sort { display: flex; align-items: center; gap: 8px; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }
.fr-cmp-sort select { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; color: var(--text); font: 600 12.5px 'Rajdhani', sans-serif; padding: 4px 8px; color-scheme: dark; }
.fr-cmp-pane { display: none; }
.fr-cmp-pane.active { display: block; }
.fr-cmp-list { display: grid; gap: 8px; margin-top: 10px; }
.fr-cmp-row {
  display: flex; align-items: center; gap: 12px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 12px; padding: 9px 14px;
}
.fr-cmp-row .lb-cover { width: 38px; }
.fr-cmp-game { flex: 1; min-width: 0; }
.fr-cmp-game .lb-name { font-size: 14px; }
.fr-cmp-game .sub { color: var(--muted); font-size: 11.5px; margin-top: 2px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pf { font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: uppercase; border-radius: 4px; padding: 1px 6px; border: 1px solid var(--line); color: var(--text-2); white-space: nowrap; }
.pf.psn { color: var(--psn); border-color: rgba(74, 127, 255, .4); }
.pf.steam { color: var(--steam); border-color: rgba(102, 192, 244, .4); }
.pf.ea { color: var(--ea); border-color: rgba(255, 71, 71, .4); }
.pf.ubisoft { color: var(--ubisoft); border-color: rgba(148, 157, 240, .45); }
.fr-cmp-side { width: 210px; flex: none; padding: 0 12px; }
.fr-cmp-side + .fr-cmp-side { border-left: 1px solid var(--line); }
.fr-cmp-side .top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.fr-cmp-side .pct { font: 700 16px 'Orbitron', sans-serif; color: var(--text); }
.fr-cmp-side .pct.win { color: var(--accent-2); }
.fr-cmp-side .pct.plat { color: var(--gold); }
.fr-cmp-side .frac { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.fr-cmp-side .lb-bar { margin-top: 5px; }
.fr-cmp-side .lb-bar-fill.plat { background: var(--gold); }
.fr-act .lb-bar-fill.plat { background: var(--gold); }
.fr-cmp-side .hrs { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 5px; }
.fr-cmp-side .hrs b { color: var(--text); font: 700 12.5px 'Orbitron', sans-serif; }
.fr-cmp-side .none { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; font-style: italic; text-align: center; padding: 10px 0; }
.fr-cmp-side .absent { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; text-align: center; padding: 4px 0; }
.fr-cmp-side .absent button { background: none; border: none; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; cursor: pointer; display: block; margin: 3px auto 0; padding: 0; }
.fr-cmp-side .absent button:hover { text-decoration: underline; }
.fr-cmp-side .hrs-only { text-align: center; padding: 6px 0; }
.fr-cmp-side .hrs-only b { font: 700 18px 'Orbitron', sans-serif; color: var(--text); }
.fr-cmp-side .hrs-only b.win { color: var(--accent-2); }
.fr-cmp-side .hrs-only small { display: block; color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-top: 2px; }
.fr-cmp-side .hrs-only .status { display: inline-block; margin-top: 4px; font: 700 10px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .8px; border-radius: 999px; padding: 1px 8px; border: 1px solid var(--line); color: var(--muted); }
.fr-cmp-side .hrs-only .status.playing { color: var(--accent-2); border-color: rgba(0, 229, 195, .4); }
.fr-cmp-side .hrs-only .status.finished { color: var(--gold); border-color: rgba(255, 184, 56, .4); }
/* Onglet Trophées : la vue PS, juste un gros % centré ; platine devant le 100%. */
.fr-cmp-side.tro { text-align: center; }
.fr-cmp-side.tro .pct { font-size: 22px; }
.fr-cmp-side.tro .lb-bar { width: 120px; margin: 5px auto 0; }
.fr-cmp-side.tro .frac { display: block; margin-top: 4px; }
.fr-cmp-side.tro .plat-icon { width: 24px; height: 24px; vertical-align: -6px; margin-right: 6px; filter: drop-shadow(0 0 6px rgba(255, 184, 56, .55)); }
.fr-tro-summary { display: flex; justify-content: flex-end; margin-top: 8px; }
.fr-tro-who { width: 210px; text-align: center; padding: 8px 0; }
.fr-tro-who + .fr-tro-who { border-left: 1px solid var(--line); }
.fr-tro-who .n { font: 700 13px 'Rajdhani', sans-serif; color: var(--text); display: flex; align-items: center; justify-content: center; gap: 8px; }
.fr-tro-who .totals { display: flex; justify-content: center; gap: 12px; margin-top: 6px; }
.fr-tro-who .tot { font: 700 14px 'Orbitron', sans-serif; color: var(--text); }
.fr-tro-who .tot.p { color: var(--gold); }
.fr-tro-who .tot small { display: block; color: var(--muted); font: 600 10px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: .8px; margin-top: 1px; }
.fr-more-row { display: flex; justify-content: center; margin-top: 14px; }
.fr-note { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 12px; }
[data-pane="trophies"] .fr-cmp-row.has-detail { cursor: pointer; transition: border-color .16s, box-shadow .16s; }
[data-pane="trophies"] .fr-cmp-row.has-detail:hover { border-color: rgba(124, 92, 255, .55); box-shadow: 0 0 14px rgba(124, 92, 255, .15); }
[data-pane="trophies"] .fr-cmp-row.has-detail:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
[data-pane="trophies"] .fr-cmp-row.has-detail .lb-name::after { content: ''; display: inline-block; width: 1.3em; height: 1.3em; margin-left: 2px; vertical-align: -.3em; background: var(--muted); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M9.5 6l6 6-6 6%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M9.5 6l6 6-6 6%22/%3E%3C/svg%3E") center / contain no-repeat; font-size: 11px; }

/* Détail des trophées d'un jeu, joueur par joueur (« lesquels il/elle a et
   pas toi et vice versa ») — réutilise .trophy-row/.tr-* de l'onglet
   Trophées du panneau détail + deux cellules par joueur. */
.tro-detail { display: none; }
.tro-detail.active { display: block; }
.tro-detail-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 10px; }
.tro-detail-head .lb-cover { width: 46px; }
.tro-detail-title { font: 700 17px 'Rajdhani', sans-serif; color: var(--text); }
.tro-detail-sub { color: var(--muted); font-size: 12px; margin-top: 2px; }
.tro-detail-head .spacer { flex: 1; }
/* Comparaison entre amis : dit sur quelle liste de trophées elle porte quand
   les deux joueurs n'ont pas les mêmes (mockup mockup-comparaison-listes-differentes.html). */
.listes-note {
  display: flex; gap: 10px; align-items: flex-start; margin-top: 12px;
  background: rgba(124, 92, 255, .08); border: 1px solid rgba(124, 92, 255, .3);
  border-radius: 10px; padding: 10px 13px;
  color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif; line-height: 1.5;
}
.listes-note .ic { font-size: 15px; flex: none; }
.listes-note b { color: var(--text); }
.tro-players { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.tro-player {
  display: flex; align-items: center; gap: 12px;
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 16px;
}
.tro-player .n { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.tro-player .pct { font: 700 22px 'Orbitron', sans-serif; color: var(--text); margin-left: auto; }
.tro-player .pct.win { color: var(--accent-2); }
.tro-player .frac { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.tro-player .tiers { display: flex; gap: 10px; margin-left: 8px; }
.tro-player .tier { display: flex; align-items: center; gap: 4px; color: var(--text-2); font: 700 12px 'Orbitron', sans-serif; }
.tro-player .tier img { width: 16px; height: auto; }
.tro-player .tier.miss { opacity: .35; }
.tro-filters { margin-top: 14px; }
.tro-filters .chip .cnt { margin-left: 6px; font: 700 11px 'Orbitron', sans-serif; color: var(--accent-2); }
.tro-cols { display: flex; justify-content: flex-end; margin-top: 12px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.tro-cols .col { width: 124px; text-align: center; color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.tro-cmp-row .tr-rarity { width: 52px; margin-left: 6px; }
.tr-cmp-cell { width: 124px; flex: none; text-align: center; }
.tr-cmp-cell .chk { display: block; font: 800 15px 'Orbitron', sans-serif; }
.tr-cmp-cell .dt { display: block; font: 600 11px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 1px; }
.tr-cmp-cell.got .chk { color: var(--accent-2); }
.tr-cmp-cell.miss .chk { color: var(--muted); opacity: .6; }
/* Un seul des deux a le trophée : la ligne reste bien visible (pas de
   not-earned grisé), liseré côté joueur qui l'a. */
.tro-cmp-row { padding-left: 10px; border-left: 3px solid transparent; }
.tro-cmp-row.only-them { border-left-color: var(--accent); }
.tro-cmp-row.only-me { border-left-color: var(--accent-2); }
.tro-cmp-row.none { opacity: .5; }
.tro-cmp-row.filtered-out { display: none; }
/* Hauteur d'un écran minimum : filtrer 34 → 5 lignes ne raccourcit plus la
   page, donc le navigateur ne remonte plus tout seul (retour de Tim). */
.tro-detail .trophy-list { min-height: 100vh; }
.tro-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 8px; color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.tro-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: -1px; margin-right: 5px; }

/* Profil : section « Amis & partage » */
.fr-code-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.fr-toggle-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.fr-toggle { position: relative; width: 44px; height: 24px; border-radius: 999px; background: linear-gradient(120deg, var(--accent), var(--accent-2)); flex: none; cursor: pointer; border: none; padding: 0; }
.fr-toggle::after { content: ''; position: absolute; top: 3px; left: 23px; width: 18px; height: 18px; border-radius: 50%; background: #0b0d16; transition: left .15s; }
.fr-toggle.off { background: var(--bg-2); border: 1px solid var(--line); }
.fr-toggle.off::after { left: 2px; top: 2px; background: var(--muted); }
.fr-toggle:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* flex:1 + min-width:0 : sans ça, un texte long passe SOUS l'interrupteur
   dès que la carte est étroite (mobile, mockup à 720px) au lieu de rester
   à côté. */
.fr-toggle-text { flex: 1; min-width: 0; }
.fr-toggle-text .t { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.fr-toggle-text .d { color: var(--text-2); font: 500 12.5px 'Rajdhani', sans-serif; line-height: 1.5; margin-top: 2px; max-width: 560px; }
.fr-shared-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 6px 18px; margin-top: 10px; color: var(--text-2); font: 500 12.5px 'Rajdhani', sans-serif; }
.fr-shared-list .ok::before { content: '✓ '; color: var(--accent-2); font-weight: 700; }
.fr-shared-list .no::before { content: ''; display: inline-block; width: 1.1em; height: 1.1em; margin-right: 4px; vertical-align: -.2em; background: var(--danger); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M6 6l12 12M18 6 6 18%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M6 6l12 12M18 6 6 18%22/%3E%3C/svg%3E") center / contain no-repeat; }
.fr-shared-list .no { color: var(--muted); }

/* Arrivée par lien d'invitation (?invite=…) dans la .login-box */
.fr-invite-by { display: flex; align-items: center; justify-content: center; gap: 10px; margin: -4px 0 12px; }
.fr-invite-by .fr-avatar { width: 36px; height: 36px; font-size: 14px; }
.fr-invite-by-text { font: 600 15px 'Rajdhani', sans-serif; color: var(--text-2); }
.fr-invite-by-text b { color: var(--text); font-weight: 700; }

@media (max-width: 700px) {
  .fr-cmp-head { display: none; }
  .fr-cmp-row { flex-wrap: wrap; }
  .fr-cmp-game { flex-basis: 100%; }
  .fr-cmp-side { flex: 1; width: auto; padding: 0; }
  .fr-cmp-side + .fr-cmp-side { border-left: none; }
  .fr-cmp-side::before { content: attr(data-who); display: block; color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 3px; }
  .fr-tro-summary { justify-content: space-between; }
  .fr-tro-who { width: auto; flex: 1; }
  .tro-players { grid-template-columns: 1fr; }
  .tro-player .tiers { display: none; }
  .tro-cols .col, .tr-cmp-cell { width: 84px; }
  .tro-cmp-row .tr-rarity { display: none; }
}

/* ═══ Bonus (idée de Tim, 2026-09-13) : au survol d'une ligne ou d'une carte,
   sa barre de progression « s'illumine » — reflet qui la balaie façon
   chargement + halo. Sur tout le dashboard : .lb-bar-fill (Leaderboards,
   comparaison entre amis, activité d'un ami) et .ttb-fill (cartes de jeux,
   barre vs référence IGDB). Coupé par prefers-reduced-motion. ═══════════ */
.lb-bar-fill, .ttb-fill { overflow: hidden; }
.lb-bar-fill::after, .ttb-fill::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, .55) 50%, transparent 100%);
  transform: translateX(-100%);
}
.lb-row:hover .lb-bar-fill, .fr-cmp-row:hover .lb-bar-fill, .fr-act:hover .lb-bar-fill {
  box-shadow: 0 0 10px rgba(0, 229, 195, .55), 0 0 2px rgba(255, 255, 255, .4);
}
.lb-row:hover .lb-bar-fill::after, .fr-cmp-row:hover .lb-bar-fill::after, .fr-act:hover .lb-bar-fill::after,
.card:hover .ttb-fill::after {
  animation: bar-shine 1.1s ease-in-out infinite;
}
@keyframes bar-shine {
  0% { transform: translateX(-100%); }
  60%, 100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .lb-bar-fill::after, .ttb-fill::after { animation: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   Page Actualités (mockup docs/mockups/mockup-news-feed.html, 2026-09-13)
   — fil groupé par jeu. Préfixe nf-. Point de couleur constant : turquoise
   = mise à jour, violet = annonce éditeur, gris clair = presse.
   ═══════════════════════════════════════════════════════════════════ */
.nf-loading { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; margin: 14px 0; }
.nf-filters { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 12px 0 4px; }
.nf-filters .spacer { flex: 1; }
.nf-kind-chip { display: inline-flex; align-items: center; gap: 6px; }
.nf-kind-chip::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.nf-kind-chip.patch::before { background: var(--accent-2); }
.nf-kind-chip.ann::before { background: var(--accent); }
.nf-kind-chip.press::before { background: var(--text-2); }
.nf-kind-chip.off { opacity: .45; text-decoration: line-through; }
.nf-search-wrap { position: relative; flex: 1 1 240px; max-width: 360px; }
.nf-search {
  width: 100%; box-sizing: border-box; background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px;
  color: var(--text); font: 600 13px 'Rajdhani', sans-serif; padding: 7px 30px 7px 34px; outline: none;
}
.nf-search::placeholder { color: var(--muted); }
.nf-search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(124,92,255,.18); }
.nf-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 13px; pointer-events: none; }
.nf-search-clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; padding: 2px 4px; }
.nf-search-clear:hover { color: var(--text); }
.nf-results { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; margin: 12px 0 0; }
.nf-results b { color: var(--accent-2); }
mark.nf-mark { background: rgba(0,229,195,.22); color: inherit; border-radius: 3px; padding: 0 1px; }
.nf-game-title .name mark.nf-mark { background: rgba(124,92,255,.35); }

/* Bande de jaquettes : les jeux en cours qui ont bougé cette semaine — en
   grand et centrée (retour de Tim, 2026-09-13, juste après livraison :
   « aérer le haut de la page et créer de la séparation avec les articles »). */
.nf-strip { display: flex; flex-direction: column; align-items: center; gap: 12px; margin: 22px 0 30px; }
.nf-strip-label { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.6px; text-transform: uppercase; }
/* Centré par marges auto, pas par justify-content : centrer un flex qui déborde
   (mobile) coupe le premier élément et l'empêche de défiler jusqu'à lui. */
.nf-strip-items { display: flex; gap: 18px; overflow-x: auto; padding: 8px 6px; max-width: 100%; scrollbar-width: none; }
.nf-strip-item:first-child { margin-left: auto; }
.nf-strip-item:last-child { margin-right: auto; }
.nf-strip-item { position: relative; flex: none; width: 92px; height: 123px; border-radius: 10px; cursor: pointer; background: none; border: none; padding: 0; }
.nf-strip-item img { width: 92px; height: 123px; border-radius: 10px; object-fit: cover; border: 1px solid var(--line); display: block; box-shadow: 0 12px 28px rgba(0,0,0,.45); transition: transform .18s, box-shadow .18s; }
.nf-strip-item:hover img, .nf-strip-item:focus-visible img { transform: translateY(-4px); box-shadow: 0 18px 34px rgba(0,0,0,.55), 0 0 0 1px var(--accent); }
.nf-strip-item .cnt { position: absolute; top: -8px; right: -8px; min-width: 24px; height: 24px; padding: 0 7px; border-radius: 999px; background: var(--accent-2); color: #0b0d16; font: 800 11.5px 'Orbitron', sans-serif; display: flex; align-items: center; justify-content: center; box-shadow: 0 3px 10px rgba(0,0,0,.5); }
.nf-strip-item .cnt.has-patch { background: linear-gradient(120deg, var(--accent), var(--accent-2)); }
.nf-game.nf-flash { box-shadow: 0 0 0 2px var(--accent-2); }

/* Deux sections empilées */
.nf-sec { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line); }
.nf-sec.first { margin-top: 14px; padding-top: 0; border-top: none; }
.nf-sec-title { font: 700 13px 'Orbitron', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--text); }
.nf-sec-title .n { font: 600 12.5px 'Rajdhani', sans-serif; letter-spacing: .3px; text-transform: none; color: var(--muted); margin-left: 6px; }
.nf-rest-toggle { margin: 0; }
.nf-sec + .nf-list { margin-top: 12px; }

/* Un groupe = un jeu */
.nf-list { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.nf-game { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px 12px; transition: box-shadow .3s; }
.nf-game-head { display: flex; align-items: center; gap: 12px; }
.nf-cover-btn { flex: none; background: none; border: none; padding: 0; cursor: pointer; border-radius: 6px; }
.nf-cover { width: 44px; height: 59px; border-radius: 6px; object-fit: cover; display: block; background: var(--bg-2); border: 1px solid var(--line); }
.nf-cover-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.nf-game-head .grow { flex: 1; min-width: 0; }
.nf-game-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nf-game-title .name { font: 700 16px 'Rajdhani', sans-serif; color: var(--text); }
.nf-game-meta { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 3px; }
.nf-game-meta b { color: var(--text-2); font-weight: 700; }
.nf-open { background: none; border: none; padding: 0; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; cursor: pointer; white-space: nowrap; }
.nf-open:hover { text-decoration: underline; }
.pill.nf-idle { color: var(--muted); border-color: var(--line); }

/* Items */
.nf-items { margin-top: 8px; }
.nf-item { display: grid; grid-template-columns: 18px 1fr; gap: 0 10px; padding: 9px 0; border-top: 1px solid var(--line); }
.nf-items > .nf-item:first-child { border-top: none; }
.nf-dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 7px; justify-self: center; background: var(--muted); }
.nf-item.patch .nf-dot { background: var(--accent-2); box-shadow: 0 0 8px rgba(0,229,195,.5); }
.nf-item.ann .nf-dot { background: var(--accent); }
.nf-item.press .nf-dot { background: var(--text-2); }
.nf-item-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.nf-title { color: var(--text); font: 700 14px 'Rajdhani', sans-serif; text-decoration: none; min-width: 0; }
.nf-title::after { content: ' ↗'; color: var(--muted); font-size: 11px; font-weight: 600; }
.nf-title:hover { color: var(--accent-2); }
.nf-meta { color: var(--muted); font-size: 11.5px; white-space: nowrap; display: inline-flex; gap: 6px; align-items: center; }
.nf-kind { font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; }
.nf-item.patch .nf-kind { color: var(--accent-2); }
.nf-item.ann .nf-kind { color: var(--accent); }
.nf-item.press .nf-kind { color: var(--text-2); }
.nf-excerpt { color: var(--text-2); font-size: 13px; line-height: 1.45; margin: 3px 0 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.nf-promo { font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 1px 7px; }
/* Grosse mise à jour, sur le fil de la page Actualités — même marquage que
   .pn-major-tag côté fiche (mockup mockup-grosses-maj.html). */
.nf-major-tag { font: 800 9.5px 'Orbitron', sans-serif; letter-spacing: .6px; text-transform: uppercase; color: var(--accent-2); border: 1px solid rgba(0,229,195,.45); border-radius: 999px; padding: 2px 7px; }
.nf-item.pn-major { border-left: 2px solid var(--accent-2); padding-left: 9px; background: linear-gradient(90deg, rgba(0,229,195,.055), transparent 45%); }
.nf-new { font: 800 9.5px 'Orbitron', sans-serif; color: #0b0d16; background: var(--accent-2); border-radius: 999px; padding: 2px 6px; letter-spacing: .5px; }

/* Plis : « ▾ N autres cette semaine » / « ▾ N plus anciens ce mois » */
.nf-more { margin-top: 6px; display: flex; gap: 8px; flex-wrap: wrap; }
.nf-more .wl-load-more { margin: 4px 0 0; }
.nf-earlier { margin-top: 4px; }
.nf-sub { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; padding: 10px 0 2px 28px; }

/* Filtre par source */
.nf-src-wrap { position: relative; }
#news-src-btn.filtered { border-color: var(--accent); color: var(--text); background: rgba(124,92,255,.15); }
.nf-src-pop { position: absolute; top: calc(100% + 6px); left: 0; z-index: 20; min-width: 250px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 8px; box-shadow: 0 16px 40px rgba(0,0,0,.55); }
.nf-src-pop .row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; cursor: pointer; color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.nf-src-pop .row:hover { background: rgba(124,92,255,.12); }
.nf-src-pop .row .cnt { margin-left: auto; color: var(--muted); font-size: 12px; }
.nf-src-pop .row input { accent-color: var(--accent); }
.nf-src-pop .row.head { color: var(--muted); font-size: 11px; letter-spacing: 1px; text-transform: uppercase; cursor: default; padding-top: 4px; }
.nf-src-pop .row.head:hover { background: none; }
.nf-src-pop .row.head button { margin-left: auto; background: none; border: none; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; cursor: pointer; text-transform: none; letter-spacing: 0; }
.nf-src-pop .sep { height: 1px; background: var(--line); margin: 4px 0; }

/* Jeux joués sans actualité, état vide */
.nf-quiet { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin: 16px 0 0; line-height: 1.6; }
.nf-quiet b { color: var(--text-2); }
.nf-rest-hint { margin-top: 8px; }
.nf-empty { background: var(--panel); border: 1px dashed var(--line); border-radius: var(--radius); padding: 34px 20px; text-align: center; margin-top: 14px; }
.nf-empty .big { font: 700 18px 'Orbitron', sans-serif; color: var(--text); margin-bottom: 8px; letter-spacing: .5px; }
.nf-empty p { color: var(--text-2); font-size: 13.5px; margin: 0; }

/* Actualités — jeux attendus (wishlist) : compte à rebours à la place du statut */
.pill.nf-upcoming { color: var(--gold); border-color: rgba(255,185,56,.5); background: rgba(255,185,56,.08); }
.pill.nf-tba { color: var(--muted); border-color: var(--line); }
/* Bloc « Actualité » de l'écran wishlist : mêmes lignes que la page */
.wl-news { margin-top: 4px; }
.wl-news .nf-item { padding: 8px 0; }
.wl-news .nf-item:first-child { border-top: none; }
.wl-news-count { color: var(--muted); letter-spacing: 0; text-transform: none; font-weight: 600; }
.wl-news-more { margin-top: 8px; }
.wl-news-more .wl-load-more { margin: 0; }

/* ═══ Actualités — « À la une » (mockup mockup-news-highlights.html, 2026-09-14) :
   panneau distinct, carrousel (mêmes classes .wl-carousel-* que la Wishlist)
   + rail des sujets ; puis en-tête « Sur tes jeux » pour la partie perso. ═══ */
.hl { margin: 14px 0 0; padding: 18px 20px 16px; background: var(--panel); border: 1px solid rgba(124,92,255,.28); border-radius: var(--radius); box-shadow: 0 0 0 1px rgba(124,92,255,.06), 0 18px 40px rgba(0,0,0,.35); }
.hl-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.hl-title { font: 700 14px 'Orbitron', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--text); }
/* Pictogramme en masque CSS (pas de balise : le titre est posé par du CSS pur) — même dessin que icons.js. */
.hl-title::before { content: ''; display: inline-block; width: 1.35em; height: 1.35em; margin-right: 8px; vertical-align: -.3em; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath fill=%22currentColor%22 fill-opacity=%22.18%22 d=%22M4 5h12v13.5a1.5 1.5 0 0 0 1.5 1.5H6A2 2 0 0 1 4 18z%22/%3E%3Cpath d=%22M16 9h4v9.5a1.5 1.5 0 0 1-3 0%22/%3E%3Cpath d=%22M7 9h6M7 12.5h6M7 16h4%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath fill=%22currentColor%22 fill-opacity=%22.18%22 d=%22M4 5h12v13.5a1.5 1.5 0 0 0 1.5 1.5H6A2 2 0 0 1 4 18z%22/%3E%3Cpath d=%22M16 9h4v9.5a1.5 1.5 0 0 1-3 0%22/%3E%3Cpath d=%22M7 9h6M7 12.5h6M7 16h4%22/%3E%3C/svg%3E") center / contain no-repeat; }
.hl-title .n { font: 600 12.5px 'Rajdhani', sans-serif; letter-spacing: .3px; text-transform: none; color: var(--muted); margin-left: 6px; }
.hl-sub { color: var(--text-2); font-size: 12.5px; margin: 0 0 10px; }
.hl-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.hl-chips .chip .n { color: var(--muted); font-weight: 600; margin-left: 4px; }
.hl-chips .chip.active .n { color: inherit; opacity: .8; }
.hl-stage { display: grid; grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr); gap: 14px; }
.hl-caro { position: relative; height: 380px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); background: var(--panel-2); }
.hl-caro .wl-carousel-track { position: relative; width: 100%; height: 100%; }
.hl-slide { position: absolute; inset: 0; display: flex; align-items: flex-end; background: var(--panel-2) center 30%/cover no-repeat; opacity: 0; transition: opacity .5s ease; pointer-events: none; }
.hl-slide.active { opacity: 1; pointer-events: auto; }
.hl-slide::before { content: ''; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(11,13,22,.96) 0%, rgba(11,13,22,.55) 45%, rgba(11,13,22,.12) 100%), linear-gradient(90deg, rgba(11,13,22,.6) 0%, transparent 60%); }
.hl-slide-content { position: relative; z-index: 1; padding: 0 60px 26px 66px; max-width: 700px; }
.hl-slide-top { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.hl-slide-title { display: block; color: var(--text); font: 900 22px/1.2 'Orbitron', sans-serif; letter-spacing: .3px; text-decoration: none; text-shadow: 0 2px 12px rgba(0,0,0,.7); margin: 0 0 8px; }
.hl-slide-title:hover { color: var(--accent-2); }
.hl-slide-excerpt { color: var(--text-2); font-size: 13.5px; line-height: 1.45; margin: 0 0 12px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hl-slide-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; color: var(--muted); font-size: 12px; margin-bottom: 14px; }
.hl-slide-meta a { color: var(--text-2); font-weight: 700; text-decoration: none; }
.hl-slide-meta a:hover { color: var(--accent-2); text-decoration: underline; }
.hl-slide-meta .lead-src { color: var(--accent-2); }
.hl-slide-actions .chip { padding: 9px 16px; font-size: 13px; text-decoration: none; display: inline-flex; }
.hl-caro .wl-carousel-arrow { width: 38px; height: 38px; font-size: 18px; }
.hl-caro .wl-carousel-arrow.prev { left: 14px; }
.hl-caro .wl-carousel-arrow.next { right: 14px; }
.hl-caro .wl-carousel-dots { bottom: 14px; right: 18px; }
.hl-plat { display: inline-flex; gap: 4px; }
.hl-plat span { font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--text); background: rgba(11,13,22,.7); border: 1px solid rgba(255,255,255,.14); border-radius: 999px; padding: 2px 8px; backdrop-filter: blur(4px); }
.hl-plat span.playstation { color: #8fb0ff; }
.hl-plat span.xbox { color: #7ee787; }
.hl-plat span.nintendo { color: #ff7b7b; }
.hl-plat span.pc { color: var(--steam); }
.hl-plat span.general { color: var(--text-2); }
.hl-src-n { font: 800 10px 'Orbitron', sans-serif; color: #0b0d16; background: var(--accent-2); border-radius: 999px; padding: 3px 8px; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.hl-src-n.hot { background: linear-gradient(120deg, var(--accent), var(--accent-2)); }
.hl-rail { display: flex; flex-direction: column; gap: 6px; max-height: 380px; overflow-y: auto; padding-right: 2px; scrollbar-width: thin; }
.hl-rail-item { display: grid; grid-template-columns: 64px 1fr; gap: 10px; align-items: center; padding: 6px; border-radius: 10px; border: 1px solid transparent; background: none; text-align: left; cursor: pointer; color: var(--text); }
.hl-rail-item:hover { background: rgba(124,92,255,.08); }
.hl-rail-item.active { background: rgba(124,92,255,.14); border-color: rgba(124,92,255,.5); }
.hl-rail-item:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 1px; }
.hl-rail-thumb { width: 64px; height: 44px; border-radius: 6px; object-fit: cover; background: var(--bg-2); border: 1px solid var(--line); }
.hl-rail-title { font: 700 12.5px/1.25 'Rajdhani', sans-serif; color: var(--text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hl-rail-meta { color: var(--muted); font-size: 11px; margin-top: 2px; }
.hl-rail-meta b { color: var(--accent-2); font-weight: 700; }
.hl-empty { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; padding: 18px 0; text-align: center; }
@media (max-width: 900px) {
  .hl-stage { grid-template-columns: 1fr; }
  .hl-caro { height: 300px; }
  .hl-slide-content { padding: 0 56px 22px 56px; }
  .hl-slide-title { font-size: 17px; }
  .hl-rail { max-height: none; flex-direction: row; overflow-x: auto; }
  .hl-rail-item { flex: 0 0 220px; }
}
/* En-tête de la partie personnalisée */
.mine-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 36px 0 0; padding-top: 22px; border-top: 1px solid var(--line); }
#news-hl.hidden + .mine-head { margin-top: 10px; padding-top: 0; border-top: none; }
.mine-title { font: 700 14px 'Orbitron', sans-serif; letter-spacing: .8px; text-transform: uppercase; color: var(--text); }
.mine-title::before { content: ''; display: inline-block; width: 1.35em; height: 1.35em; margin-right: 8px; vertical-align: -.3em; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath fill=%22currentColor%22 fill-opacity=%22.18%22 d=%22M7 7h10a4.5 4.5 0 0 1 4.4 5.4l-.7 3.6a2.7 2.7 0 0 1-4.6 1.4L14.5 16h-5l-1.6 1.4A2.7 2.7 0 0 1 3.3 16l-.7-3.6A4.5 4.5 0 0 1 7 7z%22/%3E%3Cpath d=%22M8 10v4M6 12h4%22/%3E%3Ccircle fill=%22currentColor%22 stroke=%22none%22 cx=%2215.5%22 cy=%2211%22 r=%22.9%22/%3E%3Ccircle fill=%22currentColor%22 stroke=%22none%22 cx=%2217.5%22 cy=%2213%22 r=%22.9%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.75%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath fill=%22currentColor%22 fill-opacity=%22.18%22 d=%22M7 7h10a4.5 4.5 0 0 1 4.4 5.4l-.7 3.6a2.7 2.7 0 0 1-4.6 1.4L14.5 16h-5l-1.6 1.4A2.7 2.7 0 0 1 3.3 16l-.7-3.6A4.5 4.5 0 0 1 7 7z%22/%3E%3Cpath d=%22M8 10v4M6 12h4%22/%3E%3Ccircle fill=%22currentColor%22 stroke=%22none%22 cx=%2215.5%22 cy=%2211%22 r=%22.9%22/%3E%3Ccircle fill=%22currentColor%22 stroke=%22none%22 cx=%2217.5%22 cy=%2213%22 r=%22.9%22/%3E%3C/svg%3E") center / contain no-repeat; }
.mine-sub { color: var(--text-2); font-size: 12.5px; margin: 6px 0 0; }

/* ══════════════════════════════════════════════════════════════════════
   Page Analyses (mockup validé docs/mockups/mockup-analyses.html,
   2026-09-15). Classes préfixées ana- (.card, .chart, .legend… existent
   déjà ailleurs).
   ══════════════════════════════════════════════════════════════════════ */
.ana-page { padding: 22px 32px 50px; }
@media (max-width: 700px) { .ana-page { padding: 16px 16px 40px; } }
.ana-page-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.ana-h1 { font: 900 24px 'Orbitron', sans-serif; letter-spacing: 2px; margin: 0; }
.ana-page-head p { color: var(--text-2); margin: 6px 0 0; font-size: 14px; }
.ana-card { background: linear-gradient(160deg, var(--panel-2), var(--panel)); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.ana-card-title { font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; margin: 0 0 14px; display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ana-card-extra { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; text-transform: none; letter-spacing: 0; }
.ana-muted { color: var(--muted); }
.ana-small { font-size: 12px; margin: 10px 0 0; }
.ana-sublabel { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; margin: 16px 0 8px; }
.ana-loading { margin-top: 18px; }
.ana-tip { display: none; left: 50%; top: -6px; }
.ana-nocover { display: inline-block; width: 30px; aspect-ratio: 3/4; border-radius: 4px; background: var(--bg-2); border: 1px solid var(--line); flex: none; }

/* 1. Plateformes en grand + filtre */
.ana-hero { margin-top: 18px; }
.ana-hero-total { display: flex; gap: 28px; flex-wrap: wrap; align-items: baseline; margin-bottom: 14px; }
.ana-hero-total > div { font: 800 30px 'Orbitron', sans-serif; }
.ana-hero-total span { display: block; color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.5px; text-transform: uppercase; margin-top: 2px; }
.ana-filter-hint { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 10px; color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.ana-f-clear { background: var(--bg-2); border: 1px solid var(--line); color: var(--text); font: 700 12px 'Rajdhani', sans-serif; padding: 5px 11px; border-radius: 999px; cursor: pointer; }
.ana-f-clear:hover { border-color: var(--accent-2); }
.ana-plats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.ana-plat {
  --c: var(--muted);
  position: relative; overflow: hidden; text-align: center; padding: 20px 12px 16px; cursor: pointer; user-select: none;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 16%, transparent), transparent 70%), linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); transition: border-color .15s, transform .15s, opacity .15s;
}
.ana-plat:hover { border-color: var(--c); transform: translateY(-2px); box-shadow: 0 10px 30px -12px var(--c); }
.ana-plat:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.ana-plat.on { border-color: var(--c); box-shadow: 0 0 0 1px var(--c) inset, 0 10px 30px -12px var(--c); }
.ana-plat.off { opacity: .42; filter: grayscale(.7); }
.ana-plat.off:hover { opacity: .8; filter: none; }
.ana-plat-check { position: absolute; top: 8px; right: 8px; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font: 800 11px 'Rajdhani', sans-serif; color: #0b0d16; background: var(--c); opacity: 0; transform: scale(.6); transition: .15s; }
.ana-plat.on .ana-plat-check { opacity: 1; transform: none; }
.ana-plat-logo { height: 58px; display: flex; align-items: center; justify-content: center; color: var(--c); }
.ana-plat-logo .ana-plat-svg { height: 52px; width: auto; filter: drop-shadow(0 0 14px color-mix(in srgb, var(--c) 55%, transparent)); }
.ana-plat-logo .ana-plat-img { height: 50px; width: auto; filter: invert(1); }
.ana-plat-mono { font: 900 30px 'Orbitron', sans-serif; letter-spacing: 1px; text-shadow: 0 0 16px color-mix(in srgb, var(--c) 60%, transparent); }
.ana-plat-name { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; margin-top: 8px; }
.ana-plat-count { font: 900 34px 'Orbitron', sans-serif; margin-top: 4px; line-height: 1; }
.ana-plat-count small { font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); margin-left: 3px; }
.ana-plat-hours { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; margin-top: 6px; }
.ana-plat-hours b { font: 700 13px 'Orbitron', sans-serif; color: var(--text); }
.ana-plat-avg { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 3px; }
.ana-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; color: var(--muted); font-size: 12px; }
.ana-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }

.ana-fbar { position: fixed; top: 10px; left: 50%; transform: translate(-50%, -160%); z-index: 900; display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 14px; border-radius: 999px; background: rgba(21,26,44,.94); border: 1px solid var(--line); box-shadow: 0 10px 30px -10px rgba(0,0,0,.7); transition: transform .25s; max-width: calc(100% - 32px); }
.ana-fbar.show { transform: translate(-50%, 0); }
#view-analyses.hidden .ana-fbar, #view-analyses.ana-editing .ana-fbar { display: none; }
.ana-fbar-lbl { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; }
.ana-fbar-logos { display: flex; gap: 4px; overflow-x: auto; }
.ana-fbar-logo { --c: var(--muted); width: 34px; height: 30px; border-radius: 9px; border: 1px solid transparent; background: none; color: var(--c); display: grid; place-items: center; cursor: pointer; opacity: .55; padding: 0; flex: none; }
.ana-fbar-logo .ana-plat-svg { height: 17px; width: auto; }
.ana-fbar-logo .ana-plat-img { height: 17px; filter: invert(1); }
.ana-fbar-logo .ana-plat-mono { font-size: 10px; text-shadow: none; }
.ana-fbar-logo:hover { opacity: 1; }
.ana-fbar.filtered .ana-fbar-logo:not(.on) { opacity: .3; }
.ana-fbar-logo.on { opacity: 1; border-color: var(--c); background: color-mix(in srgb, var(--c) 18%, transparent); }
.ana-fbar #ana-fbar-clear { display: none; }
.ana-fbar.filtered #ana-fbar-clear { display: inline-block; }

.ana-src-chip { font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: .5px; color: var(--psn); background: rgba(74,127,255,.12); border: 1px solid rgba(74,127,255,.35); padding: 2px 8px; border-radius: 999px; }
/* Variante avertissement : ce bloc N'APPLIQUE PAS le filtre en cours. Le bleu
   de base le faisait passer pour un chip de plateforme actif (retour de Tim). */
.ana-src-chip.warn { color: var(--gold); background: rgba(255, 185, 56, .12); border-color: rgba(255, 185, 56, .4); }
.ana-empty { display: flex; align-items: center; justify-content: center; text-align: center; min-height: 120px; padding: 18px; border-radius: 12px; border: 1px dashed rgba(139,147,184,.3); background: repeating-linear-gradient(135deg, rgba(139,147,184,.05) 0 8px, transparent 8px 16px); color: var(--text-2); font-size: 13.5px; line-height: 1.45; }
.ana-empty b { color: var(--text); }
.ana-honest { display: flex; gap: 8px; margin-top: 14px; padding: 10px 12px; border-radius: 10px; background: var(--bg-2); border: 1px solid var(--line); color: var(--text-2); font-size: 13px; }

/* Grille de blocs — ordre exact choisi par l'utilisateur, trous compris
   (décision de Tim) : jamais de grid-auto-flow: dense. */
.ana-blocks { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; margin-top: 26px; }
.ana-blocks > [data-size="full"] { grid-column: span 6; }
.ana-blocks > [data-size="half"] { grid-column: span 3; }
.ana-blocks > [data-size="third"] { grid-column: span 2; }
@media (max-width: 1000px) { .ana-blocks > [data-size] { grid-column: span 6; } }
.ana-blocks > .ana-card { position: relative; min-width: 0; }
.ana-blocks > .ana-unavailable, .ana-blocks > .ana-user-hidden { display: none; }

/* 2. Temps de jeu */
.ana-tt-top { display: flex; justify-content: space-between; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.ana-tt-big { font: 900 40px 'Orbitron', sans-serif; line-height: 1; }
.ana-tt-big small { font: 600 15px 'Rajdhani', sans-serif; color: var(--text-2); margin-left: 6px; }
.ana-tt-big-sm { font-size: 30px; }
.ana-tt-delta { display: inline-block; margin-top: 6px; font: 700 12.5px 'Rajdhani', sans-serif; color: var(--accent-2); }
.ana-tt-ctrl { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.ana-seg { display: inline-flex; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 3px; }
.ana-seg button { background: none; border: none; color: var(--muted); font: 700 12.5px 'Rajdhani', sans-serif; padding: 6px 13px; border-radius: 7px; cursor: pointer; }
.ana-seg button.on { background: var(--panel-2); color: var(--text); box-shadow: 0 0 0 1px var(--line); }
.ana-metric-switch { display: inline-flex; background: var(--bg-2); border: 1px solid var(--line); border-radius: 999px; padding: 2px; }
.ana-metric-switch button { background: none; border: none; color: var(--muted); font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: .3px; padding: 4px 11px; border-radius: 999px; cursor: pointer; }
.ana-metric-switch button.on { background: var(--accent-2); color: #0b0d16; }
.ana-metric-switch button:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.ana-ynav { display: inline-flex; align-items: center; gap: 4px; font: 700 13px 'Orbitron', sans-serif; letter-spacing: 0; }
.ana-ynav button { background: var(--bg-2); border: 1px solid var(--line); color: var(--text); width: 28px; height: 28px; border-radius: 8px; cursor: pointer; }
.ana-ynav button:disabled { opacity: .3; cursor: default; }
.ana-chart { display: flex; align-items: flex-end; gap: 4px; margin-top: 22px; }
.ana-col { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; position: relative; }
.ana-stack { display: flex; flex-direction: column-reverse; border-radius: 4px 4px 0 0; overflow: hidden; }
.ana-stack i { display: block; transition: opacity .12s; }
.ana-col.seg-focus .ana-stack i:not(.on) { opacity: .3; }
.ana-val { text-align: center; font: 700 10px 'Orbitron', sans-serif; color: #eafffb; text-shadow: 0 0 8px #00e5c3; margin-bottom: 4px; white-space: nowrap; }
.ana-col:hover .ana-stack { box-shadow: 0 0 14px rgba(0, 229, 195, .5); }
.ana-col.sel .ana-stack { outline: 2px solid var(--accent-2); outline-offset: 1px; }
.ana-col:hover .ana-tip, .ana-gap:hover .ana-tip, .ana-hcol:hover .ana-tip { display: block; }
.ana-gap { position: relative; height: 100%; min-width: 0; border-radius: 3px; background: repeating-linear-gradient(135deg, rgba(139,147,184,.035) 0 5px, transparent 5px 10px); border-bottom: 1px dashed rgba(139,147,184,.28); }
.ana-gap:hover { background: repeating-linear-gradient(135deg, rgba(139,147,184,.09) 0 5px, transparent 5px 10px); }
.ana-gap .ana-tip { top: 40%; }
.ana-axis { display: flex; gap: 4px; margin-top: 6px; color: var(--muted); font: 600 10.5px 'Rajdhani', sans-serif; }
.ana-axis span { flex: 1; min-width: 0; text-align: center; white-space: nowrap; overflow: visible; }

/* 3. Calendrier */
.ana-heat-wrap { overflow-x: auto; }
.ana-heat { display: grid; grid-template-rows: 14px repeat(7, auto); grid-auto-flow: column; grid-auto-columns: minmax(10px, 1fr); gap: 3px; min-width: 690px; }
.ana-heat-m { font: 600 10px 'Rajdhani', sans-serif; color: var(--muted); white-space: nowrap; }
.ana-heat-d { aspect-ratio: 1; border-radius: 3px; background: rgba(120,140,255,.08); }
.ana-heat-d:hover { outline: 1px solid var(--text); }
.ana-heat-d.l1, .ana-heat-legend i.l1 { background: rgba(0,229,195,.22); }
.ana-heat-d.l2, .ana-heat-legend i.l2 { background: rgba(0,229,195,.42); }
.ana-heat-d.l3, .ana-heat-legend i.l3 { background: rgba(0,229,195,.68); }
.ana-heat-d.l4, .ana-heat-legend i.l4 { background: #00e5c3; }
.ana-heat-d.l4 { box-shadow: 0 0 6px rgba(0,229,195,.6); }
.ana-heat-d.x { background: transparent; }
.ana-heat-d.x:hover { outline: none; }
.ana-heat-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; font-size: 12.5px; }
.ana-heat-foot b { color: var(--text); }
.ana-heat-legend { display: flex; align-items: center; gap: 3px; color: var(--muted); font-size: 11.5px; }
.ana-heat-legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; background: rgba(120,140,255,.08); }
.ana-streaks { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-top: 16px; }
.ana-streak { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.ana-streak b { display: block; font: 800 20px 'Orbitron', sans-serif; }
.ana-streak span { color: var(--muted); font-size: 12px; }
.ana-streak.hot { border-color: rgba(255,185,56,.45); background: linear-gradient(160deg, rgba(255,185,56,.14), var(--bg-2)); }
.ana-streak.hot b { color: var(--gold); }

/* 4. Listes façon Strava */
.ana-kv { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.ana-kv:last-child { border-bottom: none; }
.ana-kv > span { color: var(--text-2); font-size: 14px; }
.ana-kv b { font: 700 15px 'Orbitron', sans-serif; white-space: nowrap; }
.ana-kv small { display: block; color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; text-align: right; }

/* 5. Semaine type */
.ana-dow { display: flex; align-items: flex-end; gap: 8px; height: 150px; margin-top: 6px; }
.ana-dow > div { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; gap: 5px; }
.ana-dow i { width: 100%; border-radius: 5px 5px 0 0; background: linear-gradient(180deg, #00e5c3, #7c5cff); opacity: .55; }
.ana-dow .top i { opacity: 1; box-shadow: 0 0 14px rgba(0,229,195,.45); }
.ana-dow b { font: 700 10.5px 'Orbitron', sans-serif; }
.ana-dow span { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; }
.ana-insight { margin: 12px 0 0; color: var(--text-2); font-size: 13.5px; }
.ana-insight b { color: var(--text); }

/* 6. Genres */
.ana-hb { display: grid; grid-template-columns: minmax(0, 150px) 1fr 70px; gap: 10px; align-items: center; padding: 6px 0; }
.ana-hb > span { font: 600 13.5px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ana-hb b { font: 700 12.5px 'Orbitron', sans-serif; text-align: right; }
.ana-hb .lb-bar { margin-top: 0; }

/* 7. Ton année / pile de la honte */
.ana-goty { display: flex; gap: 18px; align-items: center; padding: 14px; border-radius: 12px; background: linear-gradient(120deg, rgba(124,92,255,.25), rgba(0,229,195,.10)); border: 1px solid rgba(124,92,255,.45); cursor: pointer; }
.ana-goty img { width: 86px; aspect-ratio: 3/4; object-fit: cover; border-radius: 8px; box-shadow: 0 10px 30px -8px rgba(124,92,255,.8); flex: none; }
.ana-goty-lbl { color: var(--accent-2); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.6px; text-transform: uppercase; }
.ana-goty-nm { font: 800 20px 'Orbitron', sans-serif; margin: 3px 0 6px; }
.ana-goty-facts { color: var(--text-2); font-size: 14px; }
.ana-goty-facts b { font-family: 'Orbitron', sans-serif; color: var(--text); }
.ana-ty-row { display: flex; align-items: center; gap: 12px; padding: 8px 6px; border-radius: 8px; cursor: pointer; }
.ana-ty-row:hover { background: rgba(124, 92, 255, .08); }
.ana-goty:focus-visible, .ana-ty-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.ana-ty-r { font: 800 13px 'Orbitron', sans-serif; color: var(--muted); width: 18px; flex: none; }
.ana-ty-row img { width: 30px; aspect-ratio: 3/4; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); flex: none; }
.ana-ty-n { flex: 1; min-width: 0; }
.ana-ty-n > div:first-child { font: 700 13.5px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ana-ty-n small { color: var(--muted); font-size: 11.5px; }
.ana-ty-h { font: 700 13px 'Orbitron', sans-serif; min-width: 56px; text-align: right; flex: none; }
.ana-pile { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ana-pile > div { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.ana-pile b { display: block; font: 800 20px 'Orbitron', sans-serif; }
.ana-pile span { color: var(--muted); font-size: 12px; }
.ana-pile .hot { border-color: rgba(255,185,56,.45); background: linear-gradient(160deg, rgba(255,185,56,.14), var(--bg-2)); }
.ana-pile .hot b { color: var(--gold); }
.ana-decades { display: flex; gap: 10px; align-items: flex-end; height: 90px; }
.ana-decades > div { flex: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 3px; }
.ana-decades i { width: 100%; border-radius: 4px 4px 0 0; background: linear-gradient(180deg, var(--gold), rgba(255,185,56,.25)); }
.ana-decades b { font: 700 11px 'Orbitron', sans-serif; }
.ana-decades span { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; }

/* 8. Bibliothèque */
.ana-status-bar { display: flex; height: 14px; border-radius: 7px; overflow: hidden; gap: 2px; margin-top: 4px; }
.ana-status-bar i { display: block; }
.ana-status-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; margin-top: 14px; }
.ana-status-legend > div { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.ana-status-legend b { display: block; font: 800 18px 'Orbitron', sans-serif; }
.ana-status-legend span { color: var(--muted); font-size: 12px; }
.ana-status-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }
.ana-vsref { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.ana-vsref-side { flex: 1; text-align: center; }
.ana-vsref-side b { display: block; font: 800 22px 'Orbitron', sans-serif; }
.ana-vsref-side span { color: var(--muted); font-size: 12px; }
.ana-vsref-mid { flex: 2; }

/* 9. Heure / amis */
.ana-clock { display: flex; align-items: flex-end; gap: 3px; height: 130px; margin-top: 8px; }
.ana-hcol { flex: 1; min-width: 0; height: 100%; display: flex; align-items: flex-end; position: relative; border-radius: 4px; }
.ana-hcol.night { background: rgba(124,92,255,.07); }
.ana-hcol i { display: block; width: 100%; border-radius: 3px 3px 0 0; background: linear-gradient(180deg, #00e5c3, #7c5cff); }
.ana-hcol:hover i { box-shadow: 0 0 12px rgba(0,229,195,.55); }
.ana-clock-axis { display: flex; justify-content: space-between; color: var(--muted); font: 600 10.5px 'Rajdhani', sans-serif; margin-top: 5px; }
.ana-dayparts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 14px; }
.ana-dayparts > div { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.ana-dayparts b { display: block; font: 800 17px 'Orbitron', sans-serif; }
.ana-dayparts span { color: var(--muted); font-size: 11.5px; }
.ana-vs { container-type: inline-size; }
.ana-vs-head, .ana-vs-row { display: grid; gap: 10px; align-items: baseline; grid-template-columns: minmax(96px, 1.2fr) repeat(var(--vs-cols), minmax(64px, 1fr)); }
.ana-vs-head span { font: 700 12px 'Orbitron', sans-serif; text-align: right; color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ana-vs-head span.me { color: var(--accent-2); }
.ana-vs-row { padding: 9px 0 7px; border-bottom: 1px solid var(--line); }
.ana-vs-row > span { color: var(--text-2); font-size: 14px; }
.ana-vs-row b { font: 700 15px 'Orbitron', sans-serif; text-align: right; color: var(--text-2); white-space: nowrap; }
.ana-vs-row b.win { color: var(--text); }
/* Bloc étroit (téléphone, ou tiers de largeur) : libellé au-dessus de ses
   valeurs, noms tronqués (nom complet au survol). Une valeur trop large
   déborde vers la gauche, dans l'espace entre colonnes, jamais hors de page. */
@container (max-width: 420px) {
  .ana-vs-head, .ana-vs-row { grid-template-columns: repeat(var(--vs-cols), minmax(0, 1fr)); column-gap: 8px; row-gap: 3px; }
  .ana-vs-head > span:first-child { display: none; }
  .ana-vs-row > span { grid-column: 1 / -1; font-size: 13px; }
  .ana-vs-row b { font-size: 14px; justify-self: end; }
}
@media (max-width: 560px) {
  .ana-pile, .ana-dayparts { grid-template-columns: 1fr 1fr; }
  .ana-hero-total { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  .ana-hero-total > div { font-size: 24px; }
  .ana-tt-big { font-size: 30px; }
}

/* Disposition personnalisable */
.ana-customize-btn { background: var(--panel); border: 1px solid var(--line); color: var(--text); font: 700 13px 'Rajdhani', sans-serif; padding: 8px 14px; border-radius: 10px; cursor: pointer; }
.ana-customize-btn:hover { border-color: var(--accent-2); }
#view-analyses.ana-editing .ana-customize-btn { display: none; }
.ana-edit-bar { position: sticky; top: 10px; z-index: 950; display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; padding: 10px 14px; border-radius: 12px; background: linear-gradient(90deg, rgba(124,92,255,.28), rgba(0,229,195,.14)), var(--panel); border: 1px solid rgba(0,229,195,.45); box-shadow: 0 10px 30px -12px rgba(0,0,0,.8); }
.ana-edit-bar-txt { color: var(--text-2); font-size: 13.5px; }
.ana-edit-bar-txt b { color: var(--text); }
.ana-edit-bar-actions { display: flex; gap: 8px; }
.ana-done-btn { background: var(--accent-2); color: #0b0d16; border: none; font: 800 12.5px 'Rajdhani', sans-serif; padding: 6px 14px; border-radius: 999px; cursor: pointer; }
.ana-blk-tools { display: none; position: absolute; top: -14px; right: 12px; z-index: 5; align-items: center; gap: 2px; padding: 3px; border-radius: 10px; background: var(--panel-2); border: 1px solid rgba(0,229,195,.5); box-shadow: 0 6px 18px rgba(0,0,0,.5); }
#view-analyses.ana-editing .ana-blk-tools, #view-admin.ana-editing .ana-blk-tools { display: flex; }
.blk-full-only { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .3px; padding: 0 6px; white-space: nowrap; }
@media (max-width: 1000px) { .blk-full-only { display: none; } }
.ana-blk-tools button { background: none; border: none; color: var(--text-2); font: 700 12px 'Rajdhani', sans-serif; min-width: 26px; height: 24px; border-radius: 7px; cursor: pointer; padding: 0 6px; }
.ana-blk-tools button:hover:not(:disabled) { background: var(--bg-2); color: var(--text); }
.ana-blk-tools button:disabled { opacity: .25; cursor: default; }
.ana-blk-tools .grip { cursor: grab; color: var(--accent-2); font-size: 14px; letter-spacing: -1px; }
.ana-blk-tools .sz { border: 1px solid transparent; }
.ana-blk-tools .sz.on { border-color: var(--accent-2); color: var(--accent-2); background: rgba(0,229,195,.1); }
.ana-blk-tools .sep { width: 1px; height: 16px; background: var(--line); margin: 0 3px; }
#view-analyses.ana-editing .ana-blocks > .ana-card { outline: 1px dashed rgba(0,229,195,.4); outline-offset: 3px; cursor: grab; }
#view-analyses.ana-editing .ana-blocks > .ana-card > :not(.ana-blk-tools) { pointer-events: none; user-select: none; }
#view-analyses.ana-editing .ana-blocks > .ana-card:hover { outline-color: var(--accent-2); }
.ana-blocks > .ana-card.dragging { opacity: .35; outline: 2px dashed var(--accent-2) !important; }
.ana-blocks > .ana-card.moved { animation: ana-blk-moved .5s ease; }
@keyframes ana-blk-moved { from { box-shadow: 0 0 0 2px var(--accent-2), 0 0 30px rgba(0,229,195,.45); } to { box-shadow: none; } }
@media (prefers-reduced-motion: reduce) { .ana-blocks > .ana-card.moved { animation: none; } }
@media (max-width: 1000px) { .ana-blk-tools .sz, .ana-blk-tools .sep.s, .ana-blk-tools .grip { display: none; } }
.ana-tray { margin-top: 18px; padding: 14px 16px; border-radius: 12px; border: 1px dashed rgba(139,147,184,.35); background: rgba(21,26,44,.6); }
.ana-tray-title { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; margin-bottom: 8px; }
.ana-tray-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ana-tray-chip { background: var(--panel-2); border: 1px solid var(--line); color: var(--text); font: 700 13px 'Rajdhani', sans-serif; padding: 6px 12px; border-radius: 999px; cursor: pointer; }
.ana-tray-chip:hover { border-color: var(--accent-2); color: var(--accent-2); }
.ana-tray.quiet { border-style: solid; background: none; padding: 10px 14px; color: var(--muted); font-size: 13px; }
.ana-tray.quiet button { background: none; border: none; color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; cursor: pointer; padding: 0; }

/* « Ton resume » : bloc d'Analyses (mockup-objectif-du-mois.html, etat 5) et
   ligne d'acces sous les KPIs (mockup-vue-ensemble-resume-objectif.html). */
.resume-total { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.resume-total b { font: 800 34px 'Orbitron', sans-serif; color: var(--text); }
.resume-total span { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; }
.resume-delta { color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; }
.resume-delta.down { color: var(--text-2); }
/* Une grille : la colonne du nom prend la largeur du nom le plus LONG de la
   liste (260 px au plus), la barre tout le reste (retour de Tim, 2026-10-05).
   En tiers/deux tiers, un bloc en pleine largeur donnait au nom ~500 px et un
   grand vide précédait la barre ; une colonne fixe de 260 px en laissait encore
   derrière les noms courts. Les barres démarrent toutes au même endroit ; dans
   un bloc étroit, la barre garde 35 % de la ligne et c'est le nom qui rétrécit. */
.resume-rows { display: grid; grid-template-columns: 38px minmax(0, max-content) minmax(35%, 1fr) auto; align-items: center; gap: 10px 12px; }
.resume-row { display: contents; }
.resume-row img, .resume-row .ana-nocover { width: 38px; aspect-ratio: 3/4; object-fit: cover; border-radius: 5px; flex: none; }
.resume-row .nom { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); max-width: 260px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.resume-row .bar { height: 6px; border-radius: 3px; background: var(--bg-2); overflow: hidden; }
.resume-row .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.resume-row .h { font: 800 14px 'Orbitron', sans-serif; color: var(--text); min-width: 60px; text-align: right; }
.resume-unlocks { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.resume-unlock { display: flex; align-items: center; gap: 8px; background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 7px 11px; }
.resume-unlock img { width: 26px; height: 26px; border-radius: 5px; flex: none; }
.resume-unlock .n { font: 700 12.5px 'Rajdhani', sans-serif; color: var(--text); }
.resume-unlock .s { font: 600 11.5px 'Rajdhani', sans-serif; color: var(--muted); }
.resume-unlock .tr-icon-fallback { width: 26px; height: 26px; font-size: 13px; }
.resume-teaser { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; width: 100%; text-align: left;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; margin: 16px 0 0;
  color: var(--text-2); font: 600 13.5px 'Rajdhani', sans-serif; cursor: pointer; }
.resume-teaser:hover { border-color: rgba(124,92,255,.5); }
.resume-teaser:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.resume-teaser b { color: var(--text); }
.resume-teaser .go { margin-left: auto; color: var(--accent-2); font-weight: 700; }
/* Sous 560px, la barre passe sous le nom : a plein format elle prend le
   double du nom (flex 2 contre 1), ce qui reduisait le titre a ~56px et donc
   a une ellipse des le deuxieme jeu. */
@media (max-width: 560px) {
  .resume-teaser .go { margin-left: 0; }
  .resume-rows { display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
  .resume-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; row-gap: 7px; }
  .resume-row .nom { max-width: none; }
  .resume-row img, .resume-row .ana-nocover { order: 1; }
  .resume-row .nom { order: 2; white-space: normal; flex: 1 1 0; }
  .resume-row .h { order: 3; width: auto; }
  .resume-row .bar { order: 4; flex: 1 1 100%; min-width: 0; margin-left: 50px; }
}

/* Objectif du mois : carte de la vue d'ensemble, pastille de la barre du haut
   et fenetre de choix (mockups mockup-objectif-du-mois.html et
   mockup-vue-ensemble-resume-objectif.html, valides le 2026-09-20). */
.goal-card { display: flex; gap: 16px; align-items: stretch; background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid rgba(124,92,255,.45); border-radius: var(--radius); padding: 14px; margin: 22px 32px 0; }
.goal-card.done { border-color: rgba(0,229,195,.55); }
.goal-cover { width: 92px; aspect-ratio: 3/4; border-radius: 10px; object-fit: cover; flex: none; cursor: pointer; }
.goal-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.goal-label { font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: var(--accent-2); }
.goal-name { font: 700 19px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.15; }
.goal-done-badge { display: inline-flex; align-items: center; gap: 6px; background: rgba(0,229,195,.12); border: 1px solid rgba(0,229,195,.45);
  border-radius: 999px; padding: 3px 10px; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; vertical-align: 2px; }
.goal-why { color: var(--text-2); font: 600 13.5px 'Rajdhani', sans-serif; }
.goal-why b { color: var(--text); }
.goal-bar { height: 8px; border-radius: 4px; background: var(--bg-2); overflow: hidden; margin-top: 2px; }
.goal-bar i { display: block; height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.goal-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-top: auto; }
.goal-stat { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }
.goal-stat b { color: var(--text); }
.goal-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.goal-link { background: none; border: 0; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; padding: 2px; }
.goal-link:hover { color: var(--text); }
.goal-link:focus-visible, .goal-pill:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

.goal-pill { display: inline-flex; align-items: center; gap: 7px; background: rgba(124,92,255,.12);
  border: 1px solid rgba(124,92,255,.45); border-radius: 999px; padding: 6px 13px; cursor: pointer;
  color: var(--text); font: 700 12.5px 'Rajdhani', sans-serif; flex-shrink: 0; }
.goal-pill:hover { border-color: var(--accent-2); }
.goal-pill .nom { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.goal-pill .pct { color: var(--accent-2); }
.goal-pill.done { background: rgba(0,229,195,.12); border-color: rgba(0,229,195,.5); }

/* Fenetre de choix : tete d'affiche puis alternatives. */
.goal-box { max-width: 620px; }
/* Objectif suivant (mockup mockup-objectif-suivant.html, 2026-10-03). */
.goal-next-btn { font-weight: 700; border-color: rgba(0, 229, 195, .55); }
.goal-prev { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin: -2px 0 4px; }
.goal-prev b { color: var(--accent-2); font-weight: 700; }
.goal-pick.goal-same { border-color: rgba(0, 229, 195, .45); }
.goal-same .goal-pick-why b { color: var(--gold); }
.goal-same-target { color: var(--accent-2); }
.goal-same-target.plat { color: var(--gold); }
.goal-pick { display: flex; gap: 14px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 14px; }
.goal-pick.head { border-color: rgba(124,92,255,.45); }
.goal-pick img { width: 84px; aspect-ratio: 3/4; object-fit: cover; border-radius: 8px; flex: none; }
.goal-pick-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.goal-pick-name { font: 700 17px 'Rajdhani', sans-serif; color: var(--text); line-height: 1.15; }
.goal-pick-why { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.goal-pick-why b { color: var(--text); }
.goal-alt { display: flex; align-items: center; gap: 12px; padding: 8px 0; }
.goal-alt img { width: 34px; aspect-ratio: 3/4; object-fit: cover; border-radius: 5px; flex: none; }
.goal-alt-main { flex: 1; min-width: 0; }
.goal-alt-name { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.goal-alt-why { font: 600 12px 'Rajdhani', sans-serif; color: var(--muted); }
.goal-take { background: none; border: 0; color: var(--accent); font: 700 12.5px 'Rajdhani', sans-serif; cursor: pointer; flex: none; }
.goal-take:hover { color: var(--accent-2); }

/* « Choisir un autre jeu de ma bibliothèque » — mockup
   mockup-objectif-choisir-autre.html, sous les suggestions et replié. */
.goal-other { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.goal-other-btn {
  display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: 0;
  color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; cursor: pointer; padding: 4px 0; text-align: left;
}
.goal-other-btn:hover { color: var(--text); }
.goal-other-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.goal-other-btn .chev { margin-left: auto; color: var(--muted); }
.goal-search-row { display: flex; gap: 8px; margin-top: 10px; }
.goal-search-row input {
  flex: 1; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 12px; color: var(--text); font: 600 13px 'Rajdhani', sans-serif;
}
.goal-search-row input::placeholder { color: var(--muted); }
.goal-results { margin-top: 10px; max-height: 260px; overflow-y: auto; }
.goal-res { display: flex; gap: 11px; align-items: center; padding: 8px 4px; border-bottom: 1px solid var(--line); }
.goal-res:last-child { border-bottom: 0; }
.goal-res:hover { background: rgba(124, 92, 255, .07); }
.goal-res img { width: 32px; aspect-ratio: 3/4; object-fit: cover; border-radius: 4px; flex: none; }
.goal-res-main { flex: 1; min-width: 0; }
.goal-res-name { font: 700 13px 'Rajdhani', sans-serif; color: var(--text); }
.goal-res-meta { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.goal-res-meta .over { color: var(--gold); }
.goal-hint { color: var(--muted); font-size: 11.5px; margin: 8px 0 0; line-height: 1.45; }
.resume-goal-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--line); color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }

@media (max-width: 700px) {
  .goal-card { margin: 18px 16px 0; padding: 12px; gap: 12px; }
  .goal-cover { width: 68px; }
  .goal-pill .nom { display: none; }
}

/* Carte à anneau (mockup mockup-carte-objectif-allegee.html, variante C ; C2
   sous 700 px — retour de Tim le 2026-10-04 : « trop chargée »). Le chiffre
   dans l'anneau, une phrase, un bouton, le reste dans le menu ···. */
.goal-card.goal-v2 { position: relative; align-items: center; gap: 18px; }
.goal-v2 .goal-cover { width: 70px; }
.goal-ring { width: 80px; height: 80px; border-radius: 50%; flex: none; display: grid; place-items: center; position: relative;
  background: conic-gradient(var(--accent-2) 0 var(--p), var(--bg-2) var(--p) 100%); }
.goal-ring::before { content: ''; position: absolute; inset: 7px; border-radius: 50%; background: var(--panel); }
.goal-ring > span { position: relative; text-align: center; font: 800 15px 'Orbitron', sans-serif; color: var(--text); line-height: 1.05; }
.goal-ring small { display: block; font: 600 10.5px 'Rajdhani', sans-serif; color: var(--muted); letter-spacing: .4px; margin-top: 2px; }
.goal-v2 .goal-main { gap: 5px; }
.goal-kicker { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--accent-2); }
.goal-kicker .goal-target { margin-left: 0; font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: none; color: var(--text);
  background: rgba(124, 92, 255, .16); border: 1px solid rgba(124, 92, 255, .45); border-radius: 999px; padding: 1px 9px; }
.goal-kicker .goal-target.plat { color: var(--gold); border-color: rgba(255, 185, 56, .5); background: rgba(255, 185, 56, .1); }
.goal-kicker .goal-target .ico { width: 1em; height: 1em; vertical-align: -2px; }
.goal-days { color: var(--muted); letter-spacing: .4px; text-transform: none; font-weight: 600; }
.goal-days::before { content: '· '; }
.goal-month-short, .goal-deja-m, .goal-note-m { display: none; }
.goal-note-m { color: var(--text-2); font-weight: 600; letter-spacing: .3px; text-transform: none; }
.goal-card.done .goal-note-m { color: var(--accent-2); font-weight: 700; }
.goal-deja { color: var(--accent-2); font-weight: 700; letter-spacing: .4px; text-transform: none; white-space: nowrap; }
.goal-v2 .goal-name { cursor: pointer; }
.goal-v2 .goal-why { font: 600 14px 'Rajdhani', sans-serif; }
.goal-v2 .goal-why .goal-deja { font-size: 13px; margin-left: 4px; }
.goal-v2 .goal-actions { position: relative; flex: none; display: flex; align-items: center; gap: 8px; }
.goal-cta { background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border: 0; border-radius: 999px;
  font: 800 13.5px 'Rajdhani', sans-serif; padding: 8px 16px; cursor: pointer; white-space: nowrap; }
.goal-more { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); background: var(--bg-2); color: var(--text-2);
  display: grid; place-items: center; cursor: pointer; flex: none; font: 800 16px 'Rajdhani', sans-serif; line-height: 1; padding: 0; }
.goal-more:hover, .goal-more[aria-expanded="true"] { border-color: var(--accent); color: var(--text); }
.goal-cta:focus-visible, .goal-more:focus-visible, .goal-menu button:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.goal-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 30; background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 16px 40px rgba(0, 0, 0, .45); padding: 6px; min-width: 210px; }
.goal-menu.hidden { display: none; }
.goal-menu button { display: flex; width: 100%; gap: 9px; align-items: center; background: none; border: 0; color: var(--text-2); text-align: left;
  font: 600 14px 'Rajdhani', sans-serif; padding: 8px 10px; border-radius: 8px; cursor: pointer; }
.goal-menu button:hover { background: rgba(124, 92, 255, .1); color: var(--text); }
.goal-menu .ico { width: 15px; height: 15px; }
.goal-menu-sep { height: 1px; background: var(--line); margin: 4px 6px; }
.goal-menu .danger { color: #ff8a9c; }
@media (max-width: 700px) {
  /* C2 : jaquette à gauche, anneau à droite, la cible et les jours entre les deux ;
     le titre s'efface (la jaquette le porte en texte alternatif), le bouton dessous. */
  .goal-card.goal-v2 { display: grid; grid-template-columns: 64px 1fr 72px; gap: 10px 12px; align-items: center; }
  .goal-v2 .goal-cover { width: 64px; grid-column: 1; grid-row: 1; }
  .goal-v2 .goal-main { grid-column: 2; grid-row: 1; }
  .goal-v2 .goal-ring { grid-column: 3; grid-row: 1; width: 72px; height: 72px; justify-self: end; }
  .goal-v2 .goal-name, .goal-v2 .goal-why { display: none; }
  .goal-v2 .goal-kicker { flex-direction: column; align-items: flex-start; gap: 5px; font-size: 11px; }
  .goal-v2 .goal-month-long { display: none; }
  .goal-v2 .goal-month-short { display: inline; }
  .goal-v2 .goal-deja-m, .goal-v2 .goal-note-m { display: inline; }
  .goal-v2 .goal-days::before { content: none; }
  .goal-v2 .goal-actions { grid-column: 1 / -1; grid-row: 2; }
  .goal-v2 .goal-actions .goal-cta, .goal-v2 .goal-actions .goal-next-btn { flex: 1; }
}

/* Vue par defaut (mockup mockup-vue-par-defaut.html, valide le 2026-09-21) :
   bloc du panneau « Configurer la vue » + bandeau de la vue d'ensemble. */
.cvp-sep { height: 1px; background: var(--line); margin: 16px 0 14px; }
.dv-now { background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.dv-now .k { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; }
.dv-pills { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 7px; }
.dv-pill { background: rgba(124,92,255,.12); border: 1px solid rgba(124,92,255,.4); border-radius: 999px;
  padding: 3px 10px; color: var(--text); font: 700 12px 'Rajdhani', sans-serif; }
.dv-saved { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: rgba(0,229,195,.07);
  border: 1px solid rgba(0,229,195,.4); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px;
  color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.dv-saved .ok { color: var(--accent-2); font-weight: 800; white-space: nowrap; }
.dv-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dv-banner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: var(--bg-2);
  border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 12px;
  padding: 9px 14px; margin-bottom: 14px; color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.dv-banner b { color: var(--text); }
.dv-banner .go { margin-left: auto; }
.link-btn { background: none; border: 0; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; padding: 2px; }
.link-btn:hover { color: var(--text); }
.link-btn:focus-visible, .dv-banner .go:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
@media (max-width: 560px) { .dv-banner .go { margin-left: 0; } }

/* Pastille du logo (mockup-logo-sablier.html, forme « pastille + TYG »,
   validée le 2026-09-21) — la même icône que sur l'écran d'accueil, pour
   retrouver le même objet partout. Dimensionnée en `em` : elle suit la taille
   de police de son logo (22px topbar/connexion/chargement/bienvenue, 18px
   tiroir, 19px pied de page) sans une règle par endroit.
   Le mot reste dans UN SEUL enfant flex, sinon le `gap` prévu pour écarter la
   pastille s'insère aussi entre le « TY » et le « G » — vu en mockup. */
.logo, .loading-logo, .site-footer-brand { display: inline-flex; align-items: center; gap: .4em; }
.brand-mark { width: 1.15em; height: 1.15em; border-radius: 26%; flex: none; display: block; }
.brand-word { white-space: nowrap; }
/* Badge « Beta » (2026-09-30, mockup mockup-logo-beta.html, variante C) —
   sur le logo de la barre du haut et, depuis le 2026-10-03, celui de la
   landing (décisions de Tim). En Rajdhani et
   non en Orbitron : une étiquette, pas un second mot-marque (règle d'identité
   « un symbole et un mot-marque, jamais deux »). Hors de `.brand-word`, sinon
   il en hériterait. */
.beta-badge {
  flex: none; align-self: center; line-height: 1;
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1.6px; text-transform: uppercase;
  padding: 3px 7px 2px; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2)); color: #0b0d16; text-shadow: none;
}

/* L'icône en grand : écran de chargement et haut de la landing (retour de
   Tim, 2026-09-21). Le halo reprend celui que portait le mot-marque, pour
   que l'icône s'inscrive dans la même lumière violette que le reste. */
.loading-icon { width: 104px; height: 104px; border-radius: 26%; display: block;
  box-shadow: 0 0 60px rgba(124, 92, 255, .45); }
.hero-logo { width: 92px; height: 92px; border-radius: 26%; display: block; margin: 0 auto 22px;
  box-shadow: 0 0 60px rgba(124, 92, 255, .4); }
@media (max-width: 700px) {
  .loading-icon { width: 84px; height: 84px; }
  .hero-logo { width: 72px; height: 72px; margin-bottom: 18px; }
}

/* Le sable monte et descend pendant le chargement (idée de Tim, 2026-09-21).
   On anime le bord haut du rectangle de masquage : `y` est une propriété
   géométrique SVG animable en CSS, donc pas une ligne de JavaScript.
   264 = chambre pleine, 366 = vide ; on reste entre les deux pour que le
   mouvement se lise sans jamais vider ni noyer le sablier. */
/* Le sable tombe du haut vers le bas (idée de Tim), puis le verre bascule de
   180° — et comme la forme est symétrique, l'état d'arrivée (vide en haut,
   plein en bas, retourné) est EXACTEMENT l'état de départ. La boucle se
   referme donc sans le moindre saut, sans avoir à remettre quoi que ce soit
   en place. 78 % du temps pour la chute, le reste pour le retournement. */
@keyframes tyg-verre {
  0%, 78% { transform: rotate(0deg); }
  100%    { transform: rotate(180deg); }
}
@keyframes tyg-sable-haut {      /* la chambre du haut se vide */
  0%        { transform: translateY(0); }
  78%, 100% { transform: translateY(98px); }
}
@keyframes tyg-sable-bas {       /* celle du bas se remplit */
  0%        { transform: translateY(98px); }
  78%, 100% { transform: translateY(0); }
}
.loading-icon .verre { transform-box: view-box; transform-origin: 256px 256px;
  animation: tyg-verre 3.4s cubic-bezier(.6, 0, .35, 1) infinite; }
.loading-icon .sable-haut { animation: tyg-sable-haut 3.4s ease-in-out infinite; }
.loading-icon .sable-bas  { animation: tyg-sable-bas  3.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .loading-icon .verre, .loading-icon .sable-haut, .loading-icon .sable-bas { animation: none; }
  .loading-icon .sable-bas { transform: translateY(40px); }
}

/* Note « inscriptions sur invitation » : remplace la bascule « Créer un
   compte » sur l'écran de connexion, les inscriptions publiques étant
   fermées. --text-2 et non --muted : c'est une phrase qu'on demande de lire. */
.login-note {
  margin: 10px 0 0; color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif;
  line-height: 1.5; text-align: center;
}
.login-note strong { color: var(--text); }

/* ─── Profondeur d'historique (mockup mockup-analyses-completude.html, et la
   marche à suivre dans le Guide, mockup mockup-guide-export-sony.html) ──── */
.ana-head-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ana-head-btn {
  background: none; border: 1px solid var(--line); border-radius: 999px; color: var(--muted);
  font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .4px; padding: 5px 12px; cursor: pointer;
  white-space: nowrap; transition: all .15s;
}
.ana-head-btn:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.ana-head-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* Le bandeau reprend .guide-note : même registre que le Guide — une porte de
   sortie, pas une limite de plus. */
.ana-depth-note { margin: 0 0 18px; }
.ana-depth-note .note-actions { display: flex; justify-content: flex-end; margin-top: 10px; }
.guide-note-desc a { color: var(--accent-2); font-weight: 700; text-decoration: none; }
.guide-note-desc a:hover { text-decoration: underline; }

/* Marche à suivre pour la demande RGPD, dans le Guide. */
.guide-steps { counter-reset: e; list-style: none; margin: 12px 0 0; padding: 0; }
.guide-steps li {
  counter-increment: e; position: relative; padding-left: 30px; margin-bottom: 12px;
  font: 600 13.5px 'Rajdhani', sans-serif; color: var(--text-2); line-height: 1.6;
}
.guide-steps li::before {
  content: counter(e); position: absolute; left: 0; top: 1px;
  width: 20px; height: 20px; border-radius: 50%;
  background: rgba(124, 92, 255, .15); border: 1px solid rgba(124, 92, 255, .5);
  color: var(--accent-2); font: 700 11px 'Orbitron', sans-serif;
  display: flex; align-items: center; justify-content: center;
}
.guide-steps strong { color: var(--text); font-weight: 700; }
/* Les deux surprises du moment — un nom d'onglet coupé, des jours manquants —
   répondues là où elles arrivent, sans alourdir la consigne principale. */
.guide-aside { display: block; margin-top: 6px; color: var(--muted); font-size: 12.5px; }
.guide-note-desc code, .guide-steps code {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 5px; font-size: 12.5px; color: var(--accent-2);
}
.guide-warn {
  border-left: 3px solid rgba(255, 84, 112, .6); background: rgba(255, 84, 112, .07);
  border-radius: 0 8px 8px 0; padding: 9px 13px; margin: 14px 0;
  font: 600 13px 'Rajdhani', sans-serif; color: var(--text-2); line-height: 1.55;
}
.guide-warn strong { color: #ff8fa3; }
.letter-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.letter-toggle {
  background: none; border: 1px solid var(--line); border-radius: 8px; color: var(--text-2);
  font: 700 12px 'Rajdhani', sans-serif; padding: 6px 12px; cursor: pointer;
}
.letter-toggle:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.letter-toggle:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.letter {
  margin-top: 10px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 16px; font: 500 12px/1.6 ui-monospace, Consolas, monospace;
  color: var(--text-2); max-height: 240px; overflow-y: auto; white-space: pre-wrap;
}

/* ─── Navigation dans l'historique du résumé (mockup
   docs/mockups/mockup-resume-historique.html, validé le 2026-09-21) ─────── */
.resume-nav {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 6px 8px;
}
.resume-nav-btn {
  background: none; border: 1px solid var(--line); border-radius: 8px; color: var(--text-2);
  font: 700 14px 'Rajdhani', sans-serif; line-height: 1; padding: 6px 11px; cursor: pointer; flex: none;
  transition: border-color .15s, color .15s;
}
.resume-nav-btn:hover:not(:disabled) { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.resume-nav-btn:disabled { opacity: .35; cursor: not-allowed; }
.resume-nav-btn:focus-visible, .resume-back:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.resume-period { flex: 1; text-align: center; font: 700 13.5px 'Rajdhani', sans-serif; color: var(--text); letter-spacing: .3px; }
.resume-period small { display: block; font: 600 11.5px 'Rajdhani', sans-serif; color: var(--muted); letter-spacing: 0; }
.resume-back {
  background: none; border: 0; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif;
  cursor: pointer; flex: none; padding: 4px 8px; white-space: nowrap; border-radius: 6px;
}
.resume-nav-note { color: var(--muted); font-size: 12px; margin: -6px 0 12px; text-align: center; }
/* Sous 560px, le retour passe sous les flèches plutôt que de comprimer le
   libellé de période, qui porte la date. */
@media (max-width: 560px) {
  .resume-nav { flex-wrap: wrap; }
  .resume-back { width: 100%; text-align: center; order: 3; }
}

/* ─── Runs (mockup docs/mockups/mockup-runs.html, validé le 2026-09-21) ───
   Rejouer un jeu terminé : le run en cours en avant, les runs passés en
   dessous, le total en pied — rien n'est retiré, le total ne bouge pas. */
/* Le run en cours est une vraie tuile, pas une ligne de texte : c'est
   l'information que la section existe pour porter (retour de Tim, le rendu
   repris du mockup était « un peu effacé »). */
.run-current {
  background: linear-gradient(150deg, rgba(0, 229, 195, .07), rgba(124, 92, 255, .05));
  border: 1px solid rgba(0, 229, 195, .28); border-radius: 12px;
  padding: 12px 14px 13px; margin-bottom: 12px;
}
.run-title { font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .6px; color: var(--text); }
.run-live {
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--accent-2); border: 1px solid rgba(0, 229, 195, .4); background: rgba(0, 229, 195, .08);
  border-radius: 999px; padding: 2px 8px; margin-left: 8px; vertical-align: 2px;
}
.run-hours {
  font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 30px; letter-spacing: .5px;
  margin-top: 6px; background: linear-gradient(90deg, var(--text), var(--accent-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* --text-2 et non --muted : c'est une phrase qu'on demande de lire, pas une
   métadonnée (voir la règle des deux couleurs dans CLAUDE.md). */
.run-since { color: var(--text-2); font-size: 12.5px; margin-top: 3px; }
.run-past-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 8px 0; border-top: 1px solid var(--line); font-size: 13.5px; color: var(--text);
}
.run-past-row .rp-h { font-family: 'Orbitron', sans-serif; font-size: 13px; color: var(--text); }
.run-past-row .rp-dates { color: var(--muted); font-size: 12px; font-weight: 500; }
/* Un platine décroché pendant un run se rattache à ce run-là : il a une date,
   et cette date tombe dans une fenêtre. Purement informatif — platiner ne
   clôt rien, « platiné ne veut pas forcément dire terminé selon les jeux »
   (Tim, 2026-09-21). */
.run-plat { color: var(--gold); font-size: 12px; font-weight: 600; margin-left: 6px; white-space: nowrap; }
.run-total {
  display: flex; justify-content: space-between; align-items: baseline;
  border-top: 1px solid var(--line); margin-top: 2px; padding-top: 10px;
  font: 600 13.5px 'Rajdhani', sans-serif; color: var(--text-2);
}
.run-total .rt-h { font-family: 'Orbitron', sans-serif; font-size: 15px; color: var(--text); }

/* Badge de carte : prend la place de .badge-live (même coin, et les deux
   signalent la même chose) — masqué en mode sélection comme ses voisins,
   la case à cocher occupe ce coin-là. */
.badge-run {
  position: absolute; top: 8px; left: 8px;
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase;
  color: #0b0d16; background: linear-gradient(120deg, var(--accent), var(--accent-2));
  border-radius: 999px; padding: 3px 9px;
}
.grid.selecting .badge-run { display: none; }

/* ── Fenêtre « Terminer » : qu'as-tu terminé ? (2026-09-30, mockup
   mockup-jalons-final.html) ── */
.ms-choices { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.ms-choice { display: flex; align-items: flex-start; gap: 10px; text-align: left; cursor: pointer; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text); font-family: 'Rajdhani', sans-serif; }
.ms-choice .dot { flex: none; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--muted); margin-top: 2px; box-sizing: border-box; }
.ms-choice b { display: block; font-size: 14.5px; }
.ms-choice .d { display: block; color: var(--text-2); font-size: 12.5px; font-weight: 500; margin-top: 1px; }
.ms-choice:hover:not(.done) { border-color: rgba(124, 92, 255, .5); }
.ms-choice.on { border-color: rgba(124, 92, 255, .8); background: linear-gradient(135deg, rgba(124, 92, 255, .22), rgba(0, 229, 195, .1)); }
.ms-choice.on .dot { border-color: var(--accent-2); background: radial-gradient(circle, var(--accent-2) 45%, transparent 50%); }
.ms-choice:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.ms-choice.done { opacity: .55; cursor: default; }
.ms-choice.done .dot { border-color: var(--accent-2); background: var(--accent-2); }
.ms-choice .when { margin-left: auto; color: var(--accent-2); font: 700 12px 'Rajdhani', sans-serif; white-space: nowrap; }
.ms-foot { margin: 12px 0 0; color: var(--text-2); font-size: 13px; }
.ms-foot b { color: var(--text); }

/* ── Difficulté jouée (2026-10-09, mockup mockup-difficulte-terminer.html) :
   curseur à quatre crans, facultatif — pas de poignée tant qu'on n'a rien
   touché. Couleurs : turquoise, violet, or, rouge ; « Ça a varié » en gris. ── */
.ms-choice .runtag { margin-left: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase; color: var(--muted); }
.diff { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); font-family: 'Rajdhani', sans-serif; }
.diff-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.diff-head .t { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.diff-head .opt { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; }
.diff-head .val { margin-left: auto; font: 700 12px 'Orbitron', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); transition: color .15s; }
.diff-track-wrap { position: relative; height: 34px; margin: 10px 9px 0; cursor: pointer; touch-action: none; }
.diff-track { position: absolute; left: 0; right: 0; top: 15px; height: 4px; border-radius: 2px; background: var(--line); }
.diff-fill { position: absolute; left: 0; top: 15px; height: 4px; border-radius: 2px; width: 0;
  background: linear-gradient(90deg, var(--accent-2), var(--accent), var(--gold), var(--danger)); background-size: var(--full, 100%) 100%; transition: width .15s; }
.diff-stop { position: absolute; top: 11px; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: var(--panel-2); border: 2px solid var(--line); box-sizing: border-box; }
.diff-stop.past { border-color: rgba(232, 236, 255, .35); }
.diff-thumb { position: absolute; top: 6px; width: 22px; height: 22px; margin-left: -11px; border-radius: 50%; background: var(--text);
  border: 3px solid var(--c, var(--accent)); box-sizing: border-box; box-shadow: 0 0 14px var(--c, var(--accent)); transition: left .15s, border-color .15s, box-shadow .15s; }
.diff-thumb.hidden { display: none; }
.diff-track-wrap:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 4px; border-radius: 8px; }
.diff-labels { position: relative; height: 18px; margin: 2px 9px 0; }
.diff-labels button { position: absolute; transform: translateX(-50%); background: none; border: 0; padding: 0 2px; cursor: pointer;
  color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; white-space: nowrap; }
.diff-labels button:first-child { transform: none; left: -9px !important; }
.diff-labels button:last-child { transform: translateX(-100%); left: calc(100% + 9px) !important; }
.diff-labels button.on { color: var(--text); font-weight: 700; }
.diff-foot { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.diff-foot .chip { padding: 4px 11px; font-size: 11.5px; }
.diff-foot .hint { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.diff-reset { margin-left: auto; background: none; border: 0; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; text-decoration: underline; cursor: pointer; }
.diff.varied .diff-track-wrap, .diff.varied .diff-labels { opacity: .3; pointer-events: none; }
.diff.varied .diff-head .val { color: var(--text-2); }
.mt-pop-diff { padding: 0 8px 8px; }
.mt-pop-diff .diff { margin-top: 6px; padding-top: 10px; }
/* Le niveau d'un run ou d'un groupe de jalons, en pastille colorée. */
.lvl { display: inline-flex; align-items: center; gap: 5px; margin-left: 6px; padding: 1px 7px; border-radius: 6px; border: 1px solid var(--c); color: var(--c);
  font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: uppercase; vertical-align: 1px; white-space: nowrap; }
.lvl::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--c); }
.mt-chips > .lvl { margin-left: 0; align-self: center; }
.mt-run { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 0; }
.mt-run:first-of-type { margin-top: 2px; }
.mt-run + .mt-chips { margin-top: 8px; }
.mt-run-h { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; min-width: 44px; }
.mt-run .lvl { margin-left: 0; }
.lvl-pick { background: var(--bg-2); cursor: pointer; padding: 4px 8px; border-radius: 999px; border: 1px solid var(--c); color: var(--c);
  font: 700 11.5px 'Rajdhani', sans-serif; }
.lvl-pick option { color: var(--text); background: var(--panel); }
.lvl-pick:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* Joueurs TYG par difficulté, sous la référence. */
.tyg-levels { margin-top: 12px; }
.tyg-levels-h { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 6px; }
.tyg-level-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 6px; }
.tyg-level-k { font: 700 13px 'Rajdhani', sans-serif; color: var(--text); min-width: 120px; }
.dchip { display: inline-flex; gap: 6px; align-items: baseline; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); font: 600 12px 'Rajdhani', sans-serif; color: var(--text-2); }
.dchip i { font-style: normal; width: 7px; height: 7px; border-radius: 50%; background: var(--c); align-self: center; }
.dchip b { font: 700 11.5px 'Orbitron', sans-serif; color: var(--text); }
.dchip small { color: var(--muted); font-size: 11px; }
.dchip.you { border-color: rgba(255, 185, 56, .55); }
/* New Game+ et difficulté la plus dure, par la rareté du trophée. */
.feat { display: flex; gap: 10px; align-items: center; margin-top: 10px; padding: 10px 12px; border-radius: 10px; background: var(--bg-2); border: 1px dashed rgba(255, 84, 112, .45); }
.feat.ngp { border: 1px solid var(--line); }
.feat .badge { font: 900 10px 'Orbitron', sans-serif; letter-spacing: 1px; color: #0b0d16; background: var(--danger); padding: 3px 7px; border-radius: 6px; flex: none; text-transform: uppercase; }
.feat.ngp .badge { font-size: 11px; background: linear-gradient(120deg, var(--accent), var(--accent-2)); }
.feat p { margin: 0; color: var(--text-2); font: 500 13.5px 'Rajdhani', sans-serif; }
.feat p b { color: var(--text); }
.feat .feat-src { color: var(--muted); }
.feat .ok { color: var(--gold); font-weight: 700; }

/* ── Type de run (2026-09-30, mockup mockup-runs-type.html) : choix à la
   réouverture et dans le ✎, étiquette dans la section Runs, chiffre du run
   sur la carte (option B). ── */
.rk-label { font: 700 12px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-2); margin: 14px 0 8px; }
.rk-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.rk-choice { text-align: left; cursor: pointer; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg-2); color: var(--text); font-family: 'Rajdhani', sans-serif; }
.rk-choice b { display: block; font-size: 14.5px; font-weight: 700; }
.rk-choice span { display: block; color: var(--text-2); font-size: 12.5px; font-weight: 500; margin-top: 2px; line-height: 1.3; }
.rk-choice:hover { border-color: rgba(124, 92, 255, .5); }
.rk-choice.on { border-color: rgba(124, 92, 255, .8); background: linear-gradient(135deg, rgba(124, 92, 255, .22), rgba(0, 229, 195, .1)); box-shadow: 0 0 14px rgba(124, 92, 255, .25); }
.rk-choice:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.rk-note { display: block; margin-top: 12px; font: 700 12px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-2); }
.rk-note small { color: var(--muted); font-weight: 600; letter-spacing: .6px; text-transform: none; margin-left: 6px; font-size: 12px; }
.rk-note input { display: block; width: 100%; margin-top: 6px; box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 8px 10px; font: 600 14px 'Rajdhani', sans-serif; letter-spacing: 0; text-transform: none; }
.rk-note input::placeholder { color: var(--muted); }
@media (max-width: 420px) { .rk-choices { grid-template-columns: 1fr; } }
.run-kind { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 6px; vertical-align: 1px;
  font: 700 10px 'Rajdhani', sans-serif; letter-spacing: .9px; text-transform: uppercase; border: 1px solid var(--line); color: var(--text-2); }
.run-kind.ngp { border-color: rgba(124, 92, 255, .6); color: #c9bcff; background: rgba(124, 92, 255, .12); }
.run-note { color: var(--text-2); font-size: 12.5px; font-weight: 600; margin-left: 6px; }
.run-edit { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 13px; padding: 0 2px; margin-left: 4px; vertical-align: 1px; }
.run-edit:hover { color: var(--accent-2); }
.run-current .run-edit { float: right; }
.run-past-row .rp-h { white-space: nowrap; }
.hr-run { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 11px; letter-spacing: 1px; text-transform: uppercase;
  background: linear-gradient(90deg, var(--accent), var(--accent-2)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hr-total { display: block; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin: -2px 0 6px; }
.list-row-side .hr-total { margin: 0; font-size: 11px; }

/* ─── Barre de navigation mobile (mockup mockup-mobile-barre-nav.html,
   validé le 2026-09-21) ───────────────────────────────────────────────────

   Sous 761px, le hamburger cachait la navigation : changer de page demandait
   deux gestes et on ne voyait jamais les pastilles. La barre du bas rend les
   pages atteignables au pouce, et met le chronomètre au centre — l'action
   principale sur téléphone, seul moyen de compter le temps des plateformes
   sans API. Au-dessus de 760px elle disparaît, la nav de la topbar reprend. */
.mobile-nav { display: none; }

@media (max-width: 760px) {
  .mobile-nav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
    height: calc(74px + env(safe-area-inset-bottom, 0px));
    padding: 9px 4px env(safe-area-inset-bottom, 0px);
    display: flex; align-items: flex-start; justify-content: space-around;
    background: linear-gradient(180deg, rgba(11, 13, 22, .86), var(--bg) 55%);
    backdrop-filter: blur(12px);
    border-top: 1px solid var(--line);
  }
  .mnav-item {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    width: 58px; background: none; border: 0; cursor: pointer; position: relative;
    color: var(--muted); font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: .4px;
  }
  .mnav-item .ic { font-size: 17px; line-height: 1; filter: grayscale(1) opacity(.65); }
  /* Le libellé n'apparaît que sous l'onglet actif : cinq mots alignés sous
     cinq icônes font une barre illisible sur 375px. */
  .mnav-item .lbl { display: none; }
  .mnav-item.active { color: var(--accent-2); }
  .mnav-item.active .ic { filter: none; }
  .mnav-item.active .lbl { display: block; }
  .mnav-item:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; border-radius: 8px; }
  .mnav-badge {
    position: absolute; top: -3px; right: 9px; min-width: 15px; height: 15px; padding: 0 4px;
    border-radius: 999px; background: var(--accent); color: #fff;
    font: 700 9px 'Rajdhani', sans-serif; display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--bg);
  }
  .mnav-chrono {
    width: 58px; height: 58px; border-radius: 50%; border: 0; cursor: pointer; flex: none;
    margin-top: -20px; display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #0b0d16;
    box-shadow: 0 8px 22px rgba(124, 92, 255, .45), 0 0 0 5px var(--bg);
    font: 900 19px 'Orbitron', sans-serif;
  }
  .mnav-chrono:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 4px; }
  /* Session en cours : le bouton DEVIENT le chrono et remplace .timer-widget,
     qui occupait déjà ce coin de l'écran. Un appui rouvre le plein écran — il
     n'arrête pas : terminer se fait depuis le plein écran, qui a son bouton. */
  .mnav-chrono.running {
    background: linear-gradient(135deg, #0b0d16, #14203a);
    border: 2px solid var(--accent-2); color: var(--accent-2);
    box-shadow: 0 8px 22px rgba(0, 229, 195, .3), 0 0 0 5px var(--bg);
    animation: mnav-pulse 2.4s ease-in-out infinite;
  }
  .mnav-chrono .t { font: 800 13px 'Orbitron', sans-serif; letter-spacing: -.3px; }
  .mnav-chrono .l { font: 700 11px 'Rajdhani', sans-serif; line-height: .6; opacity: .75; }
  @keyframes mnav-pulse {
    0%, 100% { box-shadow: 0 8px 22px rgba(0, 229, 195, .3), 0 0 0 5px var(--bg); }
    50% { box-shadow: 0 8px 26px rgba(0, 229, 195, .55), 0 0 0 5px var(--bg); }
  }
  @media (prefers-reduced-motion: reduce) { .mnav-chrono.running { animation: none; } }

  /* Feuille « Plus » — remplace le tiroir hamburger. */
  .mnav-sheet-overlay { position: fixed; inset: 0; z-index: 96; background: rgba(5, 6, 12, .55); backdrop-filter: blur(4px); }
  .mnav-sheet {
    position: absolute; left: 0; right: 0; bottom: calc(74px + env(safe-area-inset-bottom, 0px));
    background: var(--panel-2); border-top: 1px solid var(--line);
    border-radius: 16px 16px 0 0; padding: 14px 14px 10px;
    box-shadow: 0 -18px 40px rgba(0, 0, 0, .5);
    animation: sheet-up .22s cubic-bezier(.2, .8, .3, 1) both;
  }
  @keyframes sheet-up { from { transform: translateY(14px); opacity: 0; } }
  .mnav-sheet-grip { width: 36px; height: 4px; border-radius: 2px; background: var(--line); margin: 0 auto 12px; }
  .mnav-sheet-item {
    display: flex; align-items: center; gap: 11px; width: 100%;
    padding: 12px 6px; background: none; border: 0; border-bottom: 1px solid var(--line);
    color: var(--text); font: 600 13.5px 'Rajdhani', sans-serif; text-align: left; cursor: pointer;
  }
  .mnav-sheet-item:last-child { border-bottom: 0; }
  .mnav-sheet-item .ic { font-size: 16px; width: 22px; text-align: center; }
  .mnav-sheet-item:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }

  /* Le widget de chrono tomberait pile sous la barre — le bouton central le remplace. */
  .timer-widget { display: none !important; }
  /* Deux boutons du haut mènent exactement où la barre du bas mène déjà :
     « ▶ Démarrer une session » au chronomètre, l'avatar au Profil (« ⋯ »).
     Retirés sur téléphone (retour de Tim) — `#start-session-btn` reste dans le
     DOM, le bouton central le clique pour ouvrir le choix du jeu.
     La cloche RESTE : `openReleaseNotifQueue()` n'est appelable que par elle
     et par une bannière qui s'efface après 5 s, c'est le seul accès permanent
     à la file des sorties à J-5 — la pastille Wishlist mène à la page, pas à
     la file. */
  #start-session-btn, #topbar-avatar-btn { display: none !important; }
  /* De quoi ne pas manger le dernier élément de chaque vue. */
  body { padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }

  /* Ni barre ni marge tant qu'on est sur la landing ou l'écran de connexion :
     `:has()` plutôt qu'un drapeau JS à poser aux cinq endroits qui montrent ou
     masquent la landing — une source de moins à tenir synchronisée. */
  body:has(#landing-overlay:not(.hidden)) .mobile-nav,
  body:has(#login-overlay:not(.hidden)) .mobile-nav { display: none; }
  body:has(#landing-overlay:not(.hidden)),
  body:has(#login-overlay:not(.hidden)) { padding-bottom: 0; }
}

/* ── Jalons, seconde étape (2026-09-30, mockup mockup-jalons-final.html,
   panneaux 2, 3, 6, 7, 8) : « Mes temps » en pastilles dans l'Aperçu, menu
   « + poser un jalon », « Mes jalons » dans Ajustements, saisie à la main. ── */
.mt-chips { position: relative; display: flex; flex-wrap: wrap; gap: 6px; }
.mt-chip { display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg-2);
  font: 600 12.5px 'Rajdhani', sans-serif; color: var(--text-2); }
.mt-chip b { color: var(--text); font-weight: 700; }
.mt-chip small { color: var(--muted); font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px; }
.mt-chip.done { border-color: rgba(0, 229, 195, .35); }
.mt-chip.perso { border-style: dashed; }
.mt-chip.add { cursor: pointer; color: var(--accent-2); border-color: rgba(0, 229, 195, .5); background: none; }
.mt-chip.add.open { background: rgba(0, 229, 195, .1); }
.mt-chip.add:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.mt-hint { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin: 8px 0 0; }
.mt-pop { position: absolute; top: calc(100% + 8px); left: 0; z-index: 5; width: min(340px, 100%); box-sizing: border-box; padding: 8px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line); box-shadow: 0 16px 34px rgba(0, 0, 0, .55); }
.mt-pop.hidden { display: none; }
.mt-pop-h { color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.1px; text-transform: uppercase; margin: 6px 6px 4px; }
.mt-pop-row { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 10px; text-align: left; background: none; border: 0; border-radius: 8px;
  padding: 8px; color: var(--text); font-family: 'Rajdhani', sans-serif; cursor: pointer; box-sizing: border-box; }
.mt-pop-row:hover { background: rgba(124, 92, 255, .14); }
.mt-pop-row b { display: block; font-size: 14px; }
.mt-pop-row small { display: block; color: var(--text-2); font-size: 12px; font-weight: 500; }
.mt-pop-row .t { font: 700 13px 'Orbitron', sans-serif; white-space: nowrap; }
.mt-pop-row.confirm { background: rgba(124, 92, 255, .14); cursor: default; }
.mt-pop-row.confirm small { color: var(--accent-2); }
.mt-pop-actions { display: flex; gap: 6px; flex-shrink: 0; }
.mt-pop-actions .chip { padding: 4px 10px; font-size: 11.5px; }
.mt-pop-actions.end { justify-content: flex-end; padding: 0 6px 6px; }
.mt-pop-perso { display: flex; gap: 6px; padding: 2px 6px 6px; }
.mt-pop-perso input { flex: 1; min-width: 0; box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 6px 9px; font: 600 13px 'Rajdhani', sans-serif; }
.mt-pop-perso input::placeholder { color: var(--muted); }
.mt-pop-link { display: block; border-top: 1px solid var(--line); margin-top: 4px; padding: 8px 6px 2px; color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; text-decoration: none; }
.mt-pop-note { padding: 2px 8px 6px; color: var(--text-2); font: 500 12.5px 'Rajdhani', sans-serif; }
.mt-pop-done { padding: 8px 8px 4px; color: var(--accent-2); font: 600 13px 'Rajdhani', sans-serif; }
.mt-pop-done b { color: var(--text); }
.mt-pop-ask { padding: 4px 8px 8px; color: var(--text); font: 600 14px 'Rajdhani', sans-serif; }
.mt-pop-ask .d { display: block; color: var(--text-2); font-size: 12.5px; font-weight: 500; margin-top: 2px; }
/* Ajustements — « Mes jalons » */
.mt-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; align-items: center; padding: 10px 0; border-top: 1px solid var(--line); }
#mt-ajust > h3 + .mt-row { border-top: none; }
.mt-name { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.mt-val { font: 700 12px 'Orbitron', sans-serif; color: var(--text-2); text-align: right; white-space: nowrap; }
.mt-meta { grid-column: 1 / -1; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.mt-tag { display: inline-block; padding: 0 6px; border-radius: 5px; border: 1px solid var(--line); color: var(--muted); font: 700 9.5px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; margin-left: 6px; vertical-align: 1px; }
.mt-tag.ref { border-color: rgba(0, 229, 195, .45); color: var(--accent-2); }
.mt-actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.mt-actions .chip { padding: 5px 10px; font-size: 11.5px; }
.mt-sub { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; margin: 16px 0 0; padding-bottom: 2px; }
.mt-perso-add { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.mt-perso-add input { flex: 1; min-width: 160px; box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 10px; font: 600 13.5px 'Rajdhani', sans-serif; }
.mt-perso-add input::placeholder { color: var(--muted); }
/* Saisie à la main */
.hm { display: flex; align-items: center; gap: 6px; margin-top: 10px; }
.hm input { width: 70px; box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 10px; font: 700 15px 'Orbitron', sans-serif; }
.hm span { color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; }
.hm-date { display: block; margin-top: 12px; font: 700 12px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-2); }
.hm-date small { color: var(--muted); text-transform: none; letter-spacing: .6px; margin-left: 6px; font-size: 12px; }
.hm-date input { display: block; margin-top: 6px; box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 10px; font: 600 14px 'Rajdhani', sans-serif; letter-spacing: 0; text-transform: none; }
.hm-date input[type="text"] { width: 100%; }
.hm-note { margin: 12px 0 0; padding: 8px 10px; border-radius: 8px; border: 1px dashed var(--line); color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; }

/* ── Référence des joueurs TYG (2026-09-30, mockup
   mockup-reference-tyg-variantes.html, variante A) : un trait turquoise sur la
   barre IGDB, le chiffre au survol, au focus ou au toucher (.show-tip). ── */
.ref-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tyg-leg { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; }
.tyg-leg i { width: 3px; height: 11px; border-radius: 2px; background: var(--accent-2); box-shadow: 0 0 6px rgba(0, 229, 195, .7); }
.ttb-row-bar.has-tyg { overflow: visible; }
/* Une barre de 6 px est une cible trop fine pour la souris et le doigt. */
.ttb-row-bar.has-tyg::before { content: ''; position: absolute; inset: -7px 0; }
.ttb-row-bar.has-tyg:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }
.tyg-tick { position: absolute; top: -4px; width: 3px; height: 12px; margin-left: -1px; border-radius: 2px; background: var(--accent-2); box-shadow: 0 0 8px rgba(0, 229, 195, .7); }
.tyg-tip { display: none; position: absolute; bottom: 14px; transform: translateX(-50%); white-space: nowrap; padding: 3px 8px; border-radius: 7px; background: var(--panel-2);
  border: 1px solid rgba(0, 229, 195, .45); color: var(--text); font: 700 11.5px 'Rajdhani', sans-serif; box-shadow: 0 8px 18px rgba(0, 0, 0, .5); z-index: 2; pointer-events: none; }
.tyg-tip small { color: var(--muted); font-weight: 600; font-size: 11.5px; }
.ttb-row-bar.has-tyg:hover .tyg-tip, .ttb-row-bar.has-tyg:focus-visible .tyg-tip, .ttb-row-bar.show-tip .tyg-tip { display: block; }

/* ── Œil sur les mots de passe (2026-10-02) : bouton dans le champ, à droite.
   Sélecteurs à deux classes pour passer devant `.login-box .edit-input-row input`. ── */
.pw-wrap { position: relative; display: flex; flex: 1; min-width: 0; }
.edit-input-row .pw-wrap input { flex: 1; min-width: 0; width: 100%; padding-right: 38px; }
.pw-eye { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 30px; height: 30px; flex-shrink: 0; display: grid; place-items: center;
  background: none; border: 0; border-radius: 6px; color: var(--muted); cursor: pointer; padding: 0; }
.pw-eye:hover { color: var(--text); }
.pw-eye:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 1px; }
.pw-eye[aria-pressed="true"] { color: var(--accent-2); }
/* Rubrique « Sécurité » du Profil */
#profile-email-status { color: var(--text-2); line-height: 1.45; }

/* ── Offres du moment, page Actualités (2026-10-02, mockup mockup-news-offres.html,
   variante A) : même famille que « À la une » (.hl), bord turquoise. ── */
.deals { margin: 14px 0 0; padding: 14px 16px 12px; border: 1px solid rgba(0, 229, 195, .35); border-radius: var(--radius);
  background: linear-gradient(135deg, rgba(0, 229, 195, .07), rgba(124, 92, 255, .05)), var(--panel); }
.deals.hidden { display: none; }
.deals-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.deals-title { font: 700 14px 'Orbitron', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: var(--text); }
.deals-title .n { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; letter-spacing: .6px; text-transform: none; margin-left: 8px; }
.deals-src { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.deal-rail { display: flex; gap: 12px; overflow-x: auto; padding: 12px 2px 6px; scrollbar-width: thin; }
.deal { flex: none; width: 112px; padding: 0; background: none; border: 0; text-align: left; cursor: pointer; text-decoration: none; color: var(--text); font: inherit; }
.deal .cv { position: relative; width: 112px; aspect-ratio: 3 / 4; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); background: var(--bg-2); transition: border-color .15s, transform .15s; }
.deal:hover .cv { border-color: rgba(0, 229, 195, .6); transform: translateY(-2px); }
.deal:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; border-radius: 10px; }
.deal .cv img { width: 100%; height: 100%; object-fit: cover; display: block; }
.deal-pct { position: absolute; top: 6px; left: 6px; padding: 1px 7px; border-radius: 6px; background: #4c6b22; color: #beee11; font: 700 12px 'Orbitron', sans-serif; }
.deal .nm { font: 700 12.5px 'Rajdhani', sans-serif; margin-top: 6px; line-height: 1.15; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.deal-px { font: 700 12px 'Orbitron', sans-serif; color: var(--text); }
.deal-px s { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-left: 5px; }
.deal-more-tile { flex: none; width: 112px; aspect-ratio: 3 / 4; border-radius: 10px; border: 1px dashed rgba(0, 229, 195, .5); background: none; display: grid; place-items: center; text-align: center;
  color: var(--accent-2); font: 700 13px 'Rajdhani', sans-serif; padding: 8px; box-sizing: border-box; cursor: pointer; }
.deal-more-tile b { display: block; font: 700 22px 'Orbitron', sans-serif; }
.deal-more-tile:hover { background: rgba(0, 229, 195, .08); }
.deal-more-tile:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }
.deals-foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.deals-more { color: var(--accent-2); font: 700 13.5px 'Rajdhani', sans-serif; text-decoration: none; }
.deals-more:hover { text-decoration: underline; }
.deals-more b { font-family: 'Orbitron', sans-serif; font-size: 12.5px; }

/* ── Objectif du mois par jalon (2026-10-02, mockup mockup-objectif-par-jalon.html) :
   la cible dans l'étiquette, barre dorée pour le platine, choix de la cible
   dans la mise en page de « Terminer » (.ms-choice). ── */
.goal-target { color: var(--text); margin-left: 6px; padding: 1px 8px; border-radius: 999px; border: 1px solid rgba(0, 229, 195, .45); background: rgba(0, 229, 195, .08); letter-spacing: 1px; }
.goal-target.plat { border-color: rgba(255, 185, 56, .55); background: rgba(255, 185, 56, .1); color: var(--gold); }
.goal-bar.plat i { background: linear-gradient(90deg, rgba(255, 185, 56, .6), var(--gold)); }
.goal-done-btn { font-weight: 700; }
.ms-choice .when.muted { color: var(--muted); }
.ms-choice .tag { margin-left: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase; color: var(--accent-2); }
.goal-other-game { display: block; margin: 12px 0 0; padding: 0; color: var(--accent-2); }

/* ── Infos du jeu : une bande sous le « total joué », avant les onglets
   (2026-10-02, mockup mockup-fiche-section-infos.html, variante A). ── */
.facts-band { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 0 0 16px; padding: 10px 14px; border-radius: 10px;
  background: rgba(11, 13, 22, .45); border: 1px solid var(--line); }
.facts-band div { min-width: 0; }
.facts-band span { display: block; color: var(--muted); font: 700 10.5px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; }
.facts-band b { display: block; color: var(--text-2); font: 600 14px 'Rajdhani', sans-serif; }
/* « Commencé » et « Terminé » après un filet (2026-10-05, mockup
   mockup-date-de-debut.html, variante B) : vertical quand tout tient sur la
   ligne, horizontal quand « Commencé » ouvre une ligne (.wrapped, posé par
   syncFactsBandWrap() d'après la mise en page réelle). */
.facts-band .me { border-left: 1px solid var(--line); padding-left: 28px; margin-left: -2px; }
.facts-band .brk { display: none; }
.facts-band .q { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; margin-left: 5px; padding: 0;
  border-radius: 50%; border: 1px solid var(--line); background: none; color: var(--muted); font: 700 10px 'Rajdhani', sans-serif;
  letter-spacing: 0; cursor: pointer; vertical-align: 0; position: relative; }
/* Zone de toucher de 32 px autour d'un rond de 15. */
.facts-band .q::after { content: ''; position: absolute; inset: -9px; }
.facts-band .q:hover, .facts-band.tip-open .q { color: var(--accent-2); border-color: var(--accent-2); }
/* La bulle prend sa ligne en bas de la bande, dans le flux : flottante, la
   barre d'onglets collée la recouvrait. */
.facts-band .q-tip { display: none; flex-basis: 100%; padding: 8px 12px; border-radius: 8px; background: var(--panel-2);
  border: 1px solid var(--line); color: var(--text-2); font: 500 13.5px/1.4 'Rajdhani', sans-serif; }
.facts-band.tip-open .q-tip { display: block; }
.facts-band span.approx { display: inline; color: var(--accent-2); font: inherit; font-weight: 700; letter-spacing: 0; text-transform: none; }
.facts-band.wrapped .brk { display: block; flex-basis: 100%; height: 1px; background: var(--line); margin: 2px 0; }
.facts-band.wrapped .me { border-left: none; padding-left: 0; margin-left: 0; }

/* ─── Centre admin (mockup mockup-centre-admin.html, validé par Tim le 2026-10-03) ───
   Tout est préfixé adm- : .detail, .chip, .kpi, .btn existent déjà ailleurs. */
.adm-only { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; color: var(--gold);
  border: 1px solid rgba(255, 185, 56, .35); background: rgba(255, 185, 56, .08); padding: 3px 9px; border-radius: 999px; }
#adm-body { padding: 14px 0 40px; }
.adm-empty { color: var(--text-2); }

.adm-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 22px; }
.adm-kpi { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.adm-kpi .v { font: 700 24px 'Orbitron', sans-serif; }
.adm-kpi .l { color: var(--muted); font-size: 13px; text-transform: uppercase; letter-spacing: 1px; margin-top: 2px; }
.adm-kpi .s { color: var(--text-2); font-size: 14px; margin-top: 6px; }
.adm-kpi.warn .v { color: var(--gold); }
.adm-kpi.ok .v { color: var(--accent-2); }
.adm-kpi.ko .v { color: var(--danger); }
.adm-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: currentColor; margin-right: 6px; vertical-align: 1px; }

.adm-sec-title { font: 700 14px 'Orbitron', sans-serif; letter-spacing: 1.5px; margin: 0 0 10px; display: flex; align-items: center; gap: 10px; }
.adm-sec-title .cnt { color: var(--muted); font: 600 14px 'Rajdhani', sans-serif; letter-spacing: 0; }
.adm-table { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.adm-row { display: grid; grid-template-columns: 1.35fr 1.25fr 1.5fr 1fr 1fr 150px; gap: 14px; align-items: center;
  padding: 13px 16px; border-top: 1px solid var(--line); }
.adm-row.adm-head-row { border-top: 0; background: var(--bg-2); color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 1px; padding: 10px 16px; }
.adm-row.open { background: rgba(124, 92, 255, .06); }
.adm-lbl { display: none; }
.adm-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.adm-av { width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center; overflow: hidden;
  font: 700 14px 'Orbitron', sans-serif; background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #0b0d16; }
.adm-av img { width: 100%; height: 100%; object-fit: cover; }
.adm-who .n { font-weight: 700; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-who .n .me { color: var(--muted); font-weight: 600; font-size: 13px; }
.adm-meta { color: var(--muted); font-size: 13px; }
.adm-act .main { font-weight: 700; }
.adm-act .main.fresh { color: var(--accent-2); }
.adm-act .main.stale { color: var(--muted); }
.adm-days { display: flex; gap: 2px; margin-top: 5px; }
.adm-days i { width: 5px; height: 10px; border-radius: 2px; background: rgba(120, 140, 255, .14); }
.adm-days i.on { background: var(--accent-2); }
/* Jours d'avant la mise en service du suivi : pas « inactifs », inconnus. */
.adm-days i.pre { background: transparent; border: 1px dashed rgba(120, 140, 255, .18); }
.adm-plats { display: flex; flex-direction: column; gap: 5px; }
.adm-pl { display: flex; align-items: center; gap: 7px; font-size: 14px; }
.adm-chip { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .8px; padding: 2px 7px; border-radius: 6px; text-transform: uppercase; }
.adm-chip.steam { color: var(--steam); background: rgba(102, 192, 244, .12); }
.adm-chip.psn { color: var(--psn); background: rgba(74, 127, 255, .14); }
.adm-tok { color: var(--muted); font-size: 13px; }
.adm-tok.warn { color: var(--gold); font-weight: 700; }
.adm-tok.ko { color: var(--danger); font-weight: 700; }
.adm-none { color: var(--muted); font-size: 14px; font-style: italic; }
.adm-lib b { font: 700 15px 'Orbitron', sans-serif; }
.adm-lib .adm-meta { display: block; }
.adm-rel b { font-weight: 700; }
.adm-btn { width: 100%; border: 1px solid rgba(124, 92, 255, .5); background: rgba(124, 92, 255, .14); color: var(--text);
  font: 700 14px 'Rajdhani', sans-serif; letter-spacing: .5px; padding: 8px 10px; border-radius: 10px; cursor: pointer; }
.adm-btn:hover { background: rgba(124, 92, 255, .26); }
.adm-btn.running { border-color: rgba(0, 229, 195, .5); background: rgba(0, 229, 195, .1); color: var(--accent-2); cursor: default; }
.adm-btn.done { border-color: rgba(0, 229, 195, .35); background: transparent; color: var(--accent-2); }
.adm-btn.failed { border-color: rgba(255, 84, 112, .45); background: transparent; color: var(--danger); }
.adm-btn:disabled { opacity: .45; cursor: not-allowed; }
.adm-btn.running:disabled { opacity: 1; cursor: default; }
.adm-btn-sub { color: var(--muted); font-size: 12px; text-align: center; margin-top: 4px; }
.adm-more { display: block; margin: 4px auto 0; background: none; border: 0; color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; cursor: pointer; padding: 0; }
.adm-more:hover { color: var(--text); }

.adm-detail { padding: 4px 16px 16px 60px; background: rgba(124, 92, 255, .06); display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.adm-box { background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.adm-box h4 { margin: 0 0 8px; font: 700 12px 'Orbitron', sans-serif; letter-spacing: 1.2px; color: var(--text-2); }
.adm-kv { display: flex; justify-content: space-between; gap: 10px; font-size: 14px; padding: 2px 0; }
.adm-kv span { color: var(--muted); }
.adm-runs { display: flex; flex-direction: column; gap: 4px; font-size: 14px; }
.adm-runs .r { display: flex; justify-content: space-between; gap: 8px; }
.adm-ok { color: var(--accent-2); }
.adm-ko { color: var(--danger); }

/* Section Pipeline (mockup mockup-centre-admin-pipeline.html). */
.adm-pipes { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* Le centre admin en blocs (mockup mockup-admin-personnalisable.html, 2026-10-05) :
   même grille à 6 colonnes et même mode personnalisation qu'Analyses. */
.adm-head-btns { display: inline-flex; gap: 8px; flex-wrap: wrap; }
.adm-blocks { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 26px 16px; }
.adm-blocks > [data-size="full"] { grid-column: span 6; }
.adm-blocks > [data-size="half"] { grid-column: span 3; }
.adm-blocks > [data-size="third"] { grid-column: span 2; }
@media (max-width: 1000px) { .adm-blocks > [data-size] { grid-column: span 6; } }
.adm-blk { position: relative; min-width: 0; }
.adm-blocks > .ana-user-hidden { display: none; }
.adm-blk .adm-kpis { margin-bottom: 0; }
.adm-blk[data-size="half"] .adm-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.adm-blk[data-size="third"] .adm-kpis { grid-template-columns: 1fr; }
#view-admin.ana-editing .adm-blk { outline: 1px dashed rgba(0,229,195,.4); outline-offset: 6px; border-radius: 6px; cursor: grab; }
#view-admin.ana-editing .adm-blk > :not(.ana-blk-tools) { pointer-events: none; user-select: none; }
#view-admin.ana-editing .adm-blk:hover { outline-color: var(--accent-2); }
.adm-blk.dragging { opacity: .35; outline: 2px dashed var(--accent-2) !important; }
.adm-blk.moved { animation: ana-blk-moved .5s ease; }
@media (prefers-reduced-motion: reduce) { .adm-blk.moved { animation: none; } }
#view-admin .ana-edit-bar { margin: 14px 0 18px; }
#view-admin .ana-tray { margin-top: 22px; }
.adm-pipe { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; min-width: 0; }
.adm-pipe-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 12px; }
.adm-pipe-head .t { flex: 1; min-width: 0; }
.adm-pipe-head h3 { margin: 0; font: 700 15px 'Orbitron', sans-serif; letter-spacing: 1.2px; display: flex; align-items: center; gap: 8px; }
.adm-pipe-head .sub { color: var(--text-2); font-size: 14px; margin-top: 4px; }
.adm-pipe-head .sub b { color: var(--text); }
.adm-pipe-head .adm-btn { width: auto; white-space: nowrap; padding: 8px 12px; }
.adm-pipe-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; background: var(--muted); }
.adm-pipe-dot.ok { background: var(--accent-2); }
.adm-pipe-dot.warn { background: var(--gold); }
.adm-pipe-dot.ko { background: var(--danger); }
.adm-run { display: grid; grid-template-columns: 118px 1fr auto; gap: 12px; align-items: start; padding: 9px 0; border-top: 1px solid var(--line); }
.adm-run .when b { display: block; font-weight: 700; }
.adm-run .when span { color: var(--muted); font-size: 13px; }
.adm-run .what { display: flex; flex-wrap: wrap; gap: 6px; }
.adm-stat { font-size: 13px; padding: 2px 8px; border-radius: 7px; background: var(--panel-2); color: var(--text-2); white-space: nowrap; }
.adm-stat b { color: var(--text); font-weight: 700; }
.adm-stat.zero, .adm-stat.zero b { color: var(--muted); }
.adm-tag { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; padding: 2px 7px; border-radius: 6px; white-space: nowrap; }
.adm-tag.ok { color: var(--accent-2); background: rgba(0, 229, 195, .1); }
.adm-tag.ko { color: var(--danger); background: rgba(255, 84, 112, .12); }
.adm-tag.run { color: var(--text-2); background: var(--panel-2); }
.adm-fail { color: var(--danger); font-size: 13px; grid-column: 2 / 4; }

@media (max-width: 1100px) {
  .adm-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .adm-detail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Téléphone et tablette : une carte par compte, libellé à gauche, valeur à
   droite (téléphone du mockup). */
@media (max-width: 860px) {
  .adm-row.adm-head-row { display: none; }
  .adm-pipes { grid-template-columns: 1fr; }
  .adm-pipe-head { flex-wrap: wrap; }
  .adm-pipe-head > div:last-child { width: 100%; }
  .adm-pipe-head .adm-btn { width: 100%; }
  .adm-run { grid-template-columns: 96px 1fr; }
  .adm-run .adm-tag { grid-column: 2; justify-self: start; }
  .adm-fail { grid-column: 1 / 3; }
  .adm-table { background: none; border: 0; overflow: visible; }
  .adm-row { display: block; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 12px 14px; margin-bottom: 10px; }
  .adm-row.open { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .adm-row > .adm-cell { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
    font-size: 14px; margin-top: 8px; color: var(--text-2); text-align: right; }
  .adm-row > .adm-cell.adm-who-cell { margin-top: 0; }
  .adm-lbl { display: block; color: var(--muted); text-align: left; flex-shrink: 0; }
  .adm-act .adm-meta, .adm-days, .adm-rel .adm-meta { display: none; }
  .adm-plats { align-items: flex-end; }
  .adm-lib .adm-meta { display: inline; }
  .adm-lib .adm-meta::before { content: " · "; }
  .adm-row > .adm-cell.adm-action-cell { display: block; margin-top: 10px; }
  .adm-detail { grid-template-columns: 1fr; padding: 10px 14px 14px; margin-bottom: 10px;
    border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--radius) var(--radius); }
}
@media (max-width: 600px) {
  .adm-kpis { gap: 8px; }
  .adm-kpi { padding: 12px; }
  .adm-kpi .v { font-size: 20px; }
}

/* ─── Analyses : Tes jalons, Tes objectifs, Tous les blocs (mockups
   mockup-analyses-jalons-objectifs.html et mockup-analyses-menu-blocs.html,
   2026-10-03) ─────────────────────────────────────────────────────────── */
.ana-jal-kinds { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; }
.ana-jal-kind { font: 700 12.5px 'Rajdhani', sans-serif; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg-2); color: var(--text-2); }
.ana-jal-kind b { color: var(--text); font: 700 12px 'Orbitron', sans-serif; margin-right: 4px; }
.ana-jal-kind.plat { border-color: rgba(255, 185, 56, .45); color: var(--gold); }
.ana-jal-rythme { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; display: flex; gap: 14px; align-items: center; }
.ana-jal-rythme .x { font: 800 26px 'Orbitron', sans-serif; color: var(--text); flex: none; }
.ana-jal-rythme .x.slow { color: var(--gold); }
.ana-jal-rythme .x.fast { color: var(--accent-2); }
.ana-jal-rythme p { margin: 0; color: var(--text-2); font: 600 14px 'Rajdhani', sans-serif; }
.ana-jal-rythme p b { color: var(--text); }
.ana-jal-rythme small { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
.ana-jal-row { align-items: flex-start; }
.ana-jal-bar { position: relative; height: 6px; border-radius: 3px; background: var(--bg-2); margin-top: 7px; }
.ana-jal-bar i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.ana-jal-bar i.plat { background: linear-gradient(90deg, rgba(255, 185, 56, .6), var(--gold)); }
.ana-jal-bar .ref { position: absolute; top: -4px; width: 2px; height: 14px; margin-left: -1px; background: var(--text-2); border-radius: 1px; }
.ana-jal-bar .tyg { position: absolute; top: -4px; width: 3px; height: 14px; margin-left: -1.5px; background: var(--accent-2); border-radius: 1px; box-shadow: 0 0 6px rgba(0, 229, 195, .6); }
.ana-jal-ratio { font: 800 13px 'Orbitron', sans-serif; min-width: 52px; text-align: right; flex: none; }
.ana-jal-ratio small { display: block; font: 600 11.5px 'Rajdhani', sans-serif; color: var(--muted); }
.ana-jal-ratio.slow { color: var(--gold); }
.ana-jal-ratio.fast { color: var(--accent-2); }
.ana-jal-legend { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 10px; display: flex; gap: 14px; flex-wrap: wrap; }
.ana-jal-legend i { display: inline-block; width: 2px; height: 11px; vertical-align: -1px; margin-right: 5px; background: var(--text-2); }
.ana-jal-legend i.t { width: 3px; background: var(--accent-2); }

.ana-obj-tiles .ok-tile { border-color: rgba(0, 229, 195, .45); background: linear-gradient(160deg, rgba(0, 229, 195, .12), var(--bg-2)); }
.ana-obj-strip { display: flex; gap: 6px; align-items: flex-end; overflow-x: auto; padding-bottom: 2px; }
.ana-obj-month { flex: 1 0 44px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ana-obj-month > span { color: var(--muted); font: 600 11.5px 'Rajdhani', sans-serif; }
.ana-obj-dots { display: flex; flex-direction: column-reverse; gap: 4px; min-height: 18px; align-items: center; }
.ana-obj-dot { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; font: 800 10px 'Rajdhani', sans-serif; box-sizing: border-box; }
.ana-obj-dot.ok { background: var(--accent-2); color: #0b0d16; }
.ana-obj-dot.ko { border: 2px solid var(--muted); }
.ana-obj-dot.ab { border: 2px dashed rgba(139, 147, 184, .6); }
.ana-obj-dot.cur { border: 2px dashed var(--accent-2); }
.ana-obj-dot.none { background: rgba(120, 140, 255, .1); width: 10px; height: 10px; margin: 4px 0; }
.ana-obj-legend { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 10px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.ana-obj-legend .ana-obj-dot { width: 12px; height: 12px; display: inline-grid; vertical-align: -2px; margin-right: 5px; font-size: 0; }
.ana-obj-badge { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: .8px; text-transform: uppercase; padding: 2px 8px; border-radius: 6px; flex: none; white-space: nowrap; }
.ana-obj-badge.ok { color: var(--accent-2); background: rgba(0, 229, 195, .1); }
.ana-obj-badge.ko, .ana-obj-badge.ab { color: var(--muted); background: var(--bg-2); }
.ana-obj-badge.cur { color: var(--text-2); border: 1px dashed rgba(0, 229, 195, .5); }

.ana-page-head { position: relative; }
.ana-blk-btn { background: var(--panel); border: 1px solid rgba(0, 229, 195, .5); color: var(--text); font: 700 13px 'Rajdhani', sans-serif; padding: 8px 14px; border-radius: 10px; cursor: pointer; }
.ana-blk-btn:hover { border-color: var(--accent-2); }
.ana-blk-btn b { font: 700 11.5px 'Orbitron', sans-serif; color: var(--accent-2); margin-left: 4px; }
.ana-blk-pop { position: absolute; right: 0; top: calc(100% + 8px); width: 360px; max-width: calc(100vw - 32px); background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55); padding: 10px 10px 10px; z-index: 40; }
.ana-blk-grip, .ana-blk-h { display: none; }
.ana-blk-scroll { max-height: min(470px, 60vh); overflow-y: auto; }
.ana-blk-group { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; padding: 8px 8px 4px; }
.ana-blk-row { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 9px; }
.ana-blk-row[data-ana-go] { cursor: pointer; }
.ana-blk-row[data-ana-go]:hover, .ana-blk-row[data-ana-go]:focus-visible { background: rgba(124, 92, 255, .1); outline: none; }
.ana-blk-row .ic { width: 22px; text-align: center; flex: none; }
.ana-blk-row .nm { flex: 1; min-width: 0; font: 700 14px 'Rajdhani', sans-serif; color: var(--text); }
.ana-blk-row .nm small { display: block; font-weight: 600; font-size: 12px; color: var(--muted); }
.ana-blk-row .go { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; flex: none; }
.ana-blk-row:hover .go { color: var(--accent-2); }
.ana-blk-eye { flex: none; background: none; border: 1px solid var(--line); color: var(--text-2); border-radius: 8px; padding: 3px 8px; font: 700 12px 'Rajdhani', sans-serif; cursor: pointer; }
.ana-blk-eye:hover { border-color: var(--accent-2); color: var(--text); }
.ana-blk-eye.add { border-color: rgba(0, 229, 195, .5); color: var(--accent-2); }
.ana-blk-row.off .nm { color: var(--text-2); }
.ana-blk-row.na { opacity: .62; }
.ana-blk-foot { border-top: 1px solid var(--line); margin-top: 6px; padding: 9px 8px 2px; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }
.ana-blk-foot button { background: none; border: 0; color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; cursor: pointer; padding: 0; }
.ana-blk-veil { display: none; }
/* Téléphone : une feuille qui remonte du bas, comme « Plus ». */
@media (max-width: 760px) {
  .ana-blk-veil:not(.hidden) { display: block; position: fixed; inset: 0; z-index: 96; background: rgba(5, 6, 12, .55); backdrop-filter: blur(4px); }
  .ana-blk-pop { position: fixed; left: 0; right: 0; bottom: 0; top: auto; width: auto; max-width: none; z-index: 97;
    border-radius: 18px 18px 0 0; padding: 8px 10px calc(16px + env(safe-area-inset-bottom)); max-height: 78vh; display: flex; flex-direction: column; }
  .ana-blk-pop.hidden { display: none; }
  .ana-blk-grip { display: block; width: 40px; height: 4px; border-radius: 2px; background: var(--line); margin: 4px auto 8px; flex: none; }
  .ana-blk-h { display: block; font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; margin: 2px 8px 4px; }
  .ana-blk-scroll { max-height: none; flex: 1; min-height: 0; }
  .ana-blk-row .go { display: none; }
}

/* ─── Double authentification (mockup mockup-2fa.html, 2026-10-03) ─── */
.mfa-factor { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-2); margin: 12px 0 0; }
.mfa-factor + .mfa-factor { margin-top: 8px; }
.mfa-factor .ic { font-size: 18px; }
.mfa-factor .nm { flex: 1; min-width: 0; font: 700 14px 'Rajdhani', sans-serif; }
.mfa-factor .nm small { display: block; color: var(--muted); font-weight: 600; font-size: 12px; }
.mfa-factor button { background: none; border: 0; color: var(--muted); font: 700 13px 'Rajdhani', sans-serif; cursor: pointer; flex: none; }
.mfa-factor button:hover { color: var(--danger); }
.mfa-warn { border: 1px solid rgba(255, 185, 56, .45); background: rgba(255, 185, 56, .08); color: var(--text-2); border-radius: 10px; padding: 9px 12px; font: 600 13.5px 'Rajdhani', sans-serif; margin: 10px 0; }
.mfa-warn b { color: var(--gold); }
.mfa-note { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; margin: 10px 0 0; }
.mfa-actions { margin-top: 10px; }
.mfa-steps { display: flex; flex-direction: column; gap: 14px; text-align: left; }
.mfa-step { display: flex; gap: 12px; }
.mfa-step .n { width: 24px; height: 24px; border-radius: 50%; background: rgba(124, 92, 255, .25); color: var(--text); font: 800 12px 'Orbitron', sans-serif; display: grid; place-items: center; flex: none; }
.mfa-step .t { flex: 1; min-width: 0; font: 600 14px 'Rajdhani', sans-serif; color: var(--text-2); }
.mfa-step .t b { color: var(--text); }
.mfa-qr { display: flex; gap: 14px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
.mfa-qr img { width: 150px; height: 150px; background: #fff; border-radius: 8px; padding: 6px; flex: none; }
.mfa-secret { font: 700 13px 'Orbitron', sans-serif; letter-spacing: 1.5px; color: var(--text); background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; display: inline-block; margin: 4px 0; word-break: break-all; }
.mfa-code { font: 800 24px 'Orbitron', sans-serif; letter-spacing: 8px; text-align: center; width: 100%; max-width: 240px; padding: 10px 12px; border-radius: 12px; border: 1px solid rgba(124, 92, 255, .5); background: var(--bg-2); color: var(--text); }
.mfa-code:focus { outline: none; border-color: var(--accent-2); }
.mfa-code-wrap { text-align: center; margin-bottom: 12px; }
.mfa-err { color: var(--danger); font: 600 13px 'Rajdhani', sans-serif; min-height: 1em; margin-top: 6px; }
.mfa-help { color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; border-top: 1px solid var(--line); margin-top: 14px; padding-top: 10px; text-align: left; line-height: 1.45; }
.mfa-help b { color: var(--text); }
.mfa-pick { display: flex; gap: 6px; justify-content: center; margin: 0 0 10px; flex-wrap: wrap; }
.mfa-pick:empty { display: none; }
.mfa-pick button { font: 700 12.5px 'Rajdhani', sans-serif; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg-2); color: var(--text-2); cursor: pointer; }
.mfa-pick button.on { border-color: rgba(0, 229, 195, .55); color: var(--text); }
.mfa-modal .modal-box { max-width: 520px; }
.adm-reset { background: none; border: 0; color: var(--danger); font: 700 13px 'Rajdhani', sans-serif; padding: 0; margin-top: 8px; cursor: pointer; }

/* Réglages de chaque compte (mockup mockup-admin-reglages.html, variante A,
   2026-10-05) : un tableau qui défile de côté dans son cadre, jamais la page ;
   la colonne des comptes reste collée à gauche. Un point doré = choisi par la
   personne (différent du défaut). */
.adm-rg-wrap { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow-x: auto; }
.adm-rg { width: 100%; border-collapse: collapse; font: 600 14px 'Rajdhani', sans-serif; min-width: 980px; }
.adm-rg th, .adm-rg td { padding: 9px 10px; text-align: center; border-bottom: 1px solid var(--line); white-space: nowrap; }
.adm-rg thead th { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; vertical-align: bottom; }
.adm-rg thead .grp th { color: var(--accent-2); letter-spacing: 1.4px; padding-bottom: 2px; border-bottom: none; }
.adm-rg .sep { border-left: 1px solid var(--line); }
.adm-rg thead .cols th small { display: block; text-transform: none; letter-spacing: .3px; font-weight: 600; color: var(--muted); opacity: .8; margin-top: 2px; }
.adm-rg tbody th, .adm-rg thead .cols th:first-child, .adm-rg tfoot th { text-align: left; position: sticky; left: 0; background: var(--panel); z-index: 1; }
.adm-rg-who { display: flex; align-items: center; gap: 9px; }
.adm-rg-who .adm-av { width: 28px; height: 28px; font-size: 13px; }
.adm-rg-who .me { color: var(--muted); font-weight: 600; font-size: 12.5px; }
.adm-rg .on, .adm-rg-legend .on { color: var(--accent-2); font-weight: 800; }
.adm-rg .off, .adm-rg-legend .off { color: var(--muted); opacity: .55; }
.adm-rg .val { color: var(--text-2); }
.adm-rg td.chg { position: relative; }
.adm-rg td.chg::after { content: ''; position: absolute; top: 9px; right: 6px; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); }
.adm-rg tfoot td, .adm-rg tfoot th { color: var(--muted); font: 700 12.5px 'Rajdhani', sans-serif; border-bottom: none; background: var(--bg-2); }
.adm-rg tbody tr:hover td, .adm-rg tbody tr:hover th { background: rgba(124, 92, 255, .06); }
.adm-rg tbody tr:hover th { background: color-mix(in srgb, var(--panel) 94%, var(--accent)); }
.adm-rg-legend { display: flex; gap: 18px; flex-wrap: wrap; color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; margin-top: 10px; }
.adm-rg-legend i { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); margin-right: 6px; vertical-align: 1px; }

/* ─── « Nouveau sur TYG » (mockup mockup-annonces-nouveautes.html, 2026-10-03) ─── */
.nv-overlay { position: fixed; inset: 0; z-index: 640; display: grid; place-items: center; padding: 16px;
  background: radial-gradient(600px 300px at 50% 40%, rgba(124, 92, 255, .1), transparent 70%), rgba(5, 6, 12, .62); backdrop-filter: blur(4px); }
.nv-box { width: min(460px, 100%); background: linear-gradient(200deg, var(--panel-2), var(--panel)); border: 1px solid rgba(124, 92, 255, .4);
  border-radius: 20px; padding: 22px 24px 18px; box-shadow: 0 30px 80px rgba(0, 0, 0, .5), 0 0 50px rgba(124, 92, 255, .14); animation: nv-in .25s ease-out; }
@keyframes nv-in { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .nv-box { animation: none; } }
.nv-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.nv-pill { font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; color: var(--accent-2); border: 1px solid rgba(0, 229, 195, .45);
  background: rgba(0, 229, 195, .08); padding: 3px 10px; border-radius: 999px; }
.nv-count { color: var(--muted); font: 700 12px 'Orbitron', sans-serif; }
.nv-ic { width: 64px; height: 64px; border-radius: 16px; display: grid; place-items: center; font-size: 32px;
  background: linear-gradient(135deg, rgba(124, 92, 255, .35), rgba(0, 229, 195, .25)); margin-bottom: 12px; }
.nv-title { font: 800 20px 'Orbitron', sans-serif; letter-spacing: .5px; margin: 0 0 4px; color: var(--text); }
.nv-date { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-bottom: 10px; }
.nv-text { color: var(--text-2); font: 500 15px/1.5 'Rajdhani', sans-serif; margin: 0 0 16px; }
.nv-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.nv-cta { background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border: 0; font: 800 14px 'Rajdhani', sans-serif; padding: 9px 18px; border-radius: 999px; cursor: pointer; }
.nv-later { background: none; border: 1px solid var(--line); color: var(--text-2); font: 700 14px 'Rajdhani', sans-serif; padding: 8px 16px; border-radius: 999px; cursor: pointer; }
.nv-later:hover { border-color: var(--accent-2); color: var(--text); }
.nv-cta:focus-visible, .nv-later:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.nv-dots { display: flex; gap: 6px; justify-content: center; margin-top: 16px; }
.nv-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
.nv-dots i.on { background: var(--accent-2); width: 18px; border-radius: 4px; }
.nv-nav { display: flex; justify-content: space-between; margin-top: 10px; }
.nv-nav button { background: none; border: 0; color: var(--text-2); font: 700 13px 'Rajdhani', sans-serif; cursor: pointer; }
.nv-nav button:disabled { opacity: .35; cursor: default; }
.nv-foot { border-top: 1px solid var(--line); margin-top: 14px; padding-top: 10px; color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; text-align: center; }
.nv-foot button { background: none; border: 0; padding: 0; color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; cursor: pointer; }
.nv-flash { animation: nv-flash 2.2s ease-out; }
@keyframes nv-flash { 0%, 30% { box-shadow: 0 0 0 2px var(--accent-2), 0 0 24px rgba(0, 229, 195, .35); } 100% { box-shadow: none; } }

/* ── Langue et formats (mockup docs/mockups/mockup-langue.html, 2026-10-03) ─────────────────────────────────────────────
   Les sélecteurs sont posés par renderLangSwitches() dans des emplacements [data-lang-switch] ; tant que la traduction n'est
   pas livrée ils restent cachés (body.lang-ui-on les montre — voir languageUiVisible dans app.js). */
[data-lang-switch] { display: none; }
body.lang-ui-on [data-lang-switch] { display: block; }
/* Profil : le bouton de l'en-tête, la ligne du sommaire et la rubrique Langue. */
body:not(.lang-ui-on) .lang-gated { display: none !important; }
body.lang-ui-on [data-lang-switch="header"], body.lang-ui-on [data-lang-switch="footer"] { display: inline-block; }
.nav-right { display: flex; align-items: center; gap: 10px; }
.sf-bottom-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; text-align: left; }
.lang-wrap { position: relative; }
.lang-btn { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 1px solid var(--line); border-radius: 999px; color: var(--text-2); font: 700 13px 'Rajdhani', sans-serif; letter-spacing: .5px; padding: 6px 12px; cursor: pointer; transition: all .18s; }
.lang-btn:hover, .lang-btn[aria-expanded="true"] { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.lang-btn .chev { width: .8em; height: .8em; opacity: .7; }
.lang-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 320; min-width: 150px; background: var(--panel-2); border: 1px solid var(--accent); border-radius: 12px; padding: 6px; box-shadow: 0 20px 44px rgba(0, 0, 0, .5); }
.lang-wrap.up .lang-menu { top: auto; bottom: calc(100% + 8px); }
.lang-menu.hidden { display: none; }
.lang-menu button { display: flex; justify-content: space-between; align-items: center; width: 100%; background: none; border: 0; border-radius: 8px; padding: 8px 10px; color: var(--text-2); font: 700 14px 'Rajdhani', sans-serif; cursor: pointer; text-align: left; }
.lang-menu button:hover { background: rgba(124, 92, 255, .15); color: var(--text); }
.lang-menu button.on { color: var(--text); }
.lang-menu button.on::after { content: "✓"; color: var(--accent-2); }
.lang-row { display: flex; justify-content: center; gap: 6px; align-items: center; margin-top: 12px; font: 600 13px 'Rajdhani', sans-serif; color: var(--muted); }
.lang-row button { background: none; border: 0; padding: 0; font: inherit; color: var(--muted); cursor: pointer; }
.lang-row button:hover { color: var(--text); }
.lang-row button.on { color: var(--text); font-weight: 700; text-decoration: underline; text-decoration-color: var(--accent-2); text-underline-offset: 3px; }
@media (max-width: 420px) {
  .intro-nav .nav-right { gap: 6px; }
  .intro-nav .lang-btn { padding: 6px 8px; }
  .intro-nav .lang-btn .tx { display: none; }
  .sf-bottom-row { flex-direction: column; align-items: flex-start; }
}
/* Profil : la section « Langue · Language » */
.lg-block { margin-top: 16px; }
.lg-block:first-child { margin-top: 0; }
.lg-label { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); margin-bottom: 8px; }
.lg-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.lg-card { text-align: left; background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 11px 14px; cursor: pointer; color: var(--text-2); font: inherit; transition: all .18s; }
.lg-card:hover { border-color: rgba(124, 92, 255, .5); color: var(--text); }
.lg-card .nm { display: block; font: 700 17px 'Rajdhani', sans-serif; color: var(--text); }
.lg-card .ds { display: block; font: 500 12.5px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 1px; }
.lg-card.on { border-color: var(--accent); background: linear-gradient(120deg, rgba(124, 92, 255, .25), rgba(0, 229, 195, .12)); box-shadow: 0 0 14px rgba(124, 92, 255, .25); }
.lg-card.on .nm::after { content: "✓"; color: var(--accent-2); margin-left: 8px; font-size: 14px; }
.lg-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.lg-opts .chip { text-transform: none; font-size: 13.5px; letter-spacing: 0; padding: 6px 13px; border-radius: 12px; text-align: left; }
.lg-opts .chip small { display: block; font: 600 11.5px 'Rajdhani', sans-serif; color: var(--muted); margin-top: 1px; }
.lg-opts .chip.active small { color: var(--text-2); }
.lg-note { color: var(--text-2); font: 500 12.5px 'Rajdhani', sans-serif; line-height: 1.5; margin-top: 8px; }
.lg-preview { margin-top: 18px; border: 1px dashed var(--line); border-radius: 12px; padding: 10px 14px; background: rgba(11, 13, 22, .45); }
.lg-preview .pl { color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 4px; }
.lg-preview .pr { font: 600 14px 'Rajdhani', sans-serif; color: var(--text-2); line-height: 1.6; }
.lg-preview b { color: var(--text); }
@media (max-width: 420px) { .lg-cards { grid-template-columns: 1fr; } }

/* ─── Bilan de l'année (mockup docs/mockups/mockup-bilan-annee.html, validé par
   Tim le 2026-10-04) — préfixe bil- : .k, .big, .sub et .hours existent déjà. ── */
.bil-page { padding: 22px 32px 50px; max-width: 1240px; margin: 0 auto; }
@media (max-width: 700px) { .bil-page { padding: 16px 16px 40px; } }
.bil-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.bil-head h1 { font: 900 22px 'Orbitron', sans-serif; letter-spacing: 1.5px; margin: 0; }
.bil-head h1 span { color: var(--accent-2); }
.bil-head p { margin: 2px 0 0; color: var(--muted); font: 600 13px 'Rajdhani', sans-serif; }
.bil-years { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; padding: 3px; gap: 2px; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.bil-years::-webkit-scrollbar { display: none; }
.bil-years button { background: none; border: 0; color: var(--text-2); font: 700 13px 'Orbitron', sans-serif; padding: 5px 12px; border-radius: 999px; cursor: pointer; flex-shrink: 0; }
.bil-years button.on { background: rgba(124, 92, 255, .25); color: var(--text); }
.bil-years button:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.bil-empty { color: var(--text-2); font: 500 15px 'Rajdhani', sans-serif; padding: 30px 0; }

.bil-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.bil-card { position: relative; background: linear-gradient(200deg, var(--panel-2), var(--panel)); border: 1px solid var(--line); border-radius: 16px;
  padding: 16px 18px 18px; min-width: 0; overflow: hidden; }
.bil-k { font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: 6px; margin-bottom: 10px; padding-right: 36px; }
.bil-k .ico { color: var(--accent-2); }
.bil-big { font: 900 40px/1 'Orbitron', sans-serif; letter-spacing: .5px; color: var(--text); }
.bil-big small { font: 700 18px 'Orbitron', sans-serif; color: var(--text-2); margin-left: 4px; }
.bil-sub { color: var(--text-2); font: 600 15px/1.35 'Rajdhani', sans-serif; margin-top: 6px; text-wrap: pretty; }
.bil-sub b { color: var(--text); }
.bil-meta { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin-top: 8px; }
.bil-share { position: absolute; top: 10px; right: 10px; width: 32px; height: 32px; border-radius: 10px; border: 1px solid transparent; background: none;
  color: var(--muted); display: grid; place-items: center; cursor: pointer; flex-shrink: 0; }
.bil-card:hover .bil-share, .bil-share:focus-visible { color: var(--text); border-color: var(--line); background: rgba(255, 255, 255, .03); }
.bil-share:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* Pas de survol sur un écran tactile : le bouton reste visible. */
@media (hover: none) { .bil-share { color: var(--text-2); border-color: var(--line); } }

.bil-btn-cta { background: linear-gradient(120deg, var(--accent), var(--accent-2)); color: #0b0d16; border: 0; font: 800 14px 'Rajdhani', sans-serif;
  padding: 9px 16px; border-radius: 999px; cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
.bil-btn-ghost { background: none; border: 1px solid var(--line); color: var(--text-2); font: 700 14px 'Rajdhani', sans-serif;
  padding: 8px 14px; border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.bil-btn-ghost:hover { color: var(--text); border-color: rgba(124, 92, 255, .5); }
.bil-btn-cta:focus-visible, .bil-btn-ghost:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

.bil-hero { grid-column: 1 / -1; display: grid; grid-template-columns: 1.2fr 1fr; gap: 22px; align-items: center; padding: 22px 24px;
  background: radial-gradient(600px 260px at 0% 0%, rgba(124, 92, 255, .28), transparent 70%), radial-gradient(500px 240px at 100% 100%, rgba(0, 229, 195, .12), transparent 70%), var(--panel); }
.bil-hero .bil-big { font-size: 64px; }
.bil-hero .bil-big small { font-size: 24px; }
.bil-platbar { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: var(--bg-2); margin: 4px 0 10px; }
.bil-platbar i { display: block; height: 100%; }
.bil-platleg { display: flex; flex-wrap: wrap; gap: 6px 16px; color: var(--text-2); font: 600 14px 'Rajdhani', sans-serif; }
.bil-platleg span::before { content: ''; display: inline-block; width: 9px; height: 9px; border-radius: 3px; background: var(--c); margin-right: 6px; vertical-align: 0; }
.bil-platleg b { font: 700 13px 'Orbitron', sans-serif; color: var(--text); margin-left: 3px; }
.bil-hero-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.bil-hero-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.bil-hero-stats div { background: rgba(11, 13, 22, .45); border: 1px solid var(--line); border-radius: 12px; padding: 8px 12px; }
.bil-hero-stats b { display: block; font: 800 20px 'Orbitron', sans-serif; }
.bil-hero-stats span { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }

.bil-goty { grid-row: span 2; display: flex; flex-direction: column; }
.bil-goty-cover { width: 100%; aspect-ratio: 3 / 4; max-height: 290px; object-fit: cover; border-radius: 12px; box-shadow: 0 18px 40px rgba(0, 0, 0, .45); margin-bottom: 14px; }
.bil-goty-name { font: 800 17px 'Orbitron', sans-serif; letter-spacing: .4px; margin-bottom: 6px; }

.bil-top5 { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.bil-top5 li { display: grid; grid-template-columns: 18px 30px minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.bil-top5 li > div { min-width: 0; }
.bil-top5 .rk { font: 700 12px 'Orbitron', sans-serif; color: var(--muted); text-align: center; }
.bil-top5 img { width: 30px; height: 40px; object-fit: cover; border-radius: 5px; }
.bil-top5 .nm { font: 700 14.5px 'Rajdhani', sans-serif; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bil-top5 .bar { height: 4px; border-radius: 3px; background: var(--bg-2); margin-top: 3px; overflow: hidden; }
.bil-top5 .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); border-radius: 3px; }
.bil-top5 .h { font: 700 13px 'Orbitron', sans-serif; color: var(--text); }

.bil-months { display: grid; grid-template-columns: repeat(12, 1fr); gap: 5px; align-items: end; height: 118px; margin-top: 4px; }
.bil-months div { display: flex; flex-direction: column; align-items: center; gap: 5px; height: 100%; justify-content: flex-end; }
.bil-months i { display: block; width: 100%; border-radius: 4px 4px 2px 2px; background: rgba(124, 92, 255, .38); }
.bil-months .top i { background: linear-gradient(180deg, var(--accent-2), var(--accent)); }
.bil-months .cur i { background: repeating-linear-gradient(135deg, rgba(124, 92, 255, .38) 0 4px, rgba(124, 92, 255, .18) 4px 8px); }
.bil-months .fut i { background: none; border: 1px dashed var(--line); }
.bil-months span { font: 700 11px 'Rajdhani', sans-serif; color: var(--muted); }
.bil-months .top span { color: var(--accent-2); }

.bil-hours { display: grid; grid-template-columns: repeat(24, 1fr); gap: 2px; align-items: end; height: 54px; margin-top: 12px; }
.bil-hours i { display: block; border-radius: 2px; background: rgba(0, 229, 195, .30); }
.bil-hours i.pk { background: var(--accent-2); }
.bil-hours-ax { display: flex; justify-content: space-between; color: var(--muted); font: 600 11px 'Rajdhani', sans-serif; margin-top: 3px; }

.bil-covers { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.bil-covers img { width: 46px; height: 61px; object-fit: cover; border-radius: 6px; border: 1px solid rgba(255, 185, 56, .5); }
.bil-plat .bil-big { color: var(--gold); }
.bil-plat .bil-k .ico { color: var(--gold); }
.bil-split2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.bil-split2 .bil-big { font-size: 34px; }

.bil-origin { display: flex; gap: 10px; align-items: flex-start; margin-top: 14px; padding: 12px 14px; border-radius: 12px; background: var(--bg-2); border: 1px solid var(--line); }
.bil-origin .ico { color: var(--accent-2); margin-top: 3px; }
.bil-origin p { margin: 0; color: var(--text-2); font: 500 14.5px/1.45 'Rajdhani', sans-serif; }
.bil-origin b { color: var(--text); }

@media (max-width: 980px) {
  .bil-grid { grid-template-columns: 1fr 1fr; }
  .bil-hero { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .bil-grid { grid-template-columns: 1fr; }
  .bil-goty { grid-row: auto; }
  .bil-goty-cover { max-height: 220px; width: auto; align-self: flex-start; }
  .bil-hero { padding: 16px; }
  .bil-hero .bil-big { font-size: 48px; }
}

/* Bandeau d'Analyses, du 15 au 31 décembre */
.bil-banner { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-radius: 14px; margin: 14px 0 0;
  background: linear-gradient(110deg, rgba(124, 92, 255, .22), rgba(0, 229, 195, .10)); border: 1px solid rgba(124, 92, 255, .4); }
.bil-banner .yr { font: 900 26px 'Orbitron', sans-serif; letter-spacing: 1px; color: var(--text); }
.bil-banner .txt { flex: 1; min-width: 0; }
.bil-banner .txt b { display: block; font: 700 15px 'Rajdhani', sans-serif; color: var(--text); }
.bil-banner .txt span { color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; }
.bil-banner-x { width: 32px; height: 32px; border-radius: 10px; border: 1px solid var(--line); background: none; color: var(--text-2); display: grid; place-items: center; cursor: pointer; flex-shrink: 0; }
@media (max-width: 600px) { .bil-banner { flex-wrap: wrap; } .bil-banner .txt { flex-basis: calc(100% - 120px); } }

/* Fenêtre de partage */
.bil-share-bg { position: fixed; inset: 0; background: rgba(5, 6, 12, .72); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center;
  padding: 16px; z-index: 1200; overflow: auto; }
.bil-sh-box { width: 100%; max-width: 820px; margin: auto; background: linear-gradient(200deg, var(--panel-2), var(--panel)); border: 1px solid rgba(124, 92, 255, .4);
  border-radius: 20px; padding: 20px 22px; box-shadow: 0 30px 80px rgba(0, 0, 0, .5), 0 0 50px rgba(124, 92, 255, .14);
  display: grid; grid-template-columns: 300px 1fr; gap: 22px; position: relative; box-sizing: border-box; }
.bil-sh-x { position: absolute; top: 12px; right: 12px; width: 32px; height: 32px; border-radius: 10px; border: 1px solid var(--line); background: none; color: var(--text-2); display: grid; place-items: center; cursor: pointer; }
.bil-sh-title { font: 800 17px 'Orbitron', sans-serif; letter-spacing: .5px; margin: 0 0 4px; padding-right: 40px; }
.bil-sh-sub { color: var(--text-2); font: 500 14px 'Rajdhani', sans-serif; margin: 0 0 12px; }
.bil-sh-lbl { font: 700 11.5px 'Rajdhani', sans-serif; letter-spacing: 1.3px; text-transform: uppercase; color: var(--muted); margin: 12px 0 6px; }
.bil-sh-text { width: 100%; box-sizing: border-box; min-height: 92px; resize: vertical; background: var(--bg-2); color: var(--text); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; font: 500 14.5px/1.45 'Rajdhani', sans-serif; }
.bil-sh-opt { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--line); cursor: pointer; }
.bil-sh-opt:first-of-type { border-top: 0; }
.bil-sh-opt b { display: block; font: 700 14.5px 'Rajdhani', sans-serif; }
.bil-sh-opt span { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; }
.bil-sw { position: relative; width: 38px; height: 22px; flex-shrink: 0; }
.bil-sw input { opacity: 0; width: 0; height: 0; position: absolute; }
.bil-sw i { position: absolute; inset: 0; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line); cursor: pointer; transition: background .15s; }
.bil-sw i::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--muted); transition: transform .15s, background .15s; }
.bil-sw input:checked + i { background: rgba(0, 229, 195, .25); border-color: rgba(0, 229, 195, .5); }
.bil-sw input:checked + i::after { transform: translateX(16px); background: var(--accent-2); }
.bil-sw input:focus-visible + i { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.bil-sh-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.bil-sh-note { color: var(--muted); font: 600 12.5px 'Rajdhani', sans-serif; margin-top: 10px; }
.bil-sh-canvas { width: min(300px, 100%); height: auto; aspect-ratio: 4 / 5; border-radius: 14px; border: 1px solid rgba(124, 92, 255, .35); display: block; background: #0b0d16; }
.bil-img-caption { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; margin-top: 6px; text-align: center; }
@media (max-width: 760px) { .bil-sh-box { grid-template-columns: 1fr; justify-items: center; } .bil-sh-box > div:last-child { width: 100%; } }
@media (prefers-reduced-motion: reduce) { .bil-sw i, .bil-sw i::after { transition: none; } }

/* ─── Modes de jeu (2026-10-05, mockup mockup-modes-de-jeu.html) ───
   Le mode par défaut reste neutre (--muted), les autres ont leur couleur. */
.mode-chip { display: inline-flex; align-items: center; gap: 6px; font: 700 12.5px 'Rajdhani', sans-serif; padding: 3px 10px;
  border-radius: 999px; border: 1px solid var(--line); color: var(--text-2); background: none; cursor: pointer; }
.mode-chip .dot, .modes-line .dot, .mode-row .dot, .ttb-note.modes .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--muted)); flex-shrink: 0; }
.mode-chip.on { border-color: var(--c, var(--accent-2)); color: var(--text); background: color-mix(in srgb, var(--c, var(--accent-2)) 18%, transparent); }
.mode-chip.sug::after { content: attr(data-sug-label); font: 600 10.5px 'Rajdhani', sans-serif; color: var(--muted); text-transform: uppercase; letter-spacing: .8px; }
.mode-ask { border: 1px solid var(--line); border-left: 3px solid var(--accent-2); border-radius: 10px; background: var(--panel-2);
  padding: 10px 14px; margin: 12px 0 4px; display: grid; gap: 8px; }
.mode-ask .q { font: 600 14.5px 'Rajdhani', sans-serif; color: var(--text); }
.mode-ask .q small { color: var(--muted); font-weight: 600; margin-left: 4px; }
.mode-ask .row { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.mode-ask .hint { color: var(--text-2); font: 500 13px 'Rajdhani', sans-serif; }
.mode-ask .hint .ico { color: var(--gold); }
.mode-ask .foot { color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.mode-ask.done .ok { color: var(--accent-2); font: 700 14px 'Rajdhani', sans-serif; }
.ttb-note.modes { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; margin-top: 6px; }
.ttb-note.modes .m { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font: 600 13px 'Rajdhani', sans-serif; }
.ttb-note.modes .m small { color: var(--muted); font-weight: 600; }
.session-log-entry .plat-row .right { display: inline-flex; align-items: center; gap: 10px; }
.mode-pick { position: relative; }
.mode-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 6; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 6px; display: grid; gap: 4px; min-width: 150px; box-shadow: 0 10px 28px rgba(0, 0, 0, .45); }
.mode-menu .mode-chip { justify-content: flex-start; border-color: transparent; }
.mode-menu .mode-chip.on { border-color: var(--c); }
.modes-line { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; padding: 8px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: rgba(11, 13, 22, .45); margin: 0 0 12px; }
.modes-line .lbl { color: var(--muted); font: 700 11px 'Rajdhani', sans-serif; letter-spacing: 1.2px; text-transform: uppercase; }
.modes-line .m { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font: 600 13.5px 'Rajdhani', sans-serif; }
.modes-line .m.none { color: var(--muted); }
.modes-line .act { margin-left: auto; background: none; border: none; color: var(--accent-2); font: 700 12.5px 'Rajdhani', sans-serif; cursor: pointer; }
.modes-config { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: -6px 0 12px; }
.modes-list { display: grid; gap: 8px; }
.mode-row { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; }
.mode-row .dot { width: 10px; height: 10px; }
.mode-row .nm { font: 700 14px 'Rajdhani', sans-serif; color: var(--text); min-width: 0; }
.mode-row .nm small { display: block; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.mode-row-act { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.mode-row-act label { display: inline-flex; gap: 6px; align-items: center; color: var(--text-2); font: 600 12.5px 'Rajdhani', sans-serif; white-space: nowrap; }
.mode-row-btn { background: none; border: 1px solid var(--line); border-radius: 999px; color: var(--text-2); font: 700 11.5px 'Rajdhani', sans-serif;
  padding: 2px 9px; cursor: pointer; display: inline-flex; align-items: center; }
.mode-row-btn:hover { color: var(--text); border-color: var(--accent-2); }
.mode-add { display: flex; gap: 8px; margin-top: 10px; }
.mode-add input { flex: 1; min-width: 0; }
.mode-sugs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; color: var(--muted); font: 600 12px 'Rajdhani', sans-serif; }
.mode-sugs .chip { font-size: 12.5px; padding: 3px 10px; }
@media (max-width: 600px) { .mode-row { grid-template-columns: auto 1fr; } .mode-row-act { grid-column: 1 / -1; justify-content: flex-start; } }
/* Chronomètre : la question à l'arrêt remplace « en cours » et ses boutons. */
.session-overlay.asking .session-actions { display: none; }
.session-overlay.asking .session-live { color: var(--accent-2); }
.session-ask { display: grid; gap: 10px; margin: 6px 0 4px; justify-items: start; }
.session-ask .q { font: 600 16px 'Rajdhani', sans-serif; color: var(--text); }
.session-ask .row { display: flex; gap: 8px; flex-wrap: wrap; }
.session-ask .mode-chip { font-size: 14px; padding: 6px 14px; }
