/* ============================================================================
 * PLAN-RAIL — grille d'offres adaptative au nombre de cartes
 * HOTFIX pricing-grid-adaptive
 * ----------------------------------------------------------------------------
 * EXTENSION ASSUMÉE DE LA MAQUETTE (MCP Design 5d615881, `footlab.css`).
 *
 * Ce que dit la maquette, vérifié à la source le 2026-08-06 via
 * `DesignSync get_file` (identique au bit près à la copie servie) :
 *
 *     .pricing-grid { margin-top: 56px; display: grid; gap: 20px; }
 *     @media (min-width: 768px) { .pricing-grid {
 *         grid-template-columns: repeat(3, 1fr); align-items: stretch; } }
 *
 *     .offer-teaser { margin-top: 56px; display: grid; gap: 14px; }
 *     @media (min-width: 760px) { .offer-teaser {
 *         grid-template-columns: repeat(3, 1fr); } }
 *
 * La maquette a été dessinée pour TROIS plans. C'était exact tant que trois
 * formules étaient en vente ; le retrait du World Cup Pass (02/08) a transformé
 * ce « 3 » en constante de mise en page, et la troisième colonne est restée —
 * vide. Le nombre d'offres est une DONNÉE (règles de disponibilité : vente
 * ouverte, prix Stripe configuré, palier du visiteur), pas une constante.
 *
 * CE FICHIER N'EST PAS DANS LE DESIGN. Il est chargé APRÈS `footlab.css` par
 * `partials/maquette-base`. `footlab.css` reste le miroir exact du projet
 * Claude Design et n'est pas touché : la doctrine « le Design est la source de
 * vérité » tient, l'extension vit à côté.
 *
 * ── POURQUOI FLEX ET NON `grid auto-fit` ───────────────────────────────────
 * `repeat(auto-fit, minmax(X, 1fr))` sait effondrer les pistes vides, mais ne
 * sait pas centrer une dernière ligne incomplète : 3 cartes sur 2 colonnes
 * laissent l'orpheline collée à gauche, avec un trou à sa droite — le défaut
 * qu'on corrige, déplacé d'une ligne. `flex-wrap` + `justify-content: center`
 * le fait nativement.
 *
 * ── POURQUOI C'EST UNE EXTENSION ET NON UNE RÉÉCRITURE ─────────────────────
 * Au cas nominal, la règle REPRODUIT LA MAQUETTE AU PIXEL. `.offers-shell` fait
 * 1100px moins 2×20px de padding = 1060px de contenu ; à trois cartes :
 *
 *     3 × 340px (--plan-rail-max) + 2 × 20px (--plan-rail-gap) = 1060px
 *
 * soit exactement le `repeat(3, 1fr)` de la maquette. Le point de rupture
 * (768px), la gouttière et `align-items: stretch` sont ceux de la maquette.
 * La règle ne diverge que là où la maquette n'avait rien prévu : 1, 2, 4 cartes.
 *
 * ── ÉCART ASSUMÉ : POINT DE RUPTURE UNIFIÉ À 768px ─────────────────────────
 * `.offer-teaser` basculait à 760px, `.pricing-grid` à 768px. Deux seuils pour
 * la même intention est une dette ; ils sont unifiés à 768px. Conséquence
 * mesurable : entre 760 et 767px de viewport, le teaser de la Landing s'empile
 * au lieu d'afficher trois colonnes. Bande de 8px, sans conséquence pratique.
 *
 * ── COMPORTEMENT ATTENDU ───────────────────────────────────────────────────
 *   1 carte  → une carte de --plan-rail-max, centrée (jamais étirée)
 *   2 cartes → deux cartes de --plan-rail-max, centrées
 *   3 cartes → pleine largeur, identique à la maquette
 *   4 cartes → quatre pistes sur une ligne si la largeur le permet,
 *              sinon 3 + 1 CENTRÉE sur la seconde ligne
 *   n cartes → jamais d'emplacement fantôme, jamais de débordement
 *
 * `.plan-pop` (carte mise en avant) n'a rien de spécifique à faire ici : sa
 * bordure et son halo sont internes à la carte, et son `.plan-badge`
 * (`position: absolute; top: -11px`) tient dans la gouttière la plus étroite
 * (10px pour `.acct-upsell`… voir la note de gouttière plus bas).
 * ========================================================================= */

.plan-rail {
    display: grid;
    gap: var(--plan-rail-gap, 20px);

    /* Neutralise le `repeat(3, 1fr)` de la maquette sous le point de rupture.
       Indispensable pour `.offer-teaser`, dont la media query démarre à 760px :
       sans cette ligne, la bande 760–767px afficherait trois colonnes. */
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .plan-rail {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        align-items: stretch;
    }

    .plan-rail > * {
        flex: 1 1 var(--plan-rail-min, 220px);
        max-width: var(--plan-rail-max, 340px);
        /* Sans `min-width: 0`, un libellé long et insécable (ES/PT) impose sa
           largeur intrinsèque au flex item et fait déborder la ligne. */
        min-width: 0;
    }
}

/* ── Paramétrage par surface ───────────────────────────────────────────────
 * Chaque grille garde SA gouttière de maquette et SA largeur nominale. Aucune
 * valeur n'est écrite dans les vues : la surface porte une classe, la classe
 * porte ses variables. */

/* /abonnement — `.offers-shell` : 1100 − 40 = 1060px de contenu.
   3 × 340 + 2 × 20 = 1060 → cas nominal identique à la maquette. */
.pricing-grid.plan-rail {
    --plan-rail-gap: 20px;
    --plan-rail-min: 220px;
    --plan-rail-max: 340px;
}

/* Landing, section pricing — `.wrap` : 80rem (1280) − 2 × 2rem = 1216px.
   3 × 396 + 2 × 14 = 1216 → cas nominal identique à la maquette. */
.offer-teaser.plan-rail {
    --plan-rail-gap: 14px;
    /* 205px : au point de rupture (768px), `.wrap` n'offre que ~689px et la
       maquette y tient trois colonnes de 220px. Un seuil à 240 cassait la ligne
       en 2 + 1 là où la maquette en montre 3 — l'extension doit rester fidèle
       au cas nominal à TOUTES les largeurs, pas seulement en desktop. Mesuré :
       à 220 le calcul tombait à 688px requis pour 689 disponibles, et le
       sous-pixel décidait du résultat. 205 laisse ~30px de marge. */
    --plan-rail-min: 205px;
    --plan-rail-max: 396px;
}

/* Home compétition — mêmes cartes `.plan` que /abonnement, donc même largeur
   nominale. Avant ce hotfix : `.grid-3` en `auto-fit minmax(220px, 1fr)`, qui
   ne laissait pas d'emplacement vide mais étirait les deux cartes servies à
   ~523px, soit ~1,5× la largeur maquette. */
.plan-grid.plan-rail {
    --plan-rail-gap: 14px;
    --plan-rail-min: 220px;
    --plan-rail-max: 340px;
}

/* Dashboard → onglet Compte, bloc « Passer à… ».
   CLASSE DÉDIÉE, VOLONTAIREMENT PAS `.tc-grid` : cette dernière est partagée
   avec les paires de statistiques du même dashboard (`.tc-stat`), qui doivent
   rester en deux colonnes fixes. La toucher globalement casserait le tableau
   de bord. Avant ce hotfix, le bloc upgrade héritait de son `1fr 1fr` : à 1 ou
   3 cibles (`AccessService::getUpgradeTargets()` en renvoie 0 à 3), la grille
   laissait un emplacement vide.
   Gouttière 10px : héritée de `.tc-grid`, conservée pour ne pas décaler le
   rythme vertical du module. Elle reste inférieure au débord du `.plan-badge`
   (11px), mais ce bloc ne rend pas de `.plan` — ses cartes sont des
   `.team-card`, sans badge en débord. */
.acct-upsell.plan-rail {
    --plan-rail-gap: 10px;
    --plan-rail-min: 220px;
    --plan-rail-max: 340px;
}
