/* ════════════════════════════════════════════════════════════════════
   THÈME — Épuré minimal SO FOOT
   Chargé après bulma.min.css et style.css : surcharge les couleurs,
   bordures et ombres pour un rendu sobre.
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Note historique : --so-yellow était la couleur brand jaune SO FOOT.
     Renommé conceptuellement en "accent" mais la variable garde le même
     nom pour ne pas avoir à toucher tous les selectors qui l'utilisent.
     Valeur actuelle : un bleu plus clair que le navy vintage, pour
     contraster avec lui sans casser la cohérence chromatique. */
  --so-yellow: #5b73b8;
  --score-bg: #1c2a5c;
  /* navy — couleur dédiée au score */
  --score-fg: #f4e6c8;
  --bg: #fafafa;
  --card-bg: #ffffff;
  --border: #e8e8e8;
  --border-soft: #ddd;
  --black: #111111;
  --gray-text: #555555;
  --gray-soft: #999999;

  --prob-high-bg: #DBEAFE;
  /* bonus 1 — bleu pastel   (probable, peu de pts) */
  --prob-high-fg: #1E40AF;
  --prob-mid-bg: #FFE0CC;
  /* bonus 2 — orange pastel (peu probable) */
  --prob-mid-fg: #994D00;
  --prob-low-bg: #FCCFCF;
  /* bonus 3 — rouge pastel  (très peu probable, gros pts) */
  --prob-low-fg: #991B1B;
}

/* ─── Base ───────────────────────────────────────────────────────── */

html,
body {
  background-color: var(--bg);
}

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-weight: 400;
  color: var(--black);
}

.title,
.subtitle,
h1,
h2,
h3,
h4,
h5,
h6 {
  color: var(--black);
  font-family: inherit;
  font-weight: 600;
}

.subtitle {
  color: var(--gray-text);
  font-weight: 400;
}

/* Pas de gras dans les paragraphes courants — seul <strong> conservé. */
p,
.content p {
  font-weight: 400;
}

.has-text-grey {
  color: var(--gray-text) !important;
}

.has-text-grey-light {
  color: var(--gray-soft) !important;
}

.has-text-grey-dark {
  color: var(--gray-text) !important;
}

a {
  color: var(--black);
}

a:hover {
  color: var(--black);
  text-decoration: underline;
}

/* ─── Cartes (.box) ──────────────────────────────────────────────── */

.box {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: none;
  padding: 12px;
}

/* ─── Boutons : outline noir partout ─────────────────────────────── */

.button,
.button.is-light,
.button.is-info,
.button.is-warning,
.button.is-success {
  background: transparent;
  color: var(--black);
  border: 1px solid var(--black);
  border-radius: 4px;
  font-weight: 500;
  box-shadow: none;
}

.button:hover,
.button.is-light:hover,
.button.is-info:hover,
.button.is-warning:hover,
.button.is-success:hover {
  background: var(--black);
  color: #fff;
  border-color: var(--black);
}

/* Bouton primaire : jaune plein / texte noir → noir / texte jaune au hover. */
.button.is-primary {
  background: var(--so-yellow);
  color: var(--black);
  border: 1px solid var(--so-yellow);
  border-radius: 4px;
  font-weight: 600;
  box-shadow: none;
}

.button.is-primary:hover,
.button.is-primary:focus,
.button.is-primary:focus-visible {
  background: var(--black);
  color: var(--so-yellow);
  border-color: var(--black);
}

.button.is-danger,
.button.is-danger.is-light {
  background: transparent;
  color: var(--black);
  border: 1px solid var(--border-soft);
}

.button.is-danger:hover,
.button.is-danger.is-light:hover {
  background: #fee2e2;
  color: var(--prob-mid-fg);
  border-color: var(--prob-mid-fg);
}

.button[disabled],
.button.is-loading {
  opacity: 0.5;
}

.button.is-static {
  background: transparent;
  color: var(--gray-text);
  border-color: var(--border-soft);
}

/* ─── Inputs / forms ─────────────────────────────────────────────── */

.input,
.textarea,
.select select {
  background: var(--input-bg, #fff);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font-size: 13px;
  color: var(--black);
  box-shadow: none;
}

/* Options du <select> natif — sans ça, certains browsers rendent le
   panel déroulant en thème système, donc texte blanc sur fond blanc
   en dark mode si le système est en light. */
.select select option {
  background: var(--card-bg, #fff);
  color: var(--black);
}

.input:focus,
.textarea:focus,
.select select:focus,
.input:focus-within,
.select select:focus-within {
  border-color: var(--black);
  box-shadow: none;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--gray-soft);
}

.label {
  font-weight: 600;
  color: var(--black);
  font-size: 13px;
}

.help {
  color: var(--gray-soft);
}

.help.is-danger {
  color: var(--prob-mid-fg);
}

.help.is-success {
  color: var(--gray-text);
}

/* ─── Badges (.tag) ──────────────────────────────────────────────── */

.tag,
.tag:not(body) {
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  background: var(--tag-bg, var(--bg));
  color: var(--gray-text);
  border: none;
}

.tag.is-medium {
  font-size: 13px;
  padding: 3px 10px;
}

/* Badges de bonus — 3 niveaux par couleur */
.tag.prob-high {
  background: var(--prob-high-bg);
  color: var(--prob-high-fg);
}

.tag.prob-mid {
  background: var(--prob-mid-bg);
  color: var(--prob-mid-fg);
}

.tag.prob-low {
  background: var(--prob-low-bg);
  color: var(--prob-low-fg);
}

/* Pastille bonus sur les cellules de grille (3 niveaux mêmes couleurs) */
.grid-cell__prob-dot.prob-high {
  background: var(--prob-high-fg);
}

.grid-cell__prob-dot.prob-mid {
  background: var(--prob-mid-fg);
}

.grid-cell__prob-dot.prob-low {
  background: var(--prob-low-fg);
}

/* Tags "Réalisé / Raté / À venir / En cours / Terminée" — neutres */
.tag.is-success,
.tag.is-warning,
.tag.is-info,
.tag.is-link,
.tag.is-light {
  background: var(--bg);
  color: var(--gray-text);
}

.tag.is-success.is-light,
.tag.is-warning.is-light,
.tag.is-info.is-light,
.tag.is-link.is-light {
  background: #fff;
  color: var(--gray-text);
  border: 1px solid var(--border-soft);
}

/* Score — badge slate dédié, distinct du jaune des boutons primaires */
#score-display {
  cursor: pointer;
}

#score-display .tag.score-tag {
  background: var(--score-bg);
  color: var(--score-fg);
  border: none;
  border-radius: 4px;
  font-weight: 600;
  padding: 3px 10px;
  font-size: 14px;
  box-shadow: none;
}

#score-display:hover .tag.score-tag,
#score-display:focus-visible .tag.score-tag {
  border: none;
  box-shadow: none;
  filter: brightness(1.15);
}

#score-display .tag.score-tag strong {
  color: var(--score-fg);
  font-weight: 700;
}

/* Statut grille "Brouillon / Validée" — pill discret, dans la même
   famille visuelle que les badges de bonus (radius 10px, font 11px).
   Brouillon : fond gris très clair / texte gris.
   Validée   : fond noir / texte blanc.
   On force la hauteur en `auto` pour ne pas hériter du `height: 2em` Bulma
   qui faisait déborder le texte du pill. */
#grid-status,
#grid-status.tag,
#grid-status.tag.is-warning,
#grid-status.tag.is-success,
#grid-status.tag.is-light {
  display: inline-flex;
  align-items: center;
  height: auto;
  line-height: 1;
  padding: 4px 10px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  font-style: normal;
  white-space: nowrap;
  margin-left: 6px;
  background: #f0f0f0;
  color: var(--gray-text);
  border: none;
}

/* « Brouillon » (Bulma applique is-warning) */
#grid-status.tag.is-warning {
  background: #f0f0f0;
  color: var(--gray-text);
}

/* « Validée » (Bulma applique is-success) */
#grid-status.tag.is-success {
  background: var(--black);
  color: #fff;
}

/* ─── Grille — cellules ──────────────────────────────────────────── */

.grid-cell {
  background: var(--card-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  color: var(--black);
}

.grid-cell--empty {
  background: transparent;
  border-style: dashed;
  border-color: #ddd;
}

.grid-cell--empty::after {
  color: #ccc;
  font-size: 20px;
  content: '+';
}

body.mode-readonly .grid-cell--empty::after {
  content: none;
}

.grid-cell--filled {
  border-style: solid;
  border-color: var(--border-soft);
  cursor: grab;
}

body.mode-readonly .grid-cell--filled {
  cursor: default;
}

.grid-cell--filled:active {
  cursor: grabbing;
}

.grid-cell--realized {
  background: #fff;
  border-color: var(--black);
}

.grid-cell--bonus {
  border-color: var(--so-yellow);
  box-shadow: 0 0 0 1px var(--so-yellow) inset;
  background: #fffbe5;
}

.grid-cell--bonus.grid-cell--realized {
  border-color: var(--so-yellow);
  background: #fffbe5;
  box-shadow: 0 0 0 1px var(--so-yellow) inset;
}

.grid-cell--counter {
  border-color: var(--black);
  box-shadow: 0 0 0 1px var(--black) inset;
  background: #fff;
}

.grid-cell--counter.grid-cell--realized {
  border-color: var(--border-soft);
  box-shadow: none;
  background: #f5f5f5;
}

/* Coche réalisé / contre-pied gagnant */
.grid-cell--realized .grid-cell__check,
.grid-cell--counter-won .grid-cell__check {
  color: var(--black);
}

/* Bingo de ligne — halo subtil jaune SOFOOT */
.grid-cell--in-line {
  background: #fffce0;
  box-shadow:
    0 0 0 1px var(--so-yellow) inset,
    0 0 6px 0 rgba(254, 225, 0, 0.35);
  animation: theme-line-pulse 3.5s ease-in-out infinite;
}

.grid-cell--in-line::before {
  background:
    linear-gradient(90deg, transparent 0%, rgba(254, 225, 0, 0.18) 50%, transparent 100%);
}

@keyframes theme-line-pulse {

  0%,
  100% {
    box-shadow: 0 0 0 1px var(--so-yellow) inset, 0 0 5px 0 rgba(254, 225, 0, 0.25);
  }

  50% {
    box-shadow: 0 0 0 1px var(--so-yellow) inset, 0 0 8px 1px rgba(254, 225, 0, 0.45);
  }
}

/* ─── Catalogue ─────────────────────────────────────────────────── */

.catalog-item {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  box-shadow: none;
}

.catalog-item:hover {
  border-color: var(--black);
  background: var(--card-bg);
}

.catalog-item__title {
  font-weight: 600;
  color: var(--black);
  font-size: 13px;
}

.catalog-item__description {
  font-size: 12px;
  color: var(--gray-soft);
}

.catalog-item__add.button {
  background: transparent;
  color: var(--black);
  border: 1px solid var(--black);
  border-radius: 4px;
  font-size: 11px;
  height: 26px;
  font-weight: 500;
}

.catalog-item__add.button:hover {
  background: var(--black);
  color: #fff;
}

.catalog-item__usage {
  background: var(--bg);
  color: var(--gray-soft);
  border-radius: 10px;
}

/* ─── Navbar — sobre, non sombre ────────────────────────────────── */

.navbar.is-dark {
  background: transparent;
  border-bottom: 1px solid var(--border);
}

.navbar.is-dark,
.navbar.is-dark .navbar-item,
.navbar.is-dark a.navbar-item,
.navbar.is-dark .navbar-link {
  color: var(--black);
  background: transparent;
}

.navbar.is-dark .navbar-item:hover,
.navbar.is-dark a.navbar-item:hover {
  background: transparent;
  color: var(--black);
}

.navbar.is-dark .navbar-item.is-active {
  background: transparent;
  color: var(--black);
}

.navbar.is-dark .brand,
.navbar.is-dark .brand strong {
  color: var(--black);
}

/* Pipe de séparation après le logo */
.navbar.is-dark .brand strong {
  font-weight: 600;
  position: relative;
  padding-left: 0.7rem;
  margin-left: 0.4rem;
}

.navbar.is-dark .brand strong::before {
  content: '|';
  position: absolute;
  left: 0;
  color: var(--border-soft);
  font-weight: 400;
}

.nav-help-circle {
  border-color: var(--border-soft);
  color: var(--gray-text);
}

.navbar-item img.player-avatar {
  border: 2px solid var(--border-soft);
  background: #fff;
}

.navbar-avatar-item:hover img.player-avatar,
.navbar-avatar-item.is-active img.player-avatar {
  border-color: var(--black);
}

/* Bouton hamburger sidebar */
#btn-sidebar-toggle.sidebar-toggle {
  color: var(--black);
}

/* ─── Footer ────────────────────────────────────────────────────── */

.footer {
  background: transparent;
  padding: 1.5rem;
  border-top: 1px solid var(--border);
}

.footer,
.footer p,
.footer a {
  color: var(--gray-soft);
}

.footer a {
  text-decoration: underline;
}

/* ─── Sidebar ─────────────────────────────────────────────────── */

.sidebar-content {
  background: #fff;
}

.sidebar-links a {
  color: var(--black);
}

.sidebar-links a:hover {
  background: var(--bg);
  color: var(--black);
}

.sidebar-phase {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.sidebar-footer {
  border-top: 1px solid var(--border);
  background: var(--bg);
  color: var(--gray-soft);
}

/* ─── Modales ─────────────────────────────────────────────────── */

.modal-card {
  border-radius: 8px;
  box-shadow: none;
}

.modal-card-head,
.modal-card-foot {
  background: #fff;
  border-bottom: 1px solid var(--border);
}

.modal-card-foot {
  border-top: 1px solid var(--border);
  border-bottom: none;
}

.modal-card-title {
  color: var(--black);
  font-weight: 600;
}

.modal-card-body {
  background: #fff;
}

.modal-background {
  background-color: rgba(17, 17, 17, 0.6);
}

/* ─── Tableaux ────────────────────────────────────────────────── */

.table {
  background: transparent;
  color: var(--black);
}

.table th {
  color: var(--black);
  font-weight: 600;
  font-size: 12px;
  border-bottom: 1px solid var(--border);
}

.table td {
  border-bottom: 1px solid var(--border);
}

.table.is-striped tbody tr:nth-child(even) {
  background: var(--bg);
}

.table.is-hoverable tbody tr:hover {
  background: var(--bg);
}

/* Surlignage podium leaderboard — discret */
.has-background-warning-light {
  background-color: #fffce0 !important;
}

.has-background-light {
  background-color: var(--bg) !important;
}

/* ─── Notifications ──────────────────────────────────────────── */

.notification {
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--black);
}

.notification.is-warning {
  background: #fffce0;
  border-color: var(--so-yellow);
  color: var(--black);
}

.notification.is-danger {
  background: #fff;
  border-color: var(--prob-mid-fg);
  color: var(--prob-mid-fg);
}

.notification.is-success {
  background: var(--bg);
  border-color: var(--border);
  color: var(--gray-text);
}

.notification.is-info {
  background: var(--bg);
  border-color: var(--border);
  color: var(--black);
}

/* ─── Toast ──────────────────────────────────────────────────── */

.toast-notification {
  background: #fff;
  border: 1px solid var(--black);
  color: var(--black);
  border-radius: 6px;
  box-shadow: none;
}

.toast-notification.is-info,
.toast-notification.is-success,
.toast-notification.is-warning,
.toast-notification.is-danger {
  background: #fff;
  color: var(--black);
}

/* ─── Header de la grille : éviter le débordement à largeur réduite ─── */
/* Sur les fenêtres tablet/desktop étroites (par ex. ~1158px), la barre
   d'en-tête de la grille (titre + statut + actions + score) ne tient
   pas en une seule ligne et le score finit par déborder dans la
   colonne catalogue. On autorise le wrap. */
@media (min-width: 769px) and (max-width: 1215px) {
  #col-grid>.box>.level {
    flex-wrap: wrap;
    row-gap: 8px;
  }

  #col-grid>.box>.level>.level-right {
    margin-left: 0;
    width: 100%;
    justify-content: flex-start;
  }
}

/* ─── Catalogue : overlay « Retirer la tuile » ───────────────── */

#col-catalog .box {
  position: relative;
}

.catalog-drop-overlay {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.92);
  border: 2px dashed var(--black);
  border-radius: 8px;
  z-index: 10;
  font-weight: 600;
  font-size: 14px;
  color: var(--black);
  pointer-events: none;
}

.catalog-drop-overlay .icon {
  font-size: 28px;
  color: var(--prob-mid-fg);
}

/* Activé pendant un drag depuis la grille */
body.is-dragging-from-grid .catalog-drop-overlay {
  display: flex;
}

body.is-dragging-from-grid #col-catalog .box {
  border-color: var(--black);
}

/* ─── Slider bonus (admin) ───────────────────────────────────── */

.prob-slider {
  accent-color: var(--black);
}

/* ─── Picto SVG des événements (The Noun Project) ──────────────── */

/* Catalogue : petit picto à gauche du texte */
.catalog-item__icon {
  flex: 0 0 26px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.catalog-item__icon:empty {
  display: none;
}

.catalog-item__icon svg,
.catalog-item__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Grille : picto centré au-dessus du libellé */
.grid-cell--filled {
  flex-direction: column;
  gap: 4px;
}

.grid-cell__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
}

.grid-cell__icon:empty {
  display: none;
}

.grid-cell__icon svg,
.grid-cell__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Composition de 2 pictos : picto 1 en fond, picto 2 par-dessus,
   décalé à droite et réduit à 60 %. Le conteneur doit être un carré. */
.picto-dual {
  position: relative;
}

.picto-dual .picto--1,
.picto-dual .picto--2 {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
}

.picto-dual .picto--1 {
  inset: 0;
}

/* picto 2 = emoji posé en haut à droite (sans fond ni cercle) */
.picto-dual .picto--2 {
  left: 58%;
  top: -27%;
  width: 60%;
  height: 60%;
}

.picto-dual .picto--1 svg,
.picto-dual .picto--1 img,
.picto-dual .picto--2 svg,
.picto-dual .picto--2 img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Admin : recherche & sélection d'icône */
.icon-results {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  max-height: 220px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
}

.icon-result {
  width: 56px;
  height: 56px;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-result:hover {
  border-color: var(--black);
}

.icon-result img {
  max-width: 100%;
  max-height: 100%;
}

.icon-result.is-loading {
  opacity: 0.45;
}

/* Emplacements de pictos (form admin) : slot 1, slot 2, aperçu composé */
.icon-slots {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 6px 0;
}

.icon-slot {
  position: relative;
  width: 48px;
  height: 48px;
  border: 1px dashed var(--border-soft);
  border-radius: 6px;
  background: #fff;
  padding: 5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-slot.is-target {
  border: 2px solid var(--black);
  border-style: solid;
}

.icon-slot__badge {
  position: absolute;
  top: -7px;
  left: -7px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--black);
  color: #fff;
  font-size: 10px;
  line-height: 16px;
  text-align: center;
}

.icon-slot__preview {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-slot__preview svg,
.icon-slot__preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.icon-slot__empty {
  position: absolute;
  font-size: 9px;
  color: var(--gray-soft);
  pointer-events: none;
}

.icon-slot.is-filled .icon-slot__empty {
  display: none;
}

.icon-slot--preview {
  cursor: default;
  border-style: solid;
}

/* Rendu direct (image seule / emoji seul / composition) dans un slot-aperçu */
.icon-slot--preview>svg,
.icon-slot--preview>img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.icon-slots__sep {
  font-size: 11px;
  color: var(--gray-soft);
}

.emoji-input {
  width: 4rem;
  text-align: center;
  font-size: 1.1rem;
}

/* Emoji picker (modale) */
.emoji-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  max-height: 50vh;
  overflow-y: auto;
}

.emoji-pick {
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 22px;
  line-height: 1;
  background: #fff;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.emoji-pick:hover {
  border-color: var(--black);
  background: var(--bg);
}


/* Picto dans la liste admin des événements */
.row-icon {
  display: inline-flex;
  vertical-align: middle;
  width: 20px;
  height: 20px;
  margin-right: 6px;
}

.row-icon:empty {
  display: none;
}

.row-icon svg,
.row-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Picto dans la modale de détails d'un événement (centré) */
.event-details-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 1rem;
}
.event-details-icon:empty { display: none; }
.event-details-icon > svg, .event-details-icon > img { width: 100%; height: 100%; object-fit: contain; }

/* Liste admin : titre en gras + description grise dessous */
.row-event .row-titre { display: inline; }
.row-event .row-desc {
  display: block;
  color: var(--gray-text);
  font-size: 11px;
  margin-top: 1px;
}

/* ─── Mobile : grille edge-to-edge + onglets ─────────────────── */
/* Sur mobile, on retire les marges/paddings horizontaux autour
   de la grille pour gagner de la place sur les tuiles. */
@media (max-width: 768px) {

  /* Basculer entre les deux colonnes selon l'onglet sélectionné */
  body[data-mobile-tab="grid"] #col-catalog {
    display: none;
  }

  body[data-mobile-tab="catalog"] #col-grid {
    display: none;
  }

  /* ─── Swipe horizontal entre onglets (retour visuel en suivi) ───
     Pendant le geste, les deux colonnes coexistent : l'active reste
     dans le flux et translate avec le doigt, l'incoming est en
     position absolue par-dessus, décalée pour entrer depuis l'autre
     bord. La var --swipe-x (px, signée) est posée par js/grid.js. */
  body.is-swiping #app-layout {
    position: relative;
    touch-action: pan-y;
  }

  body.is-swiping #col-grid,
  body.is-swiping #col-catalog {
    display: block !important;
    will-change: transform, opacity;
  }

  /* Active : reste dans le flux, suit le doigt */
  body.is-swiping[data-mobile-tab="grid"] #col-grid,
  body.is-swiping[data-mobile-tab="catalog"] #col-catalog {
    transform: translateX(var(--swipe-x, 0px));
  }

  /* Incoming : superposé en absolu, glisse depuis le bord opposé */
  body.is-swiping[data-mobile-tab="grid"] #col-catalog {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    transform: translateX(calc(100% + var(--swipe-x, 0px)));
    opacity: calc(0.55 + 0.45 * var(--swipe-progress, 0));
  }

  body.is-swiping[data-mobile-tab="catalog"] #col-grid {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    transform: translateX(calc(-100% + var(--swipe-x, 0px)));
    opacity: calc(0.55 + 0.45 * var(--swipe-progress, 0));
  }

  /* Release : transition douce vers commit ou retour */
  body.is-swipe-finishing #col-grid,
  body.is-swipe-finishing #col-catalog {
    transition: transform 0.22s cubic-bezier(0.22, 0.61, 0.36, 1),
      opacity 0.22s ease-out;
  }

  /* Indicateur d'onglet : la barre jaune progresse vers la
     destination pendant le swipe (effet de "pré-bascule"). */
  body.is-swiping #mobile-tabs li.is-active a {
    border-bottom-color: color-mix(in srgb,
        var(--so-yellow) calc((1 - var(--swipe-progress, 0)) * 100%),
        var(--gray-soft) 0%);
  }

  body.is-swiping[data-mobile-tab="grid"] #mobile-tabs li[data-mobile-tab="catalog"] a,
  body.is-swiping[data-mobile-tab="catalog"] #mobile-tabs li[data-mobile-tab="grid"] a {
    border-bottom-color: color-mix(in srgb,
        var(--so-yellow) calc(var(--swipe-progress, 0) * 100%),
        transparent 0%);
    color: color-mix(in srgb,
        var(--black) calc(var(--swipe-progress, 0) * 100%),
        var(--gray-soft) 0%);
  }

  /* Onglets : design clair "selected = jaune sur noir, inactif = gris" */
  #mobile-tabs {
    margin: 0 0 12px 0;
    background: var(--bg);
    border-bottom: 2px solid var(--border);
    overflow: visible;
  }

  #mobile-tabs ul {
    border-bottom: none;
  }

  #mobile-tabs li {
    flex: 1;
    text-align: center;
  }

  #mobile-tabs li a {
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    padding: 12px 8px;
    color: var(--gray-soft);
    font-weight: 600;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: transparent;
    transition: color 0.15s ease, border-color 0.15s ease;
  }

  #mobile-tabs li a:hover {
    color: var(--black);
  }

  #mobile-tabs li.is-active a {
    color: var(--black);
    border-bottom-color: var(--so-yellow);
  }

  /* Edge-to-edge sur la page jeu pour maximiser la place disponible
     pour la grille ET le catalogue (symétrie : les deux colonnes ont
     la même largeur visuelle, cf. user request).
     Scopé via body[data-mobile-tab] pour ne pas casser les marges
     du contenu plein-largeur des autres pages (aide, classement, …). */
  body[data-mobile-tab] #col-grid,
  body[data-mobile-tab] #col-catalog {
    padding-left: 0;
    padding-right: 0;
  }

  body[data-mobile-tab] #col-grid>.box,
  body[data-mobile-tab] #col-catalog>.box {
    border-radius: 0;
    border-left: none;
    border-right: none;
    padding-left: 8px;
    padding-right: 8px;
  }

  body[data-mobile-tab] #app-layout.columns {
    margin-left: 0;
    margin-right: 0;
  }

  body[data-mobile-tab] .section {
    padding-left: 0;
    padding-right: 0;
  }

  body[data-mobile-tab] .container {
    padding-left: 0;
    padding-right: 0;
  }

  /* Bulma 1.0 applique margin: 0 20px sur .modal-card en mobile mais ne
     contraint pas sa largeur, ce qui peut faire déborder à droite si du
     contenu a width: 100% intrinsèque. On force juste la largeur à
     `100vw − 40px` pour matcher la marge Bulma — le centrage est géré par
     le flex de .modal et les margins de Bulma. */
  .modal-card,
  .modal-content,
  .modal-card.is-wide {
    width: calc(100vw - 40px);
    max-width: calc(100vw - 40px);
  }
}