/* ╔═══════════════════════════════════════════════════════════════════════╗
   ║  Cosmélyse V2 — cosmelyse_ingredient_card_base.css                    ║
   ║                                                                       ║
   ║  Socle commun du composant "card ingrédient" (l'unité de rendu        ║
   ║  utilisée par _result_ingredient_card2.php). Contient TOUT le         ║
   ║  squelette : carte repliée, indicateurs, badge minimal, body déplié,  ║
   ║  système d'onglets CSS pur, panneaux, contenu des panneaux,           ║
   ║  responsive de la card et transition d'enrichissement.                ║
   ║                                                                       ║
   ║  Ces règles étaient historiquement dans cosmelyse_result.css          ║
   ║  (sections 16 à 29). Elles ont été extraites ici pour être            ║
   ║  partagées proprement entre les pages result.php, compare.php et      ║
   ║  ingredient.php.                                                      ║
   ║                                                                       ║
   ║  Ce fichier doit être chargé AVANT cosmelyse_ingredient_card.css      ║
   ║  (qui ajoute par-dessus le layout magazine "v3" : KPI strip, hero,    ║
   ║  etc.). L'ordre est important pour que les overrides v3 prennent     ║
   ║  bien le pas sur le socle.                                            ║
   ╚═══════════════════════════════════════════════════════════════════════╝ */


/* ============================================
   16. CARD INGRÉDIENT (état replié)
   ============================================
   Une row par ingrédient. L'élément racine est un <details> pour
   permettre le déplier 100% HTML/CSS sans JS (4.3b).
*/

.ingredient-card {
    background: #fff;
    border-radius: 12px;
    border: 1px solid rgba(0, 0, 0, 0.05);
    margin-bottom: 0.5rem;
    overflow: hidden;
    transition: box-shadow 0.15s ease;
}

.ingredient-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
}

/* Bordure gauche colorée selon safety
 * ─────────────────────────────────────────────────────────────────────
 * TODO migration (salve dédiée, non urgente) :
 *   Ces 4 règles dupliquent .cosm-safety-rule[--safe/--watch/--avoid]
 *   défini dans cosmelyse2.css. La migration consiste à :
 *     1. retirer ces 4 lignes
 *     2. ajouter "cosm-safety-rule cosm-safety-rule--{safety}" au markup
 *        de _result_ingredient_card2.php (à côté de "ingredient-card")
 *     3. conserver les sélecteurs descendants .ingredient-card--safe
 *        .ingredient-card__pos etc. (lignes ~111-144) — ils dépendent
 *        de la classe combinée carte+safety, pas du border-left.
 *   À traiter quand on touchera la fiche ingrédient pour autre chose.
 * ───────────────────────────────────────────────────────────────────── */
.ingredient-card--safe    { border-left: 4px solid var(--primary-green); }
.ingredient-card--watch   { border-left: 4px solid var(--warn-orange);   }
.ingredient-card--avoid   { border-left: 4px solid var(--danger-red);    }
.ingredient-card--unrated { border-left: 4px solid #bbb;                 }

/* État minimal (fiche en cours d'enrichissement) — surcharge sobre */
.ingredient-card--minimal {
    background: var(--bg-soft);
    border-left-color: #d8d8d8;
}

/* Le <summary> lui-même : conteneur block qui empile la grille
   d'infos (head-grid) et le hint d'ouverture (expand-hint). */
.ingredient-card__head {
    cursor: pointer;
    list-style: none;
    user-select: none;
}

/* La grille à 7 colonnes (nom + 6 indicateurs) vit maintenant dans
   un wrapper interne pour que le hint d'ouverture puisse se poser
   en dessous sans devenir une 8e colonne.
.ingredient-card__head-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) repeat(6, 80px);
    gap: 0.5rem;
    align-items: center;
    padding: 1rem;
}
*/
.ingredient-card__head-grid {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
}

.ingredient-card__head::-webkit-details-marker {
    display: none;
}

/* La colonne nom à gauche : pos + name + safety + roles */
.ingredient-card__main {
    min-width: 0;
}

.ingredient-card__title-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
}

.ingredient-card__pos {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.78rem;
    font-weight: 700;
    color: #fff;
    flex-shrink: 0;
    background: var(--primary-pink);
}

/* Couleur du n° de position selon safety */
.ingredient-card--safe    .ingredient-card__pos { background: var(--primary-green); }
.ingredient-card--watch   .ingredient-card__pos { background: var(--warn-orange);   }
.ingredient-card--avoid   .ingredient-card__pos { background: var(--danger-red);    }
.ingredient-card--unrated .ingredient-card__pos { background: var(--text-disabled);                 }

.ingredient-card__name {
    font-family: 'Outfit', sans-serif;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-dark);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ingredient-card__safety {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.6rem;
    border-radius: 100px;
    font-size: 0.7rem;
    font-weight: 600;
    flex-shrink: 0;
}

.ingredient-card--safe    .ingredient-card__safety { background: rgba(143, 181, 105, 0.15); color: var(--darker-green); }
.ingredient-card--watch   .ingredient-card__safety { background: rgba(243, 156, 18, 0.15);  color: var(--warn-orange);  }
.ingredient-card--avoid   .ingredient-card__safety { background: rgba(231, 76, 60, 0.15);   color: #a52d22;             }
.ingredient-card--unrated .ingredient-card__safety { background: rgba(0, 0, 0, 0.06);       color: var(--text-soft);                }

/* Wrapper des 6 indicateurs : en desktop il est "transparent" (display:
   contents) → les 6 indicators participent à la grille parente
   .ingredient-card__head (1fr repeat(6, 80px)). En mobile, on bascule
   en grille propre 3x2 via le @media de la section 20. 
.ingredient-card__indicators {
    display: contents;
}*/
.ingredient-card__indicators {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.5rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
}
/* ============================================
   16bis. HINT D'OUVERTURE (chevron bottom)
   ============================================
   Petite bande en bas du <summary> avec un chevron centré qui
   indique que la card se déplie. Pivote à 180° quand le <details>
   est ouvert. Masqué en mode --minimal (rien à déplier) et en mode
   --forced-open (cf. cosmelyse_ingredient.css).
*/
.ingredient-card__expand-hint {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0.25rem 0;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
    color: #b0b0b0;
    background: #fcfcfc;
    transition: color 0.15s ease, background 0.15s ease;
}

.ingredient-card__expand-hint i {
    font-size: 0.95rem;
    line-height: 1;
    transition: transform 0.2s ease;
}

/* Feedback au survol du head (= summary entier) : le hint
   reprend la couleur de la charte verte */
.ingredient-card__head:hover .ingredient-card__expand-hint {
    color: var(--darker-green);
    background: rgba(143, 181, 105, 0.06);
}

/* Card ouverte : chevron pointe vers le haut (= "cliquer pour fermer") */
.ingredient-card[open] .ingredient-card__expand-hint i {
    transform: rotate(180deg);
}

/* Card minimale (fiche en cours d'enrichissement) : rien à déplier,
   on retire le hint pour ne pas suggérer une interaction inutile. */
.ingredient-card--minimal .ingredient-card__expand-hint {
    display: none;
}
/* ============================================
   17. INDICATEURS (6 colonnes par ingrédient)
   ============================================
   Chaque indicateur est un mini-bloc empilé : icône / valeur / label.
   Sur mobile : on bascule en grille 2x3 sous la colonne nom.
*/

.indicator {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    text-align: center;
    min-width: 0;
    border: 1px solid var(--border-default);
    padding: .60rem;
    border-radius: 5px;
    background: linear-gradient(135deg, #f7f7f7, #fbfbfb);
}

.indicator__icon {
    font-size: 1rem;
    line-height: 1;
}

.indicator__value {
    font-family: 'Outfit', sans-serif;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-dark);
    line-height: 1.1;
}

.indicator__label {
    font-size: 0.65rem;
    color: var(--text-muted);
    line-height: 1.1;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Couleurs sémantiques par level */
.indicator--good i    { color: var(--primary-green); }
.indicator--neutral i { color: var(--text-hint);                 }
.indicator--watch i   { color: var(--warn-orange);   }
.indicator--avoid i   { color: var(--danger-red);    }


/* ============================================
   18. CARD MINIMAL (fiche en cours d'enrichissement)
   ============================================
   Quand enrichment_status='minimal', on remplace les 6 indicateurs
   par un badge unique "Fiche en cours de complétion".
*/

.ingredient-card__minimal-badge {
    grid-column: 2 / -1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    background: rgba(243, 156, 18, 0.1);
    border-radius: 8px;
    color: var(--warn-orange);
    font-size: 0.78rem;
    font-weight: 600;
}

.ingredient-card__minimal-badge i {
    font-size: 0.95rem;
}



/* ============================================
   20. RESPONSIVE — Card ingrédient (mobile)
   ============================================
   Mobile : la card passe en layout vertical, les 6 indicateurs
   prennent une grille 3×2 sous le nom de l'ingrédient.
   (Le mobile du header de colonnes ingredients-col-header reste
   côté cosmelyse_result.css car spécifique à result.php.)
*/

@media (max-width: 760px) {
    /* Card ingrédient : layout vertical (la grille vit dans head-grid) */
    .ingredient-card__head-grid {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }

    .ingredient-card__main {
        margin-bottom: 0.4rem;
    }

    /* Les 6 indicateurs en grille 3x2 sous le nom */
    .ingredient-card__indicators {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 0.6rem;
        padding-top: 0.5rem;
        border-top: 1px solid rgba(0, 0, 0, 0.05);
    }

    .ingredient-card__minimal-badge {
        grid-column: auto;
    }

    /* En mobile on AJOUTE le label sous chaque indicateur (déjà géré
       par .indicator__label) — on s'assure juste qu'il s'affiche */
    .indicator__label {
        font-size: 0.62rem;
    }
}

/* ============================================
   21. BODY DE LA CARD (déplié)
   ============================================
   Le body apparaît automatiquement quand <details> est ouvert.
   Le layout flex-wrap (cf. section 22) permet aux 4 labels d'onglets
   de s'aligner sur une rangée, puis aux 4 panneaux de prendre toute
   la largeur en passant à la ligne.
*/

.ingredient-card__body {
    border-top: 1px solid rgba(255, 107, 157, 0.12);
    padding: 1rem;
    background: rgba(255, 107, 157, 0.035);
}


/* ── Note narrative en tête du body, au-dessus des onglets ──
   Bloc lecture rapide qui résume l'ingrédient en 1-2 phrases.
   Visible dès l'ouverture de la card, AVANT que l'utilisateur
   n'ait choisi un onglet — donne immédiatement le ton. */
.ing-body-note {
    flex: 0 0 100%;        /* prend toute la largeur du flex parent */
    width: 100%;
    margin: 0 0 1rem;
    padding: 0.85rem 1rem;
    background: rgba(143, 181, 105, 0.06);
    border-left: 4px solid var(--primary-green);
    border-radius: 0 8px 8px 0;
    color: var(--text-dark);
    font-size: 0.92rem;
    line-height: 1.5;
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}

.ing-body-note__icon {
    color: var(--primary-green);
    font-size: 1.1rem;
    line-height: 1.4;
    flex-shrink: 0;
}


/* ============================================
   22. SYSTÈME D'ONGLETS (CSS pur — zéro JS)
   ============================================
   Pattern : <input type="radio"> caché + <label> stylé en bouton +
   panneaux qui se montrent/cachent via :has() + sibling selectors.
   
   Subtilité ergonomique :
     - L'onglet ACTIF est rose plein.
     - Un onglet VIDE (sans contenu disponible) reçoit la classe
       .ing-tabs__tab--empty et apparaît grisé non-cliquable. Pédagogique :
       l'utilisateur sait avant de cliquer qu'il n'y a rien à voir.
     - Le clavier fonctionne : Tab pour passer d'onglet en onglet,
       Espace ou Entrée pour activer, flèches gauche/droite pour
       naviguer (comportement natif des radios même name).
   
   Architecture markup attendue (tous frères, dans cet ordre) :
     <input radio>  <label>  (×4)
     <div tab-pane> (×4)
   
   Les radios sont AVANT leur label correspondant pour que :checked +
   fonctionne. Les panneaux sont après, et :has() sur le body active
   le bon panneau selon la radio cochée.
*/

/* On masque les radios elles-mêmes — on stylise les labels comme
   des boutons d'onglet. Les radios restent focusables au clavier
   (donc accessibles), juste invisibles visuellement. */
.ing-tabs__radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 1px;
    height: 1px;
}

/* Le body utilise flex-wrap. Les 4 radios (taille 1×1 invisible) et les
   4 labels prennent leur place naturellement. Les panneaux qui suivent
   sont en width:100% pour passer à la ligne.
   
   Subtilité : gap=0 entre les labels pour qu'ils forment une bande
   visuellement continue. Les radios masquées sont en absolute, donc
   ne participent pas au layout flex. */
.ingredient-card__body {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0;
}

/* Les panneaux prennent toute la largeur (donc passent à la ligne après
   la rangée des labels). */
.ingredient-card__body > .tab-pane {
    flex: 0 0 100%;
    width: 100%;
    margin-top: 0;
    padding: 1.25rem 0.25rem 0;
    border-top: none;
}

/* ─── Cadrage de la barre d'onglets — option α (cream + rose actif) ──
   Les 4 labels forment une bande visuellement continue avec un fond
   crème commun. Les radius extérieurs (premier et dernier label) donnent
   l'apparence d'un bloc unifié. L'onglet actif ressort par contraste
   de couleur (rose chaud sur crème neutre), pas par contraste de
   luminosité — résultat plus doux et harmonieux que l'ancienne bande
   sombre.
*/

/* Chaque label : fond crème par défaut, séparateurs verticaux fins */
.ing-tabs__tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.75rem 1.1rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: #7a766c;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
    user-select: none;
    background: #f3ede4;
    border: none;
    border-right: 1px solid rgba(0, 0, 0, 0.05);
    flex: 1 1 auto;
    text-align: center;
    min-width: 0;
}

/* Premier et dernier label : radius extérieurs uniquement,
   pas de border-right sur le dernier */
.ing-tabs__radio:nth-of-type(1) + .ing-tabs__tab {
    border-top-left-radius: 10px;
    border-bottom-left-radius: 10px;
}

.ing-tabs__radio:last-of-type + .ing-tabs__tab {
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
    border-right: none;
}

/* Survol d'un onglet inactif : fond légèrement plus foncé + texte rose */
.ing-tabs__tab:hover {
    background: #ebe3d4;
    color: var(--primary-pink);
}

/* Indicateur clavier — outline visible quand la radio masquée reçoit le focus */
.ing-tabs__radio:focus-visible + .ing-tabs__tab {
    outline: 2px solid var(--primary-pink);
    outline-offset: -2px;
    z-index: 1;
}

/* Onglet vide (sans contenu) — texte très estompé mais reste cliquable
   (pédagogique : l'utilisateur peut quand même y aller pour le message
   "rien à montrer") */
.ing-tabs__tab--empty {
    color: #ccc7bd;
    cursor: default;
}

.ing-tabs__tab--empty:hover {
    background: #f3ede4;
    color: #ccc7bd;
}

.ing-tabs__tab i {
    font-size: 0.95rem;
}


/* ── État ACTIF : la radio cochée colore le label en rose plein.
      L'astuce du sibling (+) impose que l'input soit AVANT le label
      dans le markup, ce qui est notre cas.
      Le rose chaud ressort par contraste DE COULEUR sur le crème
      neutre, pas par contraste de luminosité — effet plus doux. */
.ing-tabs__radio:checked + .ing-tabs__tab {
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    color: #fff;
    box-shadow: 0 2px 8px rgba(233, 30, 99, 0.22);
    /* l'onglet actif ressort en élevé, on retire le séparateur droit */
    border-right-color: transparent;
    z-index: 2;
    position: relative;
}

.ing-tabs__radio:checked + .ing-tabs__tab:hover {
    color: #fff;
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
}

/* Le séparateur du label précédent un actif disparaît aussi (sinon
   ligne fine visible entre la bande sombre et le rose) */
.ing-tabs__radio:checked + .ing-tabs__tab + .ing-tabs__radio + .ing-tabs__tab {
    /* pas d'effet visuel particulier ici, juste un placeholder
       au cas où on voudrait styler le label suivant un actif */
}


/* ============================================
   23. PANNEAUX (tab-pane)
   ============================================
   Visibilité contrôlée par les radios via :has() + sélecteur d'attribut.
   :has() est largement supporté par tous les navigateurs evergreen
   depuis fin 2023.
*/

.tab-pane {
    display: none;
}

/* On affiche le panneau dont la radio sœur (par data-tab matching) est cochée */
.ingredient-card__body:has(.ing-tabs__radio--safety:checked)  .tab-pane[data-tab="safety"]  { display: block; }
.ingredient-card__body:has(.ing-tabs__radio--skin:checked)    .tab-pane[data-tab="skin"]    { display: block; }
.ingredient-card__body:has(.ing-tabs__radio--origins:checked) .tab-pane[data-tab="origins"] { display: block; }
.ingredient-card__body:has(.ing-tabs__radio--sheet:checked)   .tab-pane[data-tab="sheet"]   { display: block; }


/* ============================================
   24. CONTENU DES PANNEAUX
   ============================================
   Chaque panneau est composé de "sections" — un titre + des éléments
   visuels (badges, gauges, listes, paragraphes). La section a un padding
   et une bordure subtile entre elles pour aérer.
*/

.tab-pane {
    /* anim douce à l'apparition */
    animation: tabFadeIn 0.2s ease-out;
}

@keyframes tabFadeIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0);   }
}

.tab-section {
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}

.tab-section:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}

.tab-section__title {
    font-family: 'Outfit', sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-dark);
    margin: 0 0 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.tab-section__title i {
    color: var(--primary-pink);
    font-size: 1rem;
}

.tab-section__note {
    color: var(--text-secondary);
    font-size: 0.88rem;
    line-height: 1.55;
    margin: 0.5rem 0 0;
}

.tab-section__hint {
    color: var(--text-muted);
    font-size: 0.82rem;
    line-height: 1.5;
    margin: 0.4rem 0 0;
    font-style: italic;
}

/* Bloc de mise en valeur (encart info / warning / danger) */
.tab-callout {
    border-radius: 10px;
    padding: 0.85rem 1rem;
    margin-bottom: 0.75rem;
    border-left: 4px solid #ddd;
    background: var(--bg-soft);
}

.tab-callout--success { border-left-color: var(--primary-green); background: rgba(143, 181, 105, 0.06); }
.tab-callout--warning { border-left-color: var(--warn-orange);   background: rgba(243, 156, 18, 0.06);  }
.tab-callout--danger  { border-left-color: var(--danger-red);    background: rgba(231, 76, 60, 0.05);   }

.tab-callout__title {
    font-weight: 700;
    color: var(--text-dark);
    margin: 0 0 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.92rem;
}

.tab-callout__body {
    color: #555;
    font-size: 0.88rem;
    line-height: 1.5;
    margin: 0;
}


/* ============================================
   25. PAIRE INTERACTIONS (avoid_with + synergy_with)
   ============================================
   Subtilité ergonomique #3 : les interactions négatives et positives
   se font écho visuellement, côte à côte. L'utilisateur lit en miroir.
*/

.ing-interactions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

.ing-interactions__pair {
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
    border: 1px solid rgba(0, 0, 0, 0.05);
}

.ing-interactions__pair--avoid   { background: rgba(231, 76, 60, 0.04);   border-color: rgba(231, 76, 60, 0.15);  }
.ing-interactions__pair--synergy { background: rgba(143, 181, 105, 0.04); border-color: rgba(143, 181, 105, 0.15); }

.ing-interactions__head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.4rem;
}

.ing-interactions__pair--avoid   .ing-interactions__head { color: #a52d22;             }
.ing-interactions__pair--synergy .ing-interactions__head { color: var(--darker-green); }

.ing-interactions__list {
    color: #444;
    font-size: 0.88rem;
    line-height: 1.4;
}


/* ============================================
   26. PANNEAU "ORIGINES POSSIBLES"
   ============================================
   Liste verticale d'origines alternatives possibles, chacune avec
   un badge "Dominant / Courant / Rare".
*/

.possible-origins-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.possible-origin-item {
    background: #fff;
    border-radius: 8px;
    border: 1px solid rgba(0, 0, 0, 0.06);
    padding: 0.7rem 0.9rem;
}

.possible-origin-item__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}

.possible-origin-item__name {
    font-weight: 700;
    color: var(--text-dark);
    font-size: 0.92rem;
}

.possible-origin-item__desc {
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.45;
    margin: 0.2rem 0 0;
}


/* ============================================
   27. ONGLET FICHE — concentration + listes
   ============================================
*/

.fiche-conc {
    font-family: 'Outfit', sans-serif;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--primary-pink);
}

/* Liste de chips qui peut prendre toute la largeur (synonymes, aliases) */
.fiche-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.4rem;
}


/* ============================================
   28. RESPONSIVE — déplié
   ============================================ */

@media (max-width: 760px) {
    /* Les 4 onglets passent en 2x2 (chaque label fait 50% de largeur).
       Comme la barre est continue (gap=0), ça forme un bloc 2x2 carré. */
    .ing-tabs__tab {
        flex: 0 0 50%;
        font-size: 0.78rem;
        padding: 0.6rem 0.5rem;
    }

    /* Sur 2 rangées, les radius extérieurs sont différents :
       les 2 premiers en haut (bord supérieur), les 2 derniers en bas. */
    .ing-tabs__radio:nth-of-type(1) + .ing-tabs__tab {
        border-radius: 10px 0 0 0;
    }
    .ing-tabs__radio:nth-of-type(2) + .ing-tabs__tab {
        border-radius: 0 10px 0 0;
        border-right: none;
    }
    .ing-tabs__radio:nth-of-type(3) + .ing-tabs__tab {
        border-radius: 0 0 0 10px;
        border-top: 1px solid rgba(0, 0, 0, 0.05);
    }
    .ing-tabs__radio:last-of-type + .ing-tabs__tab {
        border-radius: 0 0 10px 0;
        border-top: 1px solid rgba(0, 0, 0, 0.05);
    }

    .ing-interactions {
        grid-template-columns: 1fr;
    }
}


/* ============================================
   29. TRANSITION DE SWAP (cards et pills)
   ============================================
   Quand le JS remplace une card minimal par sa version enrichie,
   on veut un fade-in court pour que ce soit fluide à l'œil.
   
   L'animation est ciblée par la classe .just-enriched (posée par
   cosmelyse-async-cards.js juste avant l'insertion, retirée 350ms
   plus tard). Cette ciblage évite que l'animation rejoue sur les
   cards qui ne changent pas réellement à chaque cycle de polling.
*/

.ingredient-card.just-enriched,
.formula-map__pill.just-enriched {
    animation: cosmSwapIn 0.3s ease-out;
}

@keyframes cosmSwapIn {
    from { opacity: 0.4; }
    to   { opacity: 1;   }
}


