/* =====================================================================
 * RESERVE SIDEBAR V2
 * Loaded after dashboard.css → inherits design tokens (--accent, --bg, etc.)
 * Scoped under .v2-rv so it never collides with anything else.
 * ===================================================================== */

@layer components {

  /* ---------- Outer panel — bulletproof width with !important
                because dashboard.css has competing rules ---------- */
  #reserve_sidebar.v2-rv.reserve-sidebar,
  #reserve_sidebar.v2-rv {
    inline-size: 380px !important;
    max-inline-size: 94vw !important;
    block-size: 100dvh !important;
    margin-inline-start: auto !important;
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: 0.875rem;
    line-height: 1.5;
    /* layout: flex column with scrollable middle */
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    /* slide-in animation */
    transform: translateX(100%);
    transition: transform 0.22s var(--ease-out);
    /* defaults for court color */
    --court-h1: oklch(56% 0.18 252);
    --court-h2: oklch(48% 0.22 252);
  }
  #reserve_sidebar.v2-rv.reserve-sidebar.open,
  #reserve_sidebar.v2-rv.open { transform: translateX(0) !important; }

  /* Mobile: take full width */
  @media (max-width: 640px) {
    #reserve_sidebar.v2-rv.reserve-sidebar,
    #reserve_sidebar.v2-rv {
      inline-size: 100vw !important;
      max-inline-size: 100vw !important;
    }
  }
  .v2-rv * { box-sizing: border-box; }
  .v2-rv :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
  .v2-rv h1, .v2-rv h2, .v2-rv h3 { margin: 0; letter-spacing: -0.015em; font-family: var(--font-display); }
  .v2-rv p { margin: 0; }
  .v2-rv button {
    font: inherit; cursor: pointer; border: 0; color: inherit;
  }
  .v2-rv input, .v2-rv select, .v2-rv textarea { font: inherit; color: inherit; }

  .v2-rv-shell {
    display: flex; flex-direction: column;
    flex: 1; min-block-size: 0;
    overflow: hidden;
  }

  /* ============================================================
   * HEADER (court color)
   * ============================================================ */
  .v2-rv-head {
    position: relative;
    padding: 1rem 1.125rem 1.25rem;
    background:
      radial-gradient(120% 80% at 90% 0%, color-mix(in oklch, var(--court-h2) 65%, white 0%) 0%, transparent 60%),
      linear-gradient(135deg, var(--court-h1), var(--court-h2));
    color: white;
    overflow: hidden;
  }
  .v2-rv-head::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(to bottom, transparent 60%, oklch(0% 0 0 / 0.10));
    pointer-events: none;
  }
  .v2-rv-eyebrow {
    display: flex; align-items: center; gap: 0.4rem;
    font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.85);
  }
  .v2-rv-eyebrow svg { inline-size: 14px; block-size: 14px; }
  .v2-rv-title {
    font-family: var(--font-display);
    font-size: 1.375rem; font-weight: 800; line-height: 1.15;
    margin-block-start: 0.25rem; color: white;
    text-wrap: balance;
  }
  .v2-rv-pills {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    margin-block-start: 0.875rem;
  }
  .v2-rv-pill {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.375rem 0.7rem;
    background: rgba(255,255,255,0.18);
    border: 1px solid rgba(255,255,255,0.28);
    color: white; border-radius: 999px;
    font-size: 0.8125rem; font-weight: 600;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }
  .v2-rv-pill svg { inline-size: 14px; block-size: 14px; }
  .v2-rv-close {
    position: absolute; top: 0.875rem; right: 0.875rem;
    inline-size: 36px; block-size: 36px;
    border-radius: 10px;
    display: grid; place-items: center; color: white;
    background: rgba(255,255,255,0.15);
    border: 1px solid rgba(255,255,255,0.25);
    transition: background 0.15s var(--ease-out);
  }
  .v2-rv-close:hover { background: rgba(255,255,255,0.25); }
  .v2-rv-close svg { inline-size: 18px; block-size: 18px; }

  /* ============================================================
   * BODY (scrolling container)
   * ============================================================ */
  .v2-rv-body {
    flex: 1;
    min-block-size: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    padding: 1rem;
    display: flex; flex-direction: column;
    gap: 1.125rem;
  }

  .v2-rv-section-label {
    display: flex; align-items: center; gap: 0.4rem;
    font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-3);
    margin-block-end: 0.625rem;
  }
  .v2-rv-section-label svg { inline-size: 14px; block-size: 14px; }
  .v2-rv-section-label .end {
    margin-inline-start: auto;
    text-transform: none; letter-spacing: 0;
    font-size: 0.75rem; font-weight: 500; color: var(--text-2);
  }
  .v2-rv-section-label .end b { color: var(--text); font-weight: 700; }

  /* Alerts */
  .v2-rv-alerts { display: flex; flex-direction: column; gap: 0.5rem; }
  .v2-rv-alert {
    display: flex; align-items: flex-start; gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    border-radius: var(--radius);
    font-size: 0.8125rem;
  }
  .v2-rv-alert svg { inline-size: 18px; block-size: 18px; flex: none; margin-top: 1px; }
  .v2-rv-alert .body { flex: 1; min-inline-size: 0; }
  .v2-rv-alert .body b { font-weight: 700; }
  .v2-rv-alert .action {
    margin-top: 0.375rem;
    display: inline-flex; align-items: center; gap: 0.25rem;
    font-weight: 700; font-size: 0.75rem;
    text-decoration: underline;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 3px;
  }
  .v2-rv-alert.info { background: light-dark(oklch(96% 0.04 220), oklch(26% 0.08 220)); color: light-dark(oklch(38% 0.15 220), oklch(82% 0.10 220)); }
  .v2-rv-alert.warn { background: var(--warning-soft); color: light-dark(oklch(35% 0.13 60), oklch(85% 0.10 75)); }

  /* Compact info row (used when only one option for player count / duration) */
  .v2-rv-inline-info {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 0.8125rem;
    color: var(--text-2);
  }
  .v2-rv-inline-info svg { inline-size: 14px; block-size: 14px; color: var(--text-3); flex: none; }
  .v2-rv-inline-info .lbl { font-weight: 500; }
  .v2-rv-inline-info .val {
    margin-inline-start: auto;
    font-family: var(--font-display);
    font-weight: 800; font-size: 0.9375rem;
    color: var(--text);
  }
  .v2-rv-inline-info .meta {
    font-size: 0.75rem; color: var(--text-3); font-weight: 500;
  }
  .v2-rv-inline-info .meta b { color: var(--text-2); font-weight: 700; }

  /* ── Code portier (door code) — en édition, pour les clubs à système d'accès.
     Carte accentuée : c'est l'info que l'utilisateur vient chercher. */
  .v2-rv-doorcode {
    display: flex; align-items: center; gap: 0.75rem;
    margin-block-end: 0.875rem;
    padding: 0.75rem 1rem;
    background: color-mix(in oklab, var(--accent) 10%, var(--surface-2));
    border: 1px solid color-mix(in oklab, var(--accent) 35%, var(--border));
    border-radius: 12px;
  }
  .v2-rv-doorcode-icon {
    display: grid; place-items: center;
    inline-size: 34px; block-size: 34px; flex: none;
    border-radius: 9px;
    background: color-mix(in oklab, var(--accent) 18%, transparent);
    color: var(--accent);
  }
  .v2-rv-doorcode-icon svg { inline-size: 18px; block-size: 18px; }
  .v2-rv-doorcode-body { display: flex; flex-direction: column; gap: 1px; min-inline-size: 0; }
  .v2-rv-doorcode-label {
    font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.04em; color: var(--text-3);
  }
  .v2-rv-doorcode-value {
    font-family: var(--font-display, inherit);
    font-weight: 800; font-size: 1.35rem; letter-spacing: 0.12em;
    color: var(--text); font-variant-numeric: tabular-nums;
  }

  /* ============================================================
   * Selectable cards (joueurs / durée)
   * ============================================================ */
  .v2-rv-cards { display: grid; gap: 0.5rem; }
  .v2-rv-cards.cols-4 { grid-template-columns: repeat(4, 1fr); }
  .v2-rv-cards.cols-3 { grid-template-columns: repeat(3, 1fr); }
  .v2-rv-cards.cols-2 { grid-template-columns: repeat(2, 1fr); }

  /* Cards — modern color palette with subtle tint on inactive,
     vibrant diagonal gradient on active */
  .v2-rv-card {
    background: linear-gradient(180deg,
      var(--surface) 0%,
      color-mix(in oklch, var(--accent) 4%, var(--surface-2)) 100%);
    border: 1.5px solid color-mix(in oklch, var(--accent) 18%, var(--text-3));
    border-radius: 12px;
    padding: 0.625rem 0.5rem;
    min-block-size: 56px;
    text-align: center; cursor: pointer;
    display: grid; gap: 3px; place-items: center;
    color: var(--text);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      0 1px 2px color-mix(in oklch, var(--accent) 8%, rgba(15, 23, 42, 0.06)),
      0 4px 10px color-mix(in oklch, var(--accent) 6%, rgba(15, 23, 42, 0.05));
    transition: all 0.18s var(--ease-out);
  }
  @media (prefers-color-scheme: dark) {
    .v2-rv-card {
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.05),
        0 1px 2px rgba(0, 0, 0, 0.4),
        0 4px 10px rgba(0, 0, 0, 0.3);
    }
  }
  .v2-rv-card:hover {
    border-color: var(--accent);
    background: linear-gradient(180deg,
      color-mix(in oklch, var(--accent) 6%, var(--surface)) 0%,
      color-mix(in oklch, var(--accent) 14%, var(--surface)) 100%);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.9),
      0 6px 16px color-mix(in oklch, var(--accent) 30%, transparent),
      0 12px 28px color-mix(in oklch, var(--accent) 14%, transparent);
  }
  .v2-rv-card:active { transform: translateY(0); transition: transform 0.05s; }
  .v2-rv-card.is-active {
    background: linear-gradient(135deg,
      oklch(64% 0.20 245) 0%,
      oklch(55% 0.22 268) 50%,
      oklch(50% 0.22 285) 100%);
    border-color: color-mix(in oklch, var(--accent) 75%, black);
    color: white;
    box-shadow:
      inset 0 1px 0 0 rgba(255, 255, 255, 0.35),
      inset 0 -1px 0 0 rgba(0, 0, 0, 0.10),
      0 4px 14px color-mix(in oklch, oklch(58% 0.22 270) 42%, transparent),
      0 8px 24px color-mix(in oklch, oklch(58% 0.22 270) 22%, transparent),
      0 1px 3px color-mix(in oklch, var(--accent) 30%, transparent);
    transform: translateY(0);
  }
  .v2-rv-card.is-active:hover {
    background: linear-gradient(135deg,
      oklch(68% 0.20 245) 0%,
      oklch(58% 0.22 268) 50%,
      oklch(53% 0.22 285) 100%);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 0 rgba(255, 255, 255, 0.45),
      inset 0 -1px 0 0 rgba(0, 0, 0, 0.12),
      0 10px 28px color-mix(in oklch, oklch(58% 0.22 270) 50%, transparent),
      0 16px 40px color-mix(in oklch, oklch(58% 0.22 270) 28%, transparent);
  }
  .v2-rv-card[disabled],
  .v2-rv-card.is-disabled {
    opacity: 0.4; cursor: not-allowed;
  }
  .v2-rv-card .num {
    font-family: var(--font-display);
    font-size: 1.625rem; font-weight: 800;
    color: var(--text); line-height: 1;
  }
  .v2-rv-card.is-active .num { color: white; }
  .v2-rv-card .lbl {
    font-size: 0.625rem; font-weight: 700; letter-spacing: 0.08em;
    color: var(--text-2); text-transform: uppercase;
    margin-block-start: 4px;
  }
  .v2-rv-card.is-active .lbl { color: rgba(255, 255, 255, 0.85); }
  .v2-rv-card.duration {
    flex-direction: row; padding: 0.625rem 0.875rem;
    text-align: start;
    display: flex; align-items: center; justify-content: center; gap: 6px;
  }
  .v2-rv-card.duration .num { font-size: 1rem; }
  .v2-rv-card.duration .lbl {
    font-size: 0.75rem; font-weight: 500; letter-spacing: 0;
    text-transform: none; color: var(--text-3); margin-block-start: 0;
  }
  .v2-rv-card.duration .lbl::before { content: '· '; }
  .v2-rv-card.duration.is-active .lbl { color: rgba(255, 255, 255, 0.75); }

  /* ============================================================
   * Articles
   * ============================================================ */
  .v2-rv-article {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.625rem 0.875rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-block-end: 0.4rem;
  }
  .v2-rv-article .ico {
    inline-size: 32px; block-size: 32px; flex: none;
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-2);
    display: grid; place-items: center;
  }
  .v2-rv-article .ico svg { inline-size: 16px; block-size: 16px; }
  .v2-rv-article .info { flex: 1; min-inline-size: 0; }
  .v2-rv-article .name { font-weight: 600; font-size: 0.875rem; }
  .v2-rv-article .price-row { font-size: 0.75rem; color: var(--text-3); margin-top: 1px; }

  .v2-rv-qty {
    display: inline-flex; align-items: center;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
  }
  .v2-rv-qty button {
    inline-size: 28px; block-size: 28px;
    color: var(--text-2);
    transition: background 0.15s var(--ease-out);
  }
  .v2-rv-qty button:hover { background: var(--surface-3); color: var(--text); }
  .v2-rv-qty .val {
    min-inline-size: 32px; text-align: center;
    font-weight: 700; font-size: 0.8125rem;
  }

  .v2-rv-add-article {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.625rem 0.875rem;
    background: var(--surface);
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-2); font-size: 0.8125rem; font-weight: 600;
    inline-size: 100%;
    transition: border-color 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-add-article:hover { border-color: var(--accent); color: var(--accent); border-style: solid; }
  .v2-rv-add-article svg { inline-size: 16px; block-size: 16px; }

  /* ============================================================
   * Partners
   * ============================================================ */
  .v2-rv-partners-head {
    display: flex; align-items: center; gap: 0.5rem;
    margin-block-end: 0.625rem;
  }
  .v2-rv-partners-head .v2-rv-section-label { margin: 0; }

  /* Match button — toggle pill (clearly a button : ombre + chevron + état actif) */
  .v2-rv-cta-match {
    margin-inline-start: auto;
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.45rem 0.85rem;
    background: var(--surface);
    border: 1px solid color-mix(in oklch, var(--accent) 35%, var(--border));
    color: var(--accent-text);
    font-size: 0.75rem; font-weight: 700;
    border-radius: 999px;
    box-shadow:
      0 1px 0 color-mix(in oklch, var(--accent) 8%, transparent) inset,
      0 1px 2px rgba(0, 0, 0, 0.06);
    transition: background 0.15s var(--ease-out), border-color 0.15s var(--ease-out),
                box-shadow 0.15s var(--ease-out), transform 0.08s var(--ease-out),
                color 0.15s var(--ease-out);
  }
  .v2-rv-cta-match:hover {
    background: color-mix(in oklch, var(--accent) 12%, var(--surface));
    border-color: var(--accent);
    box-shadow:
      0 1px 0 color-mix(in oklch, var(--accent) 18%, transparent) inset,
      0 3px 8px color-mix(in oklch, var(--accent) 18%, transparent);
    transform: translateY(-1px);
  }
  .v2-rv-cta-match:focus-visible {
    outline: 2px solid color-mix(in oklch, var(--accent) 60%, transparent);
    outline-offset: 2px;
  }
  .v2-rv-cta-match:active {
    transform: translateY(0);
    box-shadow:
      0 1px 0 color-mix(in oklch, var(--accent) 18%, transparent) inset,
      0 1px 2px rgba(0, 0, 0, 0.08);
  }
  /* État actif (toggle = ON) : pill remplie aux couleurs de l'accent + étoile blanche */
  .v2-rv-cta-match[aria-pressed="true"],
  .v2-rv-cta-match.is-active {
    background: linear-gradient(135deg,
                  color-mix(in oklch, var(--accent) 92%, white),
                  var(--accent));
    border-color: var(--accent);
    color: #fff;
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.25) inset,
      0 4px 10px color-mix(in oklch, var(--accent) 35%, transparent);
  }
  .v2-rv-cta-match[aria-pressed="true"] .v2-rv-cta-match-star,
  .v2-rv-cta-match.is-active .v2-rv-cta-match-star {
    color: #ffd54a;
    fill: #ffd54a;
    filter: drop-shadow(0 0 4px rgba(255, 215, 64, 0.55));
  }
  /* État désactivé (pas d'abonnement Défi-Plugin pour le format courant) */
  .v2-rv-cta-match[aria-disabled="true"],
  .v2-rv-cta-match:disabled {
    cursor: not-allowed;
    opacity: 0.55;
    box-shadow: none;
    transform: none;
  }
  .v2-rv-cta-match[aria-disabled="true"]:hover,
  .v2-rv-cta-match:disabled:hover {
    background: var(--surface);
    border-color: color-mix(in oklch, var(--accent) 25%, var(--border));
    transform: none;
    box-shadow: none;
  }
  .v2-rv-cta-match svg {
    inline-size: 13px; block-size: 13px;
  }
  .v2-rv-cta-match-star {
    color: oklch(72% 0.16 75);
    fill: oklch(72% 0.16 75);
    transition: color 0.15s var(--ease-out), fill 0.15s var(--ease-out),
                filter 0.15s var(--ease-out);
  }
  .v2-rv-cta-match-chev {
    inline-size: 11px; block-size: 11px;
    opacity: 0.7;
    transition: transform 0.2s var(--ease-out), opacity 0.15s var(--ease-out);
  }
  .v2-rv-cta-match[aria-pressed="true"] .v2-rv-cta-match-chev,
  .v2-rv-cta-match.is-active .v2-rv-cta-match-chev {
    transform: rotate(180deg);
    opacity: 1;
  }

  /* Toggle « Amical / Compétitif » — visible uniquement en mode Match Défi-Plugin */
  .v2-rv-match-type {
    display: flex; align-items: center; gap: 0.625rem;
    margin: 0 0 0.625rem 0;
    padding: 0.5rem 0.75rem;
    background: color-mix(in oklch, var(--accent) 5%, var(--surface));
    border: 1px solid color-mix(in oklch, var(--accent) 22%, var(--border));
    border-radius: 10px;
    font-size: 0.75rem;
  }
  .v2-rv-match-type[hidden] { display: none; }
  .v2-rv-match-type .lbl {
    color: var(--text-2);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.6875rem;
  }
  .v2-rv-seg {
    display: inline-flex;
    padding: 2px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    gap: 2px;
  }
  .v2-rv-seg-btn {
    padding: 0.3rem 0.75rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-2);
    background: transparent;
    transition: background 0.12s var(--ease-out), color 0.12s var(--ease-out);
  }
  .v2-rv-seg-btn:hover:not(.is-active) {
    background: color-mix(in oklch, var(--accent) 7%, transparent);
    color: var(--text);
  }
  .v2-rv-seg-btn.is-active {
    background: var(--accent);
    color: #fff;
    box-shadow: 0 1px 2px color-mix(in oklch, var(--accent) 30%, transparent);
  }

  /* Chip row (favorites + invite) */
  .v2-rv-chip-row {
    display: flex; flex-wrap: wrap; gap: 0.4rem;
    margin-block-end: 0.5rem;
  }
  .v2-rv-quota {
    font-size: 0.6875rem;
    color: var(--text-3);
    font-weight: 600;
    margin-block-end: 0.625rem;
  }
  .v2-rv-quota b { color: var(--text-2); font-weight: 700; }

  /* « Info supplémentaires (nom complet des invités) » — champ TEXTE GLOBAL
     qui apparaît sous la liste des joueurs quand au moins un invité est ajouté
     et que le typereservation (responsable ou invité) a `isNomInvite=true`.
     Parité legacy `#nomInvite` (sidebarlogedinpop.php L1552). */
  .v2-rv-guest-extra {
    margin-block-start: 0.75rem;
    padding: 0.625rem 0.75rem;
    background: light-dark(oklch(97% 0.01 95), oklch(22% 0.02 95));
    border: 1px solid light-dark(oklch(88% 0.01 95), oklch(32% 0.03 95));
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }
  .v2-rv-guest-extra-label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text-3);
    text-transform: uppercase;
  }
  .v2-rv-guest-extra-label svg { color: var(--text-3); flex: none; }
  .v2-rv-guest-extra > .v2-rv-input {
    inline-size: 100%;
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    border: 1px solid light-dark(oklch(85% 0.01 90), oklch(36% 0.03 90));
    background: light-dark(oklch(99% 0.005 95), oklch(18% 0.015 95));
    font-size: 0.8125rem;
  }
  .v2-rv-guest-extra > .v2-rv-input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: transparent;
  }

  /* Pill chip — solid pale blue bg, clear border, multiple-per-line friendly */
  .v2-rv-chip {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.4rem 0.875rem 0.4rem 0.4rem;
    background: light-dark(oklch(92% 0.045 252), oklch(28% 0.08 252));
    border: 1.5px solid light-dark(oklch(68% 0.10 252), oklch(50% 0.08 252));
    border-radius: 999px;
    font-size: 0.8125rem; font-weight: 700;
    color: var(--text);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.55),
      0 1px 2px rgba(15, 23, 42, 0.08),
      0 3px 6px rgba(15, 23, 42, 0.06);
    transition: all 0.15s var(--ease-out);
    white-space: nowrap;
  }
  .v2-rv-chip:hover {
    background: light-dark(oklch(88% 0.07 252), oklch(35% 0.10 252));
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 6px 14px color-mix(in oklch, var(--accent) 30%, transparent),
      0 12px 24px color-mix(in oklch, var(--accent) 14%, transparent);
  }
  .v2-rv-chip:active { transform: translateY(0); transition: transform 0.05s; }
  .v2-rv-chip[disabled],
  .v2-rv-chip.is-used {
    opacity: 0.4; cursor: not-allowed; transform: none;
    box-shadow: none;
  }
  .v2-rv-chip .v2-rv-avatar {
    inline-size: 24px; block-size: 24px;
    font-size: 0.5625rem;
  }

  /* Invite chip — dashed border, neutral gray bg so it's clearly different from favorites */
  .v2-rv-chip.add {
    padding: 0.4rem 0.875rem;
    border-style: dashed;
    color: var(--text-2);
  }
  .v2-rv-chip.add:hover {
    border-style: solid;
    color: var(--accent);
    background: light-dark(oklch(94% 0.04 252), oklch(30% 0.08 252));
    border-color: var(--accent);
  }
  .v2-rv-chip.add svg { inline-size: 14px; block-size: 14px; }

  /* Row : tighter gap so multiple chips fit per line */
  .v2-rv-chip-row { gap: 0.4rem 0.4rem; }

  /* Avatars */
  .v2-rv-avatar {
    inline-size: 24px; block-size: 24px; flex: none;
    border-radius: 999px;
    display: grid; place-items: center;
    color: white; font-weight: 800; font-size: 0.625rem;
    letter-spacing: 0.02em;
  }
  .v2-rv-avatar.lg { inline-size: 36px; block-size: 36px; font-size: 0.8125rem; }
  .av-c0 { background: linear-gradient(135deg, oklch(70% 0.15 200), oklch(55% 0.18 220)); }
  .av-c1 { background: linear-gradient(135deg, oklch(70% 0.15 145), oklch(52% 0.18 155)); }
  .av-c2 { background: linear-gradient(135deg, oklch(68% 0.18 295), oklch(52% 0.20 285)); }
  .av-c3 { background: linear-gradient(135deg, oklch(68% 0.16 252), oklch(52% 0.20 252)); }
  .av-c4 { background: linear-gradient(135deg, oklch(72% 0.16 18),  oklch(58% 0.20 22)); }
  .av-c5 { background: linear-gradient(135deg, oklch(76% 0.15 75),  oklch(60% 0.18 60)); }
  .av-c6 { background: linear-gradient(135deg, oklch(70% 0.16 332), oklch(52% 0.20 332)); }
  .av-c7 { background: linear-gradient(135deg, oklch(70% 0.14 175), oklch(52% 0.17 185)); }
  .av-gray { background: var(--surface-3); color: var(--text-3); border: 1px solid var(--border); }

  /* Search bar */
  .v2-rv-search {
    position: relative;
    margin-block-end: 0.625rem;
  }
  .v2-rv-search-input {
    inline-size: 100%;
    padding: 0.625rem 0.875rem 0.625rem 2.25rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 0.8125rem;
    transition: border-color 0.15s var(--ease-out);
  }
  .v2-rv-search-input:focus { border-color: var(--accent); outline: none; }
  .v2-rv-search-icon {
    position: absolute; inset-block: 0; inset-inline-start: 0.75rem;
    display: grid; place-items: center;
    color: var(--text-3); pointer-events: none;
  }
  .v2-rv-search-icon svg { inline-size: 16px; block-size: 16px; }

  .v2-rv-suggestions {
    position: absolute; inset-block-start: calc(100% + 4px); inset-inline: 0;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    z-index: 100;
    isolation: isolate;
    display: none;
    padding: 5px;
  }
  .v2-rv-suggestions.is-open { display: block; }
  .v2-rv-suggestion {
    display: flex; align-items: center; gap: 1rem;
    inline-size: 100%;
    padding: 5px;
    text-align: start;
    border-bottom: 1px solid var(--border);
    transition: background 0.15s var(--ease-out);
  }
  .v2-rv-suggestion:last-child { border-bottom: 0; }
  .v2-rv-suggestion:hover, .v2-rv-suggestion.is-focus { background: var(--surface-2); }
  .v2-rv-suggestion .info { flex: 1; min-inline-size: 0; }
  .v2-rv-suggestion .name { font-weight: 600; font-size: 0.8125rem; }
  .v2-rv-suggestion .meta { font-size: 0.6875rem; color: var(--text-3); margin-top: 1px; }
  .v2-rv-suggestion mark {
    background: color-mix(in oklch, var(--accent) 25%, transparent);
    color: inherit; padding: 0;
  }
  /* Hint affiché en mode Match (recherche vide) — pousse à taper un nom */
  .v2-rv-suggestion-hint {
    padding: 0.75rem 0.875rem;
    color: var(--text-3);
    font-size: 0.75rem;
    line-height: 1.35;
    border-radius: 6px;
    background: color-mix(in oklch, var(--accent) 5%, var(--surface));
  }
  /* Badge inline « Hors-club » dans la meta d'une suggestion (mode match) */
  .v2-rv-suggestion-badge {
    display: inline-block;
    padding: 1px 6px;
    margin-inline-end: 2px;
    border-radius: 999px;
    background: color-mix(in oklch, var(--accent) 12%, var(--surface));
    color: var(--accent-text);
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
  }
  /* Style « match mode actif » du wrap de recherche — accentue la bordure pour
     signaler que la source de la recherche a changé. */
  .v2-rv-search.is-match-mode .v2-rv-search-input {
    border-color: color-mix(in oklch, var(--accent) 55%, var(--border));
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 12%, transparent);
  }
  /* Badge « ★ Défi-Plugin » sur la chip d'un joueur ajouté via match mode */
  .v2-rv-badge.league {
    display: inline-flex; align-items: center;
    padding: 1px 7px;
    margin-inline-start: 6px;
    border-radius: 999px;
    background: color-mix(in oklch, var(--accent) 18%, var(--surface));
    color: var(--accent-text);
    border: 1px solid color-mix(in oklch, var(--accent) 35%, var(--border));
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1.4;
    white-space: nowrap;
  }

  /* Invite non-member — prominent action */
  .v2-rv-invite-btn {
    inline-size: 100%;
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.75rem 0.875rem;
    background: var(--surface);
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-2);
    text-align: start;
    transition: border-color 0.15s var(--ease-out), background 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-invite-btn:hover:not([disabled]) {
    border-color: var(--accent);
    border-style: solid;
    color: var(--accent);
    background: color-mix(in oklch, var(--accent) 4%, var(--surface));
  }
  .v2-rv-invite-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
  .v2-rv-invite-btn .ico {
    inline-size: 36px; block-size: 36px; flex: none;
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-2);
    display: grid; place-items: center;
    transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-invite-btn:hover:not([disabled]) .ico { background: var(--accent-soft); color: var(--accent-text); }
  .v2-rv-invite-btn .ico svg { inline-size: 18px; block-size: 18px; }
  .v2-rv-invite-btn .lbl { flex: 1; min-inline-size: 0; display: flex; flex-direction: column; }
  .v2-rv-invite-btn .lbl b { font-size: 0.875rem; font-weight: 700; color: var(--text); }
  .v2-rv-invite-btn:hover:not([disabled]) .lbl b { color: var(--accent); }
  .v2-rv-invite-btn .lbl small { font-size: 0.6875rem; color: var(--text-3); margin-top: 1px; }
  .v2-rv-invite-btn .arr { inline-size: 16px; block-size: 16px; color: var(--text-3); flex: none; }
  .v2-rv-invite-btn:hover:not([disabled]) .arr { color: var(--accent); }

  /* ============================================================
   * Players list (slots)
   * ============================================================ */
  .v2-rv-players-head {
    display: flex; align-items: baseline; gap: 0.5rem;
    margin-block-end: 0.625rem;
  }
  .v2-rv-players-head .v2-rv-section-label { margin: 0; }
  .v2-rv-players { display: flex; flex-direction: column; gap: 0.5rem; }
  .v2-rv-player {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.15s var(--ease-out);
  }
  .v2-rv-player:hover { border-color: var(--border-strong); }
  .v2-rv-player.empty {
    border-style: dashed;
    background: var(--surface-2);
    color: var(--text-3);
    cursor: pointer;
    inline-size: 100%;
    text-align: start;
  }
  .v2-rv-player.empty:hover { border-color: var(--accent); color: var(--accent); }
  .v2-rv-player .info { min-inline-size: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
  .v2-rv-player .name {
    font-weight: 700; font-size: 0.875rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .v2-rv-player input.name-input {
    inline-size: 100%; max-inline-size: 220px;
    padding: 0.4rem 0.625rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    font-size: 0.8125rem;
  }
  .v2-rv-player input.name-input:focus { border-color: var(--accent); outline: none; }
  .v2-rv-badge {
    display: inline-block; align-self: start;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 0.5625rem; font-weight: 800;
    letter-spacing: 0.06em; text-transform: uppercase;
  }
  .v2-rv-badge.me      { background: var(--accent-soft); color: var(--accent-text); }
  .v2-rv-badge.guest   { background: var(--surface-3);   color: var(--text-2); }
  .v2-rv-badge.free    { background: var(--success-soft); color: light-dark(oklch(38% 0.13 155), oklch(80% 0.13 155)); }
  .v2-rv-badge.paid    { background: var(--warning-soft); color: light-dark(oklch(35% 0.13 60),  oklch(85% 0.10 75)); }
  .v2-rv-player .price { text-align: end; }
  .v2-rv-player .price b { font-family: var(--font-display); font-size: 1rem; font-weight: 700; }
  .v2-rv-player .price small { display: block; font-size: 0.6875rem; color: var(--text-3); margin-top: 1px; }
  .v2-rv-player .remove {
    inline-size: 28px; block-size: 28px; flex: none;
    border-radius: 8px;
    display: grid; place-items: center;
    color: var(--text-3);
    transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-player .remove:hover { background: var(--danger-soft); color: var(--danger); }
  .v2-rv-player .remove svg { inline-size: 14px; block-size: 14px; }

  /* ============================================================
   * Payment
   * ============================================================ */
  .v2-rv-pay-banner {
    display: flex; align-items: center; gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    background: var(--warning-soft);
    border: 1px solid color-mix(in oklch, oklch(72% 0.16 75) 25%, transparent);
    border-radius: var(--radius);
    margin-block-end: 0.75rem;
  }
  .v2-rv-pay-banner svg { inline-size: 18px; block-size: 18px; color: light-dark(oklch(35% 0.13 60),  oklch(85% 0.10 75)); flex: none; }
  .v2-rv-pay-banner .lbl {
    font-size: 0.6875rem; font-weight: 800; letter-spacing: 0.08em;
    text-transform: uppercase; color: light-dark(oklch(35% 0.13 60),  oklch(85% 0.10 75));
    flex: 1;
  }
  .v2-rv-pay-banner .amount {
    font-family: var(--font-display);
    font-size: 1.125rem; font-weight: 800;
    color: light-dark(oklch(35% 0.13 60),  oklch(85% 0.10 75));
  }

  /* Restriction errors banner (red) */
  .v2-rv-restrict-banner {
    display: flex; align-items: flex-start; gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    background: var(--danger-soft);
    border: 1px solid color-mix(in oklch, var(--danger) 30%, transparent);
    border-radius: var(--radius);
    margin-block-end: 0.625rem;
  }
  .v2-rv-restrict-banner svg { inline-size: 18px; block-size: 18px; color: var(--danger); flex: none; margin-top: 1px; }
  .v2-rv-restrict-banner .body { flex: 1; min-inline-size: 0; }
  .v2-rv-restrict-banner b {
    /* Nom du joueur INLINE avec le message d'erreur — parité legacy.
       Ex : « Coppey François : SIMSUITE-1 » sur une seule ligne. */
    font-size: 0.8125rem; font-weight: 800;
    color: var(--danger);
  }
  .v2-rv-restrict-banner ul {
    margin: 0; padding: 0; list-style: none;
    font-size: 0.75rem;
    color: var(--danger);
  }
  .v2-rv-restrict-banner li {
    padding-block: 2px;
  }
  .v2-rv-restrict-banner li::before {
    content: '· ';
    color: color-mix(in oklch, var(--danger) 60%, transparent);
  }

  /* Promo applied banner (green) */
  .v2-rv-promo-banner {
    display: flex; align-items: center; gap: 0.625rem;
    padding: 0.625rem 0.875rem;
    background: var(--success-soft);
    border: 1px solid color-mix(in oklch, var(--success) 25%, transparent);
    border-radius: var(--radius);
    margin-block-end: 0.75rem;
  }
  .v2-rv-promo-banner svg { inline-size: 16px; block-size: 16px; color: var(--success-text); flex: none; }
  .v2-rv-promo-banner .lbl {
    font-size: 0.8125rem; font-weight: 600;
    color: var(--success-text);
    flex: 1;
  }
  .v2-rv-promo-banner .lbl b { font-weight: 800; letter-spacing: 0.02em; }
  .v2-rv-promo-banner .amount {
    font-family: var(--font-display);
    font-size: 0.9375rem; font-weight: 800;
    color: var(--success-text);
  }
  .v2-rv-promo-banner .clear {
    inline-size: 24px; block-size: 24px;
    border-radius: 6px;
    display: grid; place-items: center;
    color: var(--success-text); opacity: 0.6;
    transition: opacity 0.15s var(--ease-out), background 0.15s var(--ease-out);
  }
  .v2-rv-promo-banner .clear:hover { opacity: 1; background: rgba(0,0,0,0.05); }
  .v2-rv-promo-banner .clear svg { inline-size: 14px; block-size: 14px; }

  /* Encart méthodes (single grouped box) */
  .v2-rv-methods {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-block-end: 0.875rem;
  }
  .v2-rv-methods-head {
    display: flex; align-items: center;
    padding: 0.5rem 0.875rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-3);
  }
  .v2-rv-methods-head .right {
    margin-inline-start: auto;
    text-transform: none; letter-spacing: 0;
    font-size: 0.75rem; font-weight: 600;
    color: var(--text-2);
  }
  .v2-rv-method-row {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.75rem 0.875rem;
    border-bottom: 1px solid var(--border);
  }
  .v2-rv-method-row:last-of-type { border-bottom: 0; }
  .v2-rv-method-row .ico {
    inline-size: 32px; block-size: 32px; flex: none;
    border-radius: 8px;
    background: var(--accent-soft);
    color: var(--accent-text);
    display: grid; place-items: center;
  }
  .v2-rv-method-row .ico svg { inline-size: 16px; block-size: 16px; }
  .v2-rv-method-row.added .ico { background: var(--surface-2); color: var(--text-2); }
  .v2-rv-method-row .info { flex: 1; min-inline-size: 0; }
  .v2-rv-method-row .info .title {
    font-weight: 700; font-size: 0.875rem;
    line-height: 1.25;
    /* le titre peut wrap sur 2 lignes max (« Porte-monnaie · Aebischer J-J ») */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .v2-rv-method-row .info .sub {
    font-size: 0.75rem; color: var(--text-3); margin-top: 1px;
    line-height: 1.35;
    /* Le sub est multi-lignes : on respecte les '\n' du JS pour afficher
       « Solde X CHF » puis « Min Y — Max Z CHF ». Pas d'ellipse forcée —
       on laisse le contenu s'étendre verticalement si besoin. */
    white-space: pre-line;
    overflow-wrap: anywhere;
  }
  .v2-rv-amount {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.4rem 0.625rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
  }
  .v2-rv-amount input {
    inline-size: 4rem;
    background: transparent; border: 0; text-align: end;
    font-weight: 700; font-size: 0.9375rem;
  }
  .v2-rv-amount input:focus { outline: none; }
  .v2-rv-amount .cur { font-size: 0.6875rem; font-weight: 700; color: var(--text-3); letter-spacing: 0.05em; }

  /* Variante « quota » (utilisée par la ligne « Décompte invité ») — affiche un
     nombre + label « quota(s) » au lieu d'un input CHF. Visuellement plus pill
     que cell, pour bien distinguer d'un vrai paiement. */
  .v2-rv-amount--quota {
    background: var(--success-soft);
    border-color: color-mix(in oklch, var(--success) 25%, transparent);
    color: var(--success);
  }
  .v2-rv-amount--quota .quota-num {
    font-weight: 800; font-size: 0.9375rem;
    font-family: var(--font-display, inherit);
  }
  .v2-rv-amount--quota .cur { color: var(--success); }

  .v2-rv-method-row .remove {
    inline-size: 28px; block-size: 28px; flex: none;
    border-radius: 8px;
    display: grid; place-items: center;
    color: var(--text-3);
    transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-method-row .remove:hover { background: var(--danger-soft); color: var(--danger); }
  .v2-rv-method-row .remove svg { inline-size: 14px; block-size: 14px; }

  .v2-rv-methods-foot {
    display: flex; align-items: center;
    padding: 0.625rem 0.875rem;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    font-size: 0.8125rem;
    color: var(--text-2);
  }
  .v2-rv-methods-foot .right { margin-inline-start: auto; display: inline-flex; align-items: center; gap: 0.5rem; }
  .v2-rv-methods-foot b {
    font-family: var(--font-display);
    font-weight: 800; color: var(--text);
  }
  .v2-rv-methods-foot .progress {
    inline-size: 60px; block-size: 4px;
    background: var(--surface-3);
    border-radius: 999px;
    overflow: hidden;
  }
  .v2-rv-methods-foot .progress > i {
    display: block;
    block-size: 100%;
    background: var(--accent);
    border-radius: 999px;
    transition: inline-size 0.2s var(--ease-out);
  }

  /* Add-method form (3 cols: select, contextual input, big + button) */
  .v2-rv-add-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
    gap: 0.5rem;
    align-items: stretch;
  }
  .v2-rv-input-cell {
    min-inline-size: 0;
    display: flex; flex-direction: column;
  }
  .v2-rv-input-cell > .v2-rv-input-group { inline-size: 100%; }
  .v2-rv-select, .v2-rv-input-group {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    transition: border-color 0.15s var(--ease-out);
  }
  .v2-rv-select { padding: 0.55rem 0.625rem; font-size: 0.8125rem; font-weight: 500; }
  .v2-rv-select:focus, .v2-rv-input-group:focus-within { border-color: var(--accent); outline: none; }
  .v2-rv-input-group {
    position: relative;
    display: flex; align-items: center;
    overflow: hidden;
  }
  .v2-rv-input-group input {
    flex: 1; min-inline-size: 0;
    padding: 0.55rem 0.625rem;
    border: 0; background: transparent;
    font-size: 0.8125rem;
  }
  .v2-rv-input-group input:focus { outline: none; }
  .v2-rv-input-group .suffix {
    padding: 0.55rem 0.625rem;
    background: var(--surface-2);
    border-inline-start: 1px solid var(--border);
    font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.05em;
    color: var(--text-3);
  }
  .v2-rv-input-group .prefix {
    padding: 0 0.5rem 0 0.625rem;
    color: var(--text-3);
    display: grid; place-items: center;
  }
  .v2-rv-input-group .prefix svg { inline-size: 14px; block-size: 14px; }
  .v2-rv-input-group input.promo {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
  }

  .v2-rv-add-btn {
    inline-size: 44px; block-size: 100%;
    min-block-size: 42px;
    border-radius: 10px;
    background: var(--accent);
    color: white;
    border: 1px solid color-mix(in oklch, var(--accent) 80%, black);
    display: grid; place-items: center;
    box-shadow:
      0 1px 0 0 color-mix(in oklch, var(--accent) 50%, white) inset,
      0 2px 8px color-mix(in oklch, var(--accent) 28%, transparent);
    transition: all 0.15s var(--ease-out);
  }
  .v2-rv-add-btn:hover {
    background: var(--accent-hover);
    transform: translateY(-1px);
    box-shadow:
      0 1px 0 0 color-mix(in oklch, var(--accent) 50%, white) inset,
      0 4px 12px color-mix(in oklch, var(--accent) 38%, transparent);
  }
  .v2-rv-add-btn:active { transform: translateY(0); }
  .v2-rv-add-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
  .v2-rv-add-btn svg { inline-size: 18px; block-size: 18px; }

  .v2-rv-pay-note {
    display: flex; align-items: center; gap: 0.4rem;
    margin-block-start: 0.5rem;
    font-size: 0.75rem; color: var(--text-3);
  }
  .v2-rv-pay-note svg { inline-size: 13px; block-size: 13px; }

  /* ============================================================
   * Footer (sits below scrolling body, not sticky)
   * ============================================================ */
  .v2-rv-foot {
    flex: none;
    border-top: 1px solid var(--border);
    padding: 0.75rem 1rem 0.875rem;
    background: var(--surface);
    display: flex; flex-direction: column; gap: 0.5rem;
  }
  .v2-rv-foot-meta {
    display: flex; align-items: flex-start; gap: 0.4rem;
    font-size: 0.75rem; color: var(--text-3);
    line-height: 1.4;
  }
  .v2-rv-foot-meta svg { inline-size: 13px; block-size: 13px; color: var(--success); flex: none; margin-top: 2px; }
  .v2-rv-foot-meta b { color: var(--text-2); font-weight: 700; }
  .v2-rv-foot-actions {
    display: grid;
    /* minmax(0,…) : sans ça, un bouton au contenu long (nowrap, ex. « CONFIRMER
       remboursement 30.00 CHF ») élargit sa colonne au-delà du sidebar et déborde.
       Avec minmax(0,1fr) la colonne peut rétrécir et le texte s'ellipsise. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.625rem;
  }

  .v2-rv-btn {
    padding: 1rem 1.25rem;
    border-radius: 14px;
    font-size: 0.875rem; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center; gap: 0.625rem;
    transition: all 0.18s var(--ease-out);
    letter-spacing: -0.005em;
    inline-size: 100%;
    min-block-size: 52px;
    white-space: nowrap;
  }
  .v2-rv-btn.ghost {
    background: linear-gradient(180deg,
      color-mix(in oklch, var(--danger) 5%, var(--surface)) 0%,
      color-mix(in oklch, var(--danger) 11%, var(--surface)) 100%);
    color: var(--danger);
    border: 1px solid color-mix(in oklch, var(--danger) 28%, var(--border));
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 1px 2px color-mix(in oklch, var(--danger) 10%, transparent),
      0 4px 10px color-mix(in oklch, var(--danger) 7%, transparent);
  }
  .v2-rv-btn.ghost:hover {
    background: linear-gradient(180deg,
      color-mix(in oklch, var(--danger) 12%, var(--surface)) 0%,
      color-mix(in oklch, var(--danger) 22%, var(--surface)) 100%);
    border-color: var(--danger);
    color: var(--danger);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      0 6px 16px color-mix(in oklch, var(--danger) 28%, transparent),
      0 12px 28px color-mix(in oklch, var(--danger) 14%, transparent);
  }
  .v2-rv-btn.ghost:active { transform: translateY(0); transition: transform 0.05s; }

  /* Bouton « Supprimer » (mode édition) — variante rouge solide pour signaler
     l'action destructrice. Plus appuyé que `.ghost` qui sert pour « Annuler ». */
  .v2-rv-btn.danger {
    background: linear-gradient(135deg, var(--danger), oklch(50% 0.18 25));
    color: white;
    border: 1px solid color-mix(in oklch, var(--danger) 50%, transparent);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.18),
      0 2px 6px color-mix(in oklch, var(--danger) 30%, transparent);
  }
  .v2-rv-btn.danger:hover {
    background: linear-gradient(135deg, var(--danger), oklch(45% 0.20 25));
    transform: translateY(-1px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.22),
      0 4px 12px color-mix(in oklch, var(--danger) 40%, transparent);
  }
  .v2-rv-btn.danger:active { transform: translateY(0); }
  .v2-rv-btn.danger svg { color: white; }

  .v2-rv-btn.primary {
    background: linear-gradient(135deg,
      oklch(64% 0.20 245) 0%,
      oklch(55% 0.22 268) 50%,
      oklch(50% 0.22 285) 100%);
    color: white;
    border: 1px solid color-mix(in oklch, oklch(55% 0.22 268) 70%, black);
    box-shadow:
      inset 0 1px 0 0 rgba(255, 255, 255, 0.35),
      inset 0 -1px 0 0 rgba(0, 0, 0, 0.10),
      0 4px 14px color-mix(in oklch, oklch(58% 0.22 270) 38%, transparent),
      0 8px 24px color-mix(in oklch, oklch(58% 0.22 270) 18%, transparent);
  }
  .v2-rv-btn.primary:hover {
    background: linear-gradient(135deg,
      oklch(68% 0.20 245) 0%,
      oklch(58% 0.22 268) 50%,
      oklch(53% 0.22 285) 100%);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 0 rgba(255, 255, 255, 0.45),
      inset 0 -1px 0 0 rgba(0, 0, 0, 0.12),
      0 10px 28px color-mix(in oklch, oklch(58% 0.22 270) 48%, transparent),
      0 16px 40px color-mix(in oklch, oklch(58% 0.22 270) 24%, transparent);
  }
  .v2-rv-btn.primary:active { transform: translateY(0); transition: transform 0.05s; }
  /* Disabled state — muted + dashed border = clear "can't click yet" cue.
     pointer-events:none guarantees the click can never reach submitReservation. */
  .v2-rv-btn.primary[disabled],
  .v2-rv-btn.primary.is-disabled {
    background: light-dark(oklch(96% 0.015 90), oklch(24% 0.025 85));
    color: light-dark(oklch(55% 0.06 75), oklch(70% 0.05 90));
    border: 1.5px dashed light-dark(oklch(72% 0.06 85), oklch(50% 0.05 85));
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
    opacity: 0.92;
    pointer-events: none;
  }
  .v2-rv-btn.primary[disabled]:hover,
  .v2-rv-btn.primary.is-disabled:hover {
    transform: none;
    box-shadow: none;
  }
  .v2-rv-btn.primary[disabled] svg,
  .v2-rv-btn.primary.is-disabled svg {
    opacity: 0.7;
  }
  .v2-rv-btn svg { inline-size: 16px; block-size: 16px; flex: none; }

  /* Two-line stack inside a button (e.g. "Reste à payer / 80.00 CHF") */
  .v2-rv-btn-stack {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 1px;
    line-height: 1.1;
    /* le bouton CTA est étroit — on autorise la troncature plutôt qu'un débordement
       horizontal hors du bouton (cas « Montant invalide / nom partner trop long »). */
    min-inline-size: 0;
    flex: 1 1 0;
  }
  .v2-rv-btn-stack .lbl,
  .v2-rv-btn-stack .val {
    max-inline-size: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .v2-rv-btn-stack .lbl {
    font-size: 0.625rem; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase;
    opacity: 0.78;
  }
  .v2-rv-btn-stack .val {
    font-family: var(--font-display);
    font-size: 0.875rem; font-weight: 800;
    letter-spacing: -0.015em;
  }

  /* ============================================================
   * Responsive
   * ============================================================ */
  @media (max-width: 480px) {
    /* On garde le formulaire d'ajout de paiement sur UNE seule ligne (select |
       montant | +) même en étroit — on resserre juste le gap/padding et on
       laisse le <select> tronquer son texte au besoin. */
    .v2-rv-add-form { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 0.375rem; }
    .v2-rv-add-form > .v2-rv-select { padding-inline: 0.4rem; font-size: 0.75rem; }
    .v2-rv-cards.cols-4 { grid-template-columns: repeat(4, 1fr); gap: 0.4rem; }
    .v2-rv-card { padding: 0.625rem 0.4rem; }
    .v2-rv-card .num { font-size: 1.375rem; }
  }

  /* Hide elements via .hidden utility */
  .v2-rv [hidden],
  .v2-rv .v2-rv-hidden { display: none !important; }

  /* ============================================================
   * Modal « Horaire optimisé » (heureCoulee) — parité legacy `swal()`.
   * Affiché quand le backend décale l'heure cliquée pour optimiser
   * le calendrier. Centré au milieu du viewport au-dessus du sidebar.
   * ============================================================ */
  .v2-rv-modal-overlay {
    position: fixed;
    inset: 0;
    background: var(--v2-modal-backdrop);
    -webkit-backdrop-filter: var(--v2-modal-backdrop-blur);
    backdrop-filter: var(--v2-modal-backdrop-blur);
    display: grid;
    place-items: center;
    z-index: 100000;
    padding: 1rem;
    animation: v2-modal-fade 0.16s ease-out;
  }
  .v2-rv-modal {
    background: var(--v2-glass-bg);
    -webkit-backdrop-filter: var(--v2-glass-blur);
    backdrop-filter: var(--v2-glass-blur);
    color: var(--text);
    inline-size: min(440px, 100%);
    border: var(--v2-glass-border);
    border-radius: var(--v2-glass-radius);
    padding: 1.5rem 1.5rem 1.25rem;
    box-shadow: var(--v2-glass-shadow);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    text-align: center;
    animation: v2-modal-pop 0.22s var(--ease-out);
  }
  .v2-rv-modal-icon {
    inline-size: 56px;
    block-size: 56px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    /* défaut = warning (ambre) */
    background: light-dark(oklch(96% 0.05 80), oklch(28% 0.08 80));
    color: light-dark(oklch(48% 0.16 70), oklch(82% 0.14 80));
  }
  .v2-rv-modal-icon svg { inline-size: 28px; block-size: 28px; }

  /* Variantes : info (bleu) / warning (ambre) / error (rouge) */
  .v2-rv-modal--info .v2-rv-modal-icon {
    background: light-dark(oklch(95% 0.045 250), oklch(28% 0.08 250));
    color: light-dark(oklch(50% 0.16 252), oklch(82% 0.14 252));
  }
  .v2-rv-modal--warning .v2-rv-modal-icon {
    background: light-dark(oklch(96% 0.05 80), oklch(28% 0.08 80));
    color: light-dark(oklch(48% 0.16 70), oklch(82% 0.14 80));
  }
  .v2-rv-modal--error .v2-rv-modal-icon {
    background: light-dark(oklch(94% 0.045 25), oklch(26% 0.08 25));
    color: light-dark(oklch(48% 0.18 25), oklch(80% 0.14 25));
  }
  .v2-rv-modal-body h3 {
    font-size: 1.0625rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin-block-end: 0.25rem;
  }
  .v2-rv-modal-body p {
    font-size: 0.8125rem;
    color: var(--text-2);
    line-height: 1.5;
    margin: 0.25rem 0;
  }
  .v2-rv-modal-hour {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    margin-block-start: 0.875rem !important;
    padding: 0.5rem 1rem;
    background: light-dark(oklch(96% 0.015 250), oklch(26% 0.04 250));
    border-radius: 10px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.125rem;
    letter-spacing: -0.01em;
  }
  .v2-rv-modal-hour-old {
    color: var(--text-3);
    text-decoration: line-through;
    text-decoration-color: light-dark(oklch(70% 0.04 60), oklch(60% 0.06 60));
  }
  .v2-rv-modal-hour-new { color: var(--accent, oklch(55% 0.18 252)); }
  .v2-rv-modal-hour .arrow {
    inline-size: 18px;
    block-size: 18px;
    color: var(--text-3);
  }
  .v2-rv-modal-ok {
    margin-block-start: 0.75rem;
    min-inline-size: 8rem;
  }
  /* Animations partagées (v2-modal-fade / v2-modal-pop) définies dans dashboard.css. */

  /* ============================================================
   * Busy state — disable interaction while async ops are in flight
   * (state.busy > 0 in JS toggles .is-busy on root)
   * ============================================================ */
  .v2-rv.is-busy {
    cursor: wait;
  }
  .v2-rv.is-busy .v2-rv-btn,
  .v2-rv.is-busy .v2-rv-chip,
  .v2-rv.is-busy .v2-rv-card,
  .v2-rv.is-busy .v2-rv-add-btn,
  .v2-rv.is-busy .v2-rv-qty button,
  .v2-rv.is-busy .v2-rv-add-article,
  .v2-rv.is-busy .v2-rv-suggestion,
  .v2-rv.is-busy .v2-rv-cta-match,
  .v2-rv.is-busy .v2-rv-player .remove,
  .v2-rv.is-busy .v2-rv-method-row .remove,
  .v2-rv.is-busy .v2-rv-select,
  .v2-rv.is-busy .v2-rv-input,
  .v2-rv.is-busy [data-rv="add-method-type"],
  .v2-rv.is-busy [data-rv="submit"],
  .v2-rv.is-busy [data-rv="invite-btn"],
  .v2-rv.is-busy [data-rv="match-btn"],
  .v2-rv.is-busy [data-rv="add-method-btn"],
  .v2-rv.is-busy [data-rv="add-article-btn"],
  .v2-rv.is-busy [data-rv="promo-clear"],
  .v2-rv.is-busy [data-rv-fav],
  .v2-rv.is-busy [data-rv-search-id],
  .v2-rv.is-busy [data-rv-qty],
  .v2-rv.is-busy [data-rv-remove-player],
  .v2-rv.is-busy [data-rv-remove-method] {
    pointer-events: none !important;
    opacity: 0.55;
    cursor: wait !important;
  }
  .v2-rv.is-busy [data-rv="close"],
  .v2-rv.is-busy [data-rv="cancel"] {
    pointer-events: auto !important;
    opacity: 1;
    cursor: pointer !important;
  }
  /* Tiny pulsing dot near the footer to hint "working…" */
  .v2-rv.is-busy .v2-rv-footer::before {
    content: "";
    position: absolute;
    inset-block-start: 8px;
    inset-inline-end: 12px;
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--rv-accent, oklch(70% 0.18 250));
    box-shadow: 0 0 0 0 currentColor;
    animation: v2RvBusyPulse 1.1s ease-in-out infinite;
    pointer-events: none;
  }
  .v2-rv-footer { position: relative; }
  @keyframes v2RvBusyPulse {
    0%   { transform: scale(0.9); opacity: 0.6; }
    50%  { transform: scale(1.25); opacity: 1; }
    100% { transform: scale(0.9); opacity: 0.6; }
  }

  /* ============================================================
   * Modal de paiement carte (Stripe Embedded Checkout / SaferPay)
   * — overlay plein écran qui héberge un mount point Stripe ou une
   *   iframe SaferPay. Z-index > v2-rv-modal-overlay pour passer
   *   au-dessus des modales d'info classiques.
   * ============================================================ */
  .v2-rv-payment-modal-overlay {
    position: fixed;
    inset: 0;
    background: var(--v2-modal-backdrop);
    -webkit-backdrop-filter: var(--v2-modal-backdrop-blur);
    backdrop-filter: var(--v2-modal-backdrop-blur);
    display: grid;
    place-items: center;
    z-index: 100010;
    padding: 1rem;
    animation: v2-modal-fade 0.16s ease-out;
  }
  .v2-rv-payment-modal-overlay[hidden] { display: none; }
  /* Le modal est déplacé sous <body> (hors scope .v2-rv) → on rétablit
     box-sizing pour tout le sous-arbre afin que padding/largeurs restent
     cohérents. */
  .v2-rv-payment-modal-overlay,
  .v2-rv-payment-modal-overlay * { box-sizing: border-box; }
  /* Promu en top-layer via l'API Popover : neutralise les styles UA du popover
     (width/height fit-content, margin:auto, border, padding) pour conserver
     l'overlay plein écran centré. */
  .v2-rv-payment-modal-overlay:popover-open {
    inline-size: 100%;
    block-size: 100%;
    max-inline-size: none;
    max-block-size: none;
    margin: 0;
    border: 0;
    /* AUCUN scroll ici. Le modal est déjà borné à la hauteur du viewport ; si
       l'overlay pouvait défiler, on obtenait une 2e barre au-dessus de celle du
       document de paiement. Une seule barre doit exister : celle DANS la frame. */
    overflow: hidden;
  }
  .v2-rv-payment-modal-overlay::backdrop { background: transparent; }
  .v2-rv-payment-modal {
    background: var(--v2-glass-bg);
    -webkit-backdrop-filter: var(--v2-glass-blur);
    backdrop-filter: var(--v2-glass-blur);
    color: var(--text);
    inline-size: min(720px, 100%);
    max-block-size: min(900px, calc(100dvh - 2rem));
    border: var(--v2-glass-border);
    border-radius: var(--v2-glass-radius);
    box-shadow: var(--v2-glass-shadow);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: v2-modal-pop 0.22s var(--ease-out);
  }
  /* Quand la frame de paiement est affichée, le modal occupe toute la hauteur
     disponible : le document du prestataire dispose ainsi du maximum de place
     et reste le SEUL à défiler. Stripe, dont le formulaire est monté en direct
     et souvent court, conserve une hauteur automatique — pas de grand vide. */
  .v2-rv-payment-modal:has(.v2-rv-payment-saferpay-frame:not([hidden])) {
    block-size: min(900px, calc(100dvh - 2rem));
  }
  .v2-rv-payment-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.875rem 1.25rem;
    border-block-end: 1px solid var(--border);
  }
  .v2-rv-payment-modal-header h3 {
    font-size: 0.9375rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin: 0;
  }
  .v2-rv-payment-modal-close {
    inline-size: 32px;
    block-size: 32px;
    border-radius: 8px;
    border: none;
    background: transparent;
    color: var(--text-2);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background 0.12s;
  }
  .v2-rv-payment-modal-close:hover {
    background: light-dark(oklch(94% 0.012 250), oklch(28% 0.02 250));
    color: var(--text);
  }
  .v2-rv-payment-modal-close svg { inline-size: 16px; block-size: 16px; }
  .v2-rv-payment-modal-body {
    /* `min-block-size: 0` est indispensable : sans lui un enfant flex refuse de
       se comprimer sous sa taille de contenu, le corps depasse le modal et sa
       propre barre de defilement apparait. */
    flex: 1 1 auto;
    min-block-size: 0;
    overflow: auto;
    position: relative;
    background: light-dark(oklch(98% 0.005 250), oklch(15% 0.015 250));
  }
  .v2-rv-payment-modal-loader {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    color: var(--text-2);
    font-size: 0.875rem;
    z-index: 1;
  }
  .v2-rv-payment-modal-loader[hidden] { display: none; }
  .v2-rv-payment-modal-loader .spinner {
    inline-size: 38px;
    block-size: 38px;
    border-radius: 50%;
    border: 3px solid light-dark(oklch(90% 0.012 250), oklch(30% 0.02 250));
    border-block-start-color: var(--accent, oklch(55% 0.18 252));
    animation: v2RvPaySpin 0.9s linear infinite;
  }
  @keyframes v2RvPaySpin {
    to { transform: rotate(360deg); }
  }
  .v2-rv-payment-stripe-mount {
    padding: 1rem;
    min-block-size: 420px;
  }
  .v2-rv-payment-stripe-mount[hidden] { display: none; }
  .v2-rv-payment-saferpay-frame {
    inline-size: 100%;
    border: 0;
    /* L'iframe epouse EXACTEMENT la hauteur du corps, au lieu d'une valeur fixe
       calquee sur le viewport. Une hauteur en dur supposait la taille de
       l'en-tete : des qu'elle differait, le corps debordait et une 2e barre
       reapparaissait. Ici le corps ne peut plus deborder, et seul le document
       de paiement defile — en-tete du modal toujours visible. */
    block-size: 100%;
    display: block;
  }
  .v2-rv-payment-saferpay-frame[hidden] { display: none; }

  /* DEV ONLY — bouton de simulation de paiement (gabarit PHP gated). Sticky en
     haut du body pour rester visible au-dessus de l'iframe SaferPay. */
  .v2-rv-payment-simulate {
    position: sticky;
    inset-block-start: 0;
    z-index: 2;
    display: block;
    inline-size: 100%;
    padding: 0.6rem 1rem;
    border: 0;
    border-block-end: 1px dashed light-dark(oklch(80% 0.05 90), oklch(45% 0.06 90));
    background: light-dark(oklch(95% 0.06 90), oklch(28% 0.06 90));
    color: light-dark(oklch(40% 0.12 60), oklch(90% 0.08 90));
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
  }
  .v2-rv-payment-simulate:hover {
    background: light-dark(oklch(92% 0.08 90), oklch(33% 0.07 90));
  }
  .v2-rv-payment-simulate[hidden] { display: none; }

  /* ============================================================
   * Méthode de paiement « payée en ligne » (locked)
   * — row non éditable, montant figé, pas de bouton remove, badge
   *   visuel pour indiquer que le paiement est déjà capté.
   * ============================================================ */
  .v2-rv-method-row.locked {
    background: light-dark(oklch(98% 0.02 145), oklch(22% 0.03 145));
    border: 1px solid light-dark(oklch(85% 0.06 145), oklch(35% 0.06 145));
  }
  .v2-rv-method-row.locked .v2-rv-amount input {
    background: light-dark(oklch(95% 0.012 250), oklch(26% 0.02 250));
    color: var(--text);
    cursor: not-allowed;
    pointer-events: none;
    opacity: 0.92;
  }
  .v2-rv-method-row.locked .paid-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-inline-start: 0.5rem;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background: light-dark(oklch(88% 0.10 145), oklch(35% 0.10 145));
    color: light-dark(oklch(35% 0.16 145), oklch(85% 0.12 145));
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    text-transform: uppercase;
  }
  .v2-rv-method-row.locked .paid-badge svg {
    inline-size: 11px;
    block-size: 11px;
  }

  /* =====================================================================
   * RECURRENCE FORM (v2-rv-rec) — used by app/Views/v2/specialReservation.php
   *
   * Modern design that reuses the v2-rv shell (380px, header w/ court colors,
   * scrolling body, footer with primary/ghost buttons) and adds dedicated
   * controls for the recurrence-specific fields:
   *   - select (type de récurrence)
   *   - color swatch + readonly couleur input
   *   - text input (étiquette)
   *   - chip group (terrains)
   *   - chip group with day-of-week pills
   *   - date range (native date inputs)
   *   - time range (selects)
   *   - oui/non toggle for jours spéciaux
   * ===================================================================== */

  /* Form wrapper takes full height of the shell so footer sticks to bottom */
  .v2-rv-rec form { display: contents; }

  /* Generic input baseline (used by .v2-rv-input across the rec form) */
  .v2-rv-input {
    inline-size: 100%;
    padding: 0.6rem 0.75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text);
    transition: border-color 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
  }
  .v2-rv-input::placeholder { color: var(--text-3); }
  .v2-rv-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 20%, transparent);
  }
  .v2-rv-input[readonly] { background: var(--surface-2); cursor: default; }

  /* ─── Select wrapper with custom chevron ────────────────────────── */
  .v2-rv-rec-select-wrap {
    position: relative;
    inline-size: 100%;
  }
  .v2-rv-rec-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    inline-size: 100%;
    padding: 0.65rem 2.25rem 0.65rem 0.875rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    transition: border-color 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
  }
  .v2-rv-rec-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 20%, transparent);
  }
  .v2-rv-rec-select-chev {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 0.75rem;
    transform: translateY(-50%);
    inline-size: 16px; block-size: 16px;
    color: var(--text-3);
    pointer-events: none;
  }

  /* ─── 2-col grid (Couleur + Étiquette) ─────────────────────────── */
  .v2-rv-rec-grid {
    display: grid;
    grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
  }
  @media (max-width: 380px) {
    .v2-rv-rec-grid { grid-template-columns: 1fr; }
  }

  /* ─── Color swatch + readonly input ─────────────────────────────── */
  .v2-rv-rec-color {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
  }
  .v2-rv-rec-color-swatch {
    flex: none;
    inline-size: 38px; block-size: 38px;
    border-radius: 10px;
    background:
      repeating-conic-gradient(var(--surface-3) 0% 25%, var(--surface-2) 25% 50%) 50% / 12px 12px;
    border: 1px solid var(--border);
    box-shadow: inset 0 0 0 2px var(--surface);
    transition: background 0.2s var(--ease-out), border-color 0.15s var(--ease-out);
  }
  .v2-rv-rec-color-swatch.has-color {
    box-shadow: inset 0 0 0 2px var(--surface), 0 0 0 1px rgba(0,0,0,0.08);
    border-color: color-mix(in oklch, currentColor 30%, var(--border));
  }
  .v2-rv-rec-color-input {
    flex: 1;
    min-inline-size: 0;
    font-family: 'SF Mono', 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
  }

  /* ─── Chip group (terrains + jours + jours spéciaux) ───────────── */
  .v2-rv-rec-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
  }
  .v2-rv-rec-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.85rem;
    background: var(--surface);
    border: 1.5px solid var(--border);
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-2);
    cursor: pointer;
    user-select: none;
    transition: all 0.15s var(--ease-out);
  }
  .v2-rv-rec-chip input[type="checkbox"] {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
  }
  .v2-rv-rec-chip:hover {
    border-color: color-mix(in oklch, var(--accent) 50%, var(--border));
    color: var(--text);
    transform: translateY(-1px);
  }
  .v2-rv-rec-chip.is-active {
    background: linear-gradient(135deg,
      oklch(64% 0.20 245) 0%,
      oklch(55% 0.22 268) 50%,
      oklch(50% 0.22 285) 100%);
    border-color: color-mix(in oklch, var(--accent) 75%, black);
    color: white;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.30),
      0 2px 8px color-mix(in oklch, oklch(58% 0.22 270) 30%, transparent);
  }
  .v2-rv-rec-chip.is-active:hover {
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.35),
      0 6px 16px color-mix(in oklch, oklch(58% 0.22 270) 45%, transparent);
  }
  .v2-rv-rec-chip.is-disabled {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: none;
  }

  /* Day chip variant — uniform width so Lun/Mar/Mer/Jeu line up */
  .v2-rv-rec-chips--days {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.35rem;
  }
  .v2-rv-rec-chip--day {
    padding: 0.5rem 0.25rem;
    justify-content: center;
    border-radius: 10px;
    text-transform: uppercase;
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
  }

  /* ─── Date / hour range (start → end) ──────────────────────────── */
  .v2-rv-rec-range {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 0.5rem;
    align-items: center;
  }
  .v2-rv-rec-range-sep {
    color: var(--text-3);
    font-weight: 700;
    font-size: 0.875rem;
    user-select: none;
  }
  .v2-rv-rec-date {
    font-variant-numeric: tabular-nums;
    font-size: 0.875rem;
  }
  /* Native date picker styling tweaks (WebKit) */
  .v2-rv-rec-date::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.15s var(--ease-out);
  }
  .v2-rv-rec-date::-webkit-calendar-picker-indicator:hover { opacity: 1; }
  .v2-rv-rec-range .v2-rv-rec-select-wrap { min-inline-size: 0; }

  /* ─── Oui / Non toggle (jours spéciaux) ────────────────────────── */
  .v2-rv-rec-toggle {
    display: inline-flex;
    padding: 3px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
  }
  .v2-rv-rec-toggle-btn {
    padding: 0.4rem 1rem;
    background: transparent;
    border: 0;
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--text-2);
    cursor: pointer;
    transition: all 0.15s var(--ease-out);
  }
  .v2-rv-rec-toggle-btn.is-active {
    background: var(--surface);
    color: var(--accent-text);
    box-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 0 rgba(255,255,255,0.06) inset;
  }

  /* ─── Recap (used when monnaieNumerique active) ────────────────── */
  .v2-rv-rec-summary {
    padding: 0.75rem 0.875rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
  }
  .v2-rv-rec-summary-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: 0.8125rem;
    color: var(--text-2);
  }
  .v2-rv-rec-summary-row .lbl { font-weight: 500; }
  .v2-rv-rec-summary-row b {
    font-family: var(--font-display);
    font-weight: 800;
    color: var(--text);
    font-size: 0.9375rem;
  }

  /* ─── Disabled chip state — input:disabled ─────────────────────── */
  .v2-rv-rec-chip:has(input:disabled) {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: none;
  }

  /* ============================================================
   * UPDATE / DELETE RECURRENCE — used by v2/updateSpecialReservation.php
   * ============================================================ */

  /* Détails de la récurrence (dl-based summary card) */
  .v2-rv-rec-details {
    margin: 0;
    padding: 0.875rem 1rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .v2-rv-rec-details .v2-rv-rec-summary-row {
    display: grid;
    grid-template-columns: minmax(0, 7.5rem) minmax(0, 1fr);
    gap: 0.5rem;
    align-items: baseline;
    font-size: 0.8125rem;
    margin: 0;
  }
  .v2-rv-rec-details dt {
    color: var(--text-3);
    font-weight: 600;
    text-transform: none;
    margin: 0;
  }
  .v2-rv-rec-details dd {
    margin: 0;
    color: var(--text);
    font-weight: 500;
    word-break: break-word;
  }
  .v2-rv-rec-details dd b {
    font-family: var(--font-display);
    font-weight: 800;
  }

  /* Code porte — gros chiffres tabulaires, fond mis en évidence */
  .v2-rv-rec-code-portier {
    display: inline-block;
    padding: 0.625rem 1rem;
    background: linear-gradient(180deg,
      color-mix(in oklch, var(--accent) 5%, var(--surface)) 0%,
      color-mix(in oklch, var(--accent) 12%, var(--surface-2)) 100%);
    border: 1.5px solid color-mix(in oklch, var(--accent) 30%, var(--border));
    border-radius: 12px;
    font-family: 'SF Mono', 'JetBrains Mono', ui-monospace, monospace;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: 0.18em;
    color: var(--text);
    text-align: center;
  }

  /* Inline info pour 1 seul valeur de nombre (parité avec v2-rv-inline-info
     déjà existant — on précise juste le contexte rec) */
  .v2-rv-rec--edit .v2-rv-inline-info .val {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 800;
    color: var(--text);
    margin-inline-start: auto;
  }

  /* ============================================================
   * V2 sidebarpop (non-connecté) — TABS + panes + form
   * Tabs : vraie barre d'onglets en haut du body, look proéminent
   * (gros boutons + indicateur de sélection clair) pour qu'on
   * comprenne d'un coup d'œil que c'est cliquable et qu'il y a
   * 2 modes mutuellement exclusifs. Ordre conditionné par KIOSK.
   * ============================================================ */
  .v2-rv .v2-rv-tabs {
    position: relative;
    display: grid !important;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    margin: 0;
    padding: 0;
    min-block-size: 52px;
    border-radius: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    overflow: hidden;
    isolation: isolate;
  }
  .v2-rv .v2-rv-tab {
    position: relative;
    z-index: 1;
    display: flex !important;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    inline-size: 100%;
    min-block-size: 50px;
    padding: 0.75rem 0.75rem;
    background: transparent;
    color: var(--text-3);
    font-family: var(--font-display);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    border: 0;
    border-radius: 0;
    transition: color .18s var(--ease-out), background .18s var(--ease-out);
    cursor: pointer;
  }
  .v2-rv .v2-rv-tab + .v2-rv-tab { border-inline-start: 1px solid var(--border); }
  .v2-rv .v2-rv-tab:hover {
    color: var(--text-2);
    background: light-dark(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.04));
  }
  .v2-rv .v2-rv-tab-icon {
    display: inline-grid; place-items: center;
    inline-size: 18px; block-size: 18px;
    flex: none;
    color: currentColor;
  }
  .v2-rv .v2-rv-tab-icon svg { inline-size: 16px; block-size: 16px; display: block; }
  .v2-rv .v2-rv-tab-label { white-space: nowrap; display: inline-block; }

  .v2-rv .v2-rv-tab.is-active {
    color: var(--text);
    background: var(--surface);
    box-shadow: inset 0 -3px 0 0 var(--accent);
  }
  .v2-rv .v2-rv-tab.is-active .v2-rv-tab-icon { color: var(--accent); }

  .v2-rv-tab-indicator { display: none; }

  .v2-rv-pane { display: none; flex-direction: column; gap: 1rem; }
  .v2-rv-pane.is-active { display: flex; }

  /* Champ texte « legacy form-group » habillé v2-rv */
  .v2-rv .v2-rv-pop-field { display: flex; flex-direction: column; gap: 0.35rem; }
  .v2-rv .v2-rv-pop-field > label {
    font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.02em;
    color: var(--text-3); text-transform: uppercase;
    display: inline-flex; align-items: center; gap: 0.5rem;
  }
  .v2-rv .v2-rv-pop-field > label .forgot {
    margin-inline-start: auto;
    font-size: 0.6875rem; font-weight: 600;
    color: var(--accent);
    text-decoration: none; text-transform: none; letter-spacing: 0;
  }
  .v2-rv .v2-rv-pop-field > label .forgot:hover { text-decoration: underline; }
  .v2-rv .v2-rv-pop-field .v2-rv-input-group input {
    inline-size: 100%;
    padding: 0.55rem 0.625rem;
    background: transparent;
    border: 0;
    font-size: 0.875rem;
    color: var(--text);
  }
  .v2-rv .v2-rv-pop-field.error .v2-rv-input-group {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--danger) 18%, transparent);
  }
  .v2-rv .v2-rv-pop-field .invalid_text {
    display: none;
    color: var(--danger);
    font-size: 0.75rem;
    font-weight: 500;
  }
  .v2-rv .v2-rv-pop-field.error .invalid_text { display: block; }

  /* Show / Hide password icons */
  .v2-rv .show-password, .v2-rv .hide-password {
    display: inline-flex; align-items: center; padding-inline-end: 0.5rem;
    color: var(--text-3);
  }

  /* Checkbox row (remember me, biometric opt-in, conditions générales) */
  .v2-rv .v2-rv-pop-checkrow .form-check.inline,
  .v2-rv .v2-rv-pop-check .form-check.inline {
    display: inline-flex; align-items: center; gap: 0.5rem;
  }
  .v2-rv .v2-rv-pop-checkrow input[type="checkbox"],
  .v2-rv .v2-rv-pop-check input[type="checkbox"] {
    inline-size: 16px; block-size: 16px; accent-color: var(--accent);
  }
  .v2-rv .v2-rv-pop-checkrow label,
  .v2-rv .v2-rv-pop-check label {
    font-size: 0.8125rem; color: var(--text-2); margin: 0;
  }
  .v2-rv .v2-rv-pop-check a { color: var(--accent); text-decoration: underline; }

  /* Group "buttons-group" : actions de paiement empilées */
  .v2-rv .buttons-group.v2-rv-pop-pay {
    display: flex; flex-direction: column; gap: 0.5rem;
    margin-block-start: 0.25rem;
  }
  .v2-rv .buttons-group.v2-rv-pop-pay .v2-rv-btn { inline-size: 100%; }

  /* Total */
  .v2-rv .v2-rv-pop-total {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.75rem 0.875rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    font-size: 0.875rem;
  }
  .v2-rv .v2-rv-pop-total .lbl { font-weight: 600; color: var(--text-2); }
  .v2-rv .v2-rv-pop-total .amount {
    font-family: var(--font-display);
    font-size: 1.0625rem; font-weight: 800; color: var(--text);
  }

  /* Code promo input + bouton ✓ — habille le bouton "valider" dans la
     .auth-field__control (déjà bordée). On le colle à droite. */
  .v2-rv .v2-rv-pop-code .v2-rv-pop-code-btn,
  .v2-rv .v2-rv-pop-code button.bouton {
    flex: none;
    display: inline-grid; place-items: center;
    inline-size: 2.25rem; block-size: 2rem;
    margin-inline-end: 0.25rem;
    padding: 0;
    background: var(--accent);
    color: white;
    font-weight: 700;
    border-radius: 8px;
    box-shadow: 0 2px 6px color-mix(in oklch, var(--accent) 35%, transparent);
    transition: background .15s, transform .12s;
  }
  .v2-rv .v2-rv-pop-code .v2-rv-pop-code-btn svg,
  .v2-rv .v2-rv-pop-code button.bouton svg { inline-size: 14px; block-size: 14px; }
  .v2-rv .v2-rv-pop-code .v2-rv-pop-code-btn:hover,
  .v2-rv .v2-rv-pop-code button.bouton:hover { background: var(--accent-hover); transform: translateY(-1px); }
  .v2-rv .v2-rv-pop-code button.bouton[disabled],
  .v2-rv .v2-rv-pop-code button.bouton.ui-state-disabled {
    opacity: .45; cursor: not-allowed; transform: none;
  }

  /* Articles réservables : table simple + ligne de saisie */
  .v2-rv-pop-articles .v2-rv-pop-article-form {
    inline-size: 100%; border-collapse: collapse; margin-block: 0.5rem;
  }
  .v2-rv-pop-articles .v2-rv-pop-article-form td {
    padding: 0.25rem; vertical-align: middle;
  }
  .v2-rv-pop-articles .v2-rv-pop-article-form td:first-child { inline-size: 100%; }
  .v2-rv-pop-articles .v2-rv-pop-qty {
    inline-size: 48px; padding: 0.45rem 0.4rem;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--surface); color: var(--text);
    text-align: center;
  }
  .v2-rv-pop-articles .v2-rv-pop-article-price {
    font-size: 0.75rem; font-weight: 700; color: var(--text-2);
    white-space: nowrap;
  }
  .v2-rv-pop-articles .v2-rv-pop-article-list {
    inline-size: 100%;
  }
  .v2-rv-pop-articles .v2-rv-pop-article-list thead { display: none; }
  .v2-rv-pop-articles .v2-rv-pop-article-list td {
    padding: 0.25rem 0.4rem; font-size: 0.8125rem;
  }

  /* Card radio inputs : on cache l'input et clique sur le label coloré */
  .v2-rv-cards label.v2-rv-card { cursor: pointer; }

  /* Bouton biométrique dans le sidebar — réutilise `.auth-biometric__btn` de
     loginV2. Mais la règle générique `.v2-rv button { border:0; color:inherit }`
     gagne par spécificité (1 classe + 1 élément vs 1 classe seule) et lui
     enlève sa bordure. On restaure ici avec un sélecteur plus spécifique
     pour avoir le même rendu qu'en loginV2 (bordure grise + texte foncé). */
  /* Restaure TOUTES les propriétés de `.auth-biometric__btn` que la règle
     générique `.v2-rv button { font: inherit; border: 0; color: inherit }`
     écrase par spécificité. Sans ces overrides, on perd :
       • le border (= bordure grise)
       • le font-weight: 600 (= texte gras)
       • le font-family display
       • la color (= texte foncé)
     d'où l'apparence "fade" du bouton dans le sidebar vs loginV2. */
  .v2-rv button.auth-biometric__btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0.625rem;
    inline-size: 100%;
    padding: 0.75rem 1rem;
    border-radius: 0.75rem;
    background: var(--surface-2);
    color: var(--text);
    border: 1px solid var(--border);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.875rem;
    transition: background 0.15s, border-color 0.15s, transform 0.12s, box-shadow 0.18s;
  }
  .v2-rv button.auth-biometric__btn:hover {
    background: var(--surface-3);
    border-color: var(--accent);
    color: var(--accent-text);
    transform: translateY(-1px);
    box-shadow: 0 4px 14px color-mix(in oklch, var(--accent) 18%, transparent);
  }
  .v2-rv .auth-biometric__icon {
    inline-size: 1.875rem; block-size: 1.875rem;
    border-radius: 999px;
    background: color-mix(in oklch, var(--accent) 14%, transparent);
    color: var(--accent);
    display: grid; place-items: center;
    flex: none;
  }

  /* Bouton « Se connecter » dans le sidebar — réutilise `.me-login-btn` du
     menu gauche. Mais la règle générique `.v2-rv button { color: inherit; }`
     l'emporte par spécificité, d'où texte noir au lieu de blanc. On force
     la couleur ici avec un sélecteur plus spécifique. */
  .v2-rv .v2-rv-pop-login-btn,
  .v2-rv button.me-login-btn {
    color: #fff;
    background: var(--accent);
    inline-size: 100%;
    padding: 0.875rem 1rem;
    border-radius: 12px;
    font-weight: 700;
    font-size: 0.9375rem;
    box-shadow: 0 4px 14px color-mix(in oklch, var(--accent) 35%, transparent);
    transition: background .15s, transform .12s, box-shadow .18s;
  }
  .v2-rv .v2-rv-pop-login-btn:hover,
  .v2-rv button.me-login-btn:hover {
    background: var(--accent-hover, oklch(55% 0.18 240));
    transform: translateY(-1px);
    box-shadow: 0 6px 18px color-mix(in oklch, var(--accent) 40%, transparent);
  }
  .v2-rv .v2-rv-pop-login-btn:active,
  .v2-rv button.me-login-btn:active { transform: translateY(0); }
  .v2-rv .v2-rv-pop-login-btn svg,
  .v2-rv button.me-login-btn svg { color: #fff; }

  /* Form CC : on impose un flex column avec gap pour aérer les sections
     internes (joueurs / durée / articles / coordonnées / total / paiement). */
  .v2-rv-pane[data-rv-pane="cc"] > form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  /* Login pane — wrappe la totalité des champs identiquement à `.auth-form` */
  .v2-rv .v2-rv-pop-login {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
  .v2-rv .v2-rv-pop-login-inner {
    display: flex;
    flex-direction: column;
    gap: 1.125rem;
  }

  /* Pop-fields : conteneur du bloc « Tes coordonnées » — flex column avec gap */
  .v2-rv .v2-rv-pop-fields {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
  }

  /* Auth banners / context — réutilisés depuis loginV2 sans modification.
     On corrige juste leur taille relative dans le contexte étroit du sidebar. */
  .v2-rv .auth-context { margin: 0; padding: 0.625rem 0.75rem; gap: 0.625rem; }
  .v2-rv .auth-context__title { font-size: 0.8125rem; }

  /* Force la cohérence des champs auth-field dans le sidebar : on garde la
     même base que loginV2 mais on réduit légèrement le padding pour bien
     rentrer dans la largeur 380px. */
  .v2-rv .auth-field__control { padding-inline: 0.75rem; border-radius: 12px; }
  .v2-rv .auth-field__input { padding-block: 0.75rem; font-size: 0.875rem; }
  .v2-rv .auth-submit { padding-block: 0.875rem; border-radius: 12px; }

  /* =====================================================================
   * MATCH OUVERT (réservation ouverte) — V2
   * ===================================================================== */

  /* Bloc toggle « Match ouvert » — design switch pleine largeur, placé sous le
     bouton « Match Défi-Plugin » dans la section Partenaires. */
  .v2-rv-openmatch {
    margin-block: 0.5rem 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .v2-rv-openmatch-btn {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    inline-size: 100%;
    padding: 0.625rem 0.75rem;
    border: 1.5px solid var(--border);
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.18s var(--ease-out), border-color 0.18s var(--ease-out);
  }
  .v2-rv-openmatch-btn:hover { border-color: var(--border-strong); }
  .v2-rv-openmatch-btn .ico { display: inline-flex; flex: none; color: var(--text-3); }
  .v2-rv-openmatch-btn .ico svg { inline-size: 18px; block-size: 18px; }
  .v2-rv-openmatch-label { flex: 1 1 auto; text-align: start; }
  /* Petit switch on/off à droite */
  .v2-rv-openmatch-switch {
    flex: none;
    inline-size: 38px;
    block-size: 22px;
    border-radius: 999px;
    background: var(--border-strong);
    position: relative;
    transition: background 0.18s var(--ease-out);
  }
  .v2-rv-openmatch-switch::after {
    content: "";
    position: absolute;
    inset-block-start: 2px;
    inset-inline-start: 2px;
    inline-size: 18px;
    block-size: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.25);
    transition: transform 0.2s var(--ease-out);
  }
  /* État activé */
  .v2-rv-openmatch-btn[aria-pressed="true"],
  .v2-rv-openmatch-btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent-text, var(--text));
  }
  .v2-rv-openmatch-btn[aria-pressed="true"] .ico,
  .v2-rv-openmatch-btn.is-active .ico { color: var(--accent); }
  .v2-rv-openmatch-btn[aria-pressed="true"] .v2-rv-openmatch-switch,
  .v2-rv-openmatch-btn.is-active .v2-rv-openmatch-switch { background: var(--accent); }
  .v2-rv-openmatch-btn[aria-pressed="true"] .v2-rv-openmatch-switch::after,
  .v2-rv-openmatch-btn.is-active .v2-rv-openmatch-switch::after { transform: translateX(16px); }
  /* Bloc « Type de match » : libellé au-dessus + 2 vrais boutons Public/Privé
     pleine largeur (50/50). */
  .v2-rv-openmatch-type {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.625rem 0.75rem;
    border: 1.5px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
  }
  .v2-rv-openmatch-type[hidden] { display: none; }
  .v2-rv-openmatch-type .lbl {
    font-size: 0.6875rem;
    font-weight: 700;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }
  .v2-rv-openmatch-seg {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    inline-size: 100%;
  }
  .v2-rv-openmatch-segbtn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    inline-size: 100%;
    padding: 0.625rem 0.5rem;
    border: 1.5px solid var(--border-strong);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s var(--ease-out), border-color 0.15s var(--ease-out), color 0.15s var(--ease-out);
  }
  .v2-rv-openmatch-segbtn svg { inline-size: 15px; block-size: 15px; flex: none; }
  .v2-rv-openmatch-segbtn:hover:not(.is-active) {
    border-color: var(--accent);
    color: var(--text);
  }
  .v2-rv-openmatch-segbtn.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    box-shadow: 0 1px 3px color-mix(in oklch, var(--accent) 35%, transparent);
  }
  /* Note explicative tarif invité + remboursement (match ouvert) */
  /* Bouton « Partager via WhatsApp » d'un match ouvert existant (édition/rejoindre)
     — réutilise le bouton WhatsApp de la modale de partage (.v2-rv-share-wa) ; on
     ne fait que le passer pleine largeur sous le segment Public/Privé. */
  .v2-rv-openmatch [data-rv="openmatch-share"] {
    inline-size: 100%;
    justify-content: center;
    margin-block-start: 0.5rem;
    /* La modale utilise un <a> (hérite la police de la page) ; ici c'est un
       <button> qui, par défaut navigateur, n'hérite PAS font-family → on force
       l'héritage + on fige taille/graisse pour un rendu identique à la modale. */
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 700;
    color: #fff;
  }

  .v2-rv-openmatch-note {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
    margin: 0;
    padding: 0.5rem 0.625rem;
    border-radius: 10px;
    background: var(--accent-soft);
    color: var(--text-2);
    font-size: 0.75rem;
    line-height: 1.4;
  }
  .v2-rv-openmatch-note[hidden] { display: none; }
  .v2-rv-openmatch-note svg {
    inline-size: 15px; block-size: 15px; flex: none;
    margin-block-start: 1px; color: var(--accent);
  }

  /* Bannières contextuelles (profil incomplet / niveau incompatible) */
  .v2-rv-banner {
    display: flex;
    gap: 0.625rem;
    align-items: flex-start;
    padding: 0.75rem 0.875rem;
    border-radius: 12px;
    margin-block-end: 0.875rem;
    font-size: 0.8125rem;
    line-height: 1.45;
    border: 1.5px solid var(--border);
    background: var(--surface-2);
  }
  .v2-rv-banner svg { inline-size: 18px; block-size: 18px; flex: none; margin-block-start: 1px; }
  .v2-rv-banner .body { display: flex; flex-direction: column; gap: 0.375rem; min-width: 0; }
  .v2-rv-banner .body b { font-weight: 800; }
  .v2-rv-banner--warning {
    border-color: color-mix(in oklch, var(--warning) 32%, var(--border));
    background: light-dark(oklch(97% 0.04 80), oklch(26% 0.06 80));
    color: light-dark(oklch(38% 0.12 60), oklch(86% 0.10 80));
  }
  .v2-rv-banner--warning svg { color: light-dark(oklch(52% 0.16 70), oklch(82% 0.14 80)); }
  .v2-rv-banner--danger {
    border-color: color-mix(in oklch, var(--danger) 34%, var(--border));
    background: light-dark(oklch(96% 0.04 25), oklch(25% 0.06 25));
    color: light-dark(oklch(44% 0.16 25), oklch(85% 0.12 25));
  }
  .v2-rv-banner--danger svg { color: light-dark(oklch(52% 0.18 25), oklch(80% 0.14 25)); }
  .v2-rv-level-rows { display: flex; flex-direction: column; gap: 0.125rem; }
  .v2-rv-level-rows span { color: inherit; opacity: 0.92; }

  /* Petit bouton (lien profil dans une bannière) */
  .v2-rv-btn.sm {
    align-self: flex-start;
    padding: 0.375rem 0.625rem;
    font-size: 0.75rem;
    border-radius: 9px;
  }

  /* Bouton secondaire (copier le lien dans le modal de partage) */
  .v2-rv-btn.secondary {
    background: var(--surface-2);
    color: var(--text);
    border: 1.5px solid var(--border);
  }
  .v2-rv-btn.secondary:hover { background: var(--surface-3); }

  /* =====================================================================
   * MODAL DE PARTAGE (match ouvert créé)
   * ===================================================================== */
  .v2-rv-modal--success .v2-rv-modal-icon {
    background: light-dark(oklch(95% 0.06 155), oklch(28% 0.09 155));
    color: light-dark(oklch(48% 0.15 155), oklch(82% 0.14 155));
  }
  .v2-rv-share-modal .v2-rv-modal-body { inline-size: 100%; }
  .v2-rv-share-link {
    margin-block-start: 0.625rem;
  }
  .v2-rv-share-link input {
    inline-size: 100%;
    padding: 0.5rem 0.625rem;
    border: 1.5px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: 0.75rem;
    font-family: var(--font-mono, ui-monospace, monospace);
    text-overflow: ellipsis;
  }
  .v2-rv-share-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    inline-size: 100%;
    margin-block-start: 0.875rem;
  }
  .v2-rv-share-actions .v2-rv-btn { inline-size: 100%; justify-content: center; }
  /* Bouton WhatsApp (vert officiel) */
  .v2-rv-share-wa {
    background: #25d366;
    color: #fff;
    border: 1.5px solid #25d366;
  }
  .v2-rv-share-wa:hover { background: #1ebe5b; border-color: #1ebe5b; }
  .v2-rv-share-wa svg { inline-size: 18px; block-size: 18px; color: #fff; }

  /* =====================================================================
   * MODE REJOINDRE — verrou visuel du nb de joueurs / durée
   * (les cartes restent visibles mais grisées + non interactives)
   * ===================================================================== */
  .v2-rv-join-locked [data-rv="players"],
  .v2-rv-join-locked [data-rv="duration"] {
    opacity: 0.55;
    pointer-events: none;
    filter: grayscale(0.25);
  }

}

/* Fenêtre de paiement SaferPay — mise en page explicite.
   ─────────────────────────────────────────────────────────────────────────
   Deux problèmes réglés ici :
   1. La modale est bornée à la hauteur de l'écran. L'iframe recevait
      auparavant `height: 900px` en dur : sur un écran plus court, le bas du
      formulaire devenait inatteignable.
   2. UNE SEULE zone défile — le document de paiement, à l'intérieur de la
      frame. L'en-tête de la modale reste visible.
   Le markup est relocalisé sous <body> à l'ouverture (cf. le JS) : sans cela
   le `position: fixed` est capturé par #mySidebar, qui porte un transform. */
#myModalSaferpay.modal {
  position: fixed;
  inset: 0;
  z-index: 1080;
  padding: 1rem;
  overflow: hidden;
}
#myModalSaferpay .modal-dialog {
  display: flex;
  align-items: center;
  inline-size: min(720px, 100%);
  max-inline-size: none;
  block-size: 100%;
  margin: 0 auto;
  /* Le style générique de sidebarpop peint `.modal-dialog` en blanc ; or ce
     dialog fait TOUTE la hauteur du viewport (pour centrer le contenu borné à
     900px) → sur un grand écran, la carte blanche dépassait largement au-dessus
     et en dessous du contenu (faux « en-tête »/« pied » géants). Le fond et
     l'ombre appartiennent au `.modal-content`, comme pour #myModalStripe. */
  background: transparent;
  border-radius: 0;
  overflow: visible;
}
#myModalSaferpay .modal-content {
  background: #fff;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  inline-size: 100%;
  /* Hauteur DÉFINIE, pas seulement un maximum : avec un simple max-height le
     corps s'effondre à la hauteur de son contenu, et l'iframe (block-size:100%)
     se réduit à quelques dizaines de pixels. */
  block-size: min(900px, calc(100dvh - 2rem));
  overflow: hidden;
  border-radius: 14px;
}
/* `min-block-size: 0` : sans lui, un enfant flex refuse de se comprimer sous
   sa taille de contenu et fait déborder la modale. */
#myModalSaferpay #modal-Saferpay {
  flex: 1 1 auto;
  min-block-size: 0;
  overflow: hidden;
}
#myModalSaferpay #iframeSaferpay {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}
