/* ═══════════════════════════════════════════════════════════════════════
   COSMELYSE — CARD INGRÉDIENT (fichier UNIQUE)
   ═══════════════════════════════════════════════════════════════════════

   Fusion (08/2026) de trois fichiers historiques, dans leur ordre de
   cascade d'origine — servie via _score_page_assets.php sur toutes les
   pages qui rendent des cards :

     1. SOCLE        ex-cosmelyse_ingredient_card_base.css, PURGÉ des
                     règles de l'ancien header pré-v4 (template
                     supprimé : .ingredient-card__head/__pos/__name/
                     __safety, .indicator__*, .tab-section, …)
     2. MAGAZINE     ex-cosmelyse_ingredient_card_v3.css, intégral —
                     le corps de la card v4 consomme TOUT ce layout
                     (note, mag cards, onglets internes, subcards)
     3. HEADER V4    ex-cosmelyse_ingredient_card_v4.css, intégral
                     (summary grid, axes, fullname/sheet-link)

   Ce fichier est le SEUL css de la card : ne pas recréer de variante
   par version — étendre ici.
   ═══════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════
   1. SOCLE — état replié, body, mécanique des onglets (ex-base, purgé)
   ═══════════════════════════════════════════════════════════════════════ */

/* ============================================
   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-top: 1px solid rgba(0, 0, 0, 0.05);
    border-right: 1px solid rgba(0, 0, 0, 0.05);
    border-bottom: 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);
}

/* Liseré gauche safety : porté par .cosm-safety-rule[--safe/--watch/
   --avoid] (cosmelyse2.css), classes posées dans le markup de
   _result_ingredient_card2.php — TODO historique exécuté 08/2026.
   Delta assumé : unrated suit la base grise du composant (#bbb) au
   lieu de l'ancien --text-hint (#999). .ingredient-card--minimal
   conserve sa surcharge dédiée ci-dessous. Les modificateurs
   .ingredient-card--{safety} RESTENT au markup : les badges de
   position (.ing4-head__pos, section HEADER V4) en dépendent. */

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

/* ============================================
   21. BODY DE LA CARD (déplié)
   ============================================
   Le body apparaît quand <details> est ouvert. Flux block simple :
   axes, nom complet, note, radios (0×0), tabset puis panneaux
   s'empilent naturellement. Règle CONSOLIDÉE 08/2026 : fusion des
   couches historiques socle (fond rosé, jamais visible) et v3
   (override #fff) en une seule définition.
*/

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


/* 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 est un simple flux BLOCK depuis l'assainissement 08/2026 :
   l'ancien display:flex/flex-wrap legacy est retiré — il téléportait
   la position statique des radios absolute en haut de la card (spec
   flexbox) et piégeait tout enfant court (cf. lots H/I).
   DETTE C (à démêler lors d'une passe dédiée) : les anciennes
   compensations flex des enfants restent en place, inertes en flux
   block/grid — flex-basis des .tab-pane, flex des .ing-tabs__tab du
   socle, media 760 « onglets 2×2 ». Le système d'onglets du socle est
   largement écrasé par la couche MAGAZINE, SAUF le focus-visible
   clavier qui n'existe QUE ici : à préserver lors du démêlage. */

/* 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;
}

/* 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));
}

/* (Règle « séparateur du label précédant l'actif » retirée 08/2026 :
   elle était VIDE depuis l'origine.) */


/* ============================================
   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);   }
}


/* ============================================
   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);
    }
}


/* ============================================
   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;   }
}


/* ═══════════════════════════════════════════════════════════════════════
   2. MAGAZINE — corps de card : note, mag, onglets, subcards (ex-v3)
   ═══════════════════════════════════════════════════════════════════════ */

/* ╔═══════════════════════════════════════════════════════════════════════╗
 * ║  cosmelyse_ingredient_card_v3.css                                     ║
 * ║                                                                       ║
 * ║  Card d'un ingrédient — Layout C (Magazine bandeaux) + onglets        ║
 * ║  segmented control. Utilisé par _result_ingredient_card2.php.         ║
 * ║                                                                       ║
 * ║  Ce fichier contient les OVERRIDES "v3" (layout magazine, KPI strip,  ║
 * ║  hero, etc.) qui viennent par-dessus le socle commun défini dans      ║
 * ║  cosmelyse_ingredient_card_base.css. Ce dernier DOIT être chargé      ║
 * ║  AVANT ce fichier pour que la cascade fonctionne correctement.        ║
 * ║                                                                       ║
 * ║  S'appuie sur les variables globales de cosmelyse2.css :              ║
 * ║    --primary-pink, --dark-pink, --primary-green, --darker-green,      ║
 * ║    --info-blue, --warn-orange, --danger-red, --cream, --text-dark.    ║
 * ║                                                                       ║
 * ║  Les noms de classes .ing-v3-* reflètent l'historique de conception   ║
 * ║  (3 itérations layout). Conservés tels quels pour ne pas toucher le   ║
 * ║  PHP. À renommer en .cosm-* le jour où on promeut les blocs           ║
 * ║  réutilisables (KPI strip, mag-card, sub-card) en composants          ║
 * ║  génériques du design system.                                         ║
 * ╚═══════════════════════════════════════════════════════════════════════╝ */


/* ═══════════════════════════════════════════════════════════════════════
   1. VARIABLES LOCALES
   Uniquement les nuances qui n'ont pas d'équivalent global.
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 {
    /* Variantes foncées pour le contraste sur fond pâle :
       les --info-blue / --warn-orange / --danger-red globaux sont
       trop clairs en texte sur fond rgba 0.20. */
    --ing-blue-dark:   #2c6885;
    --ing-orange-dark: #b87510;
    --ing-red-dark:    #c0392b;

    /* Tons neutres réutilisés (bandeau neutre, sub-card, séparateurs) */
    --ing-neutral-bg:    #ece9e2;
    --ing-neutral-text:  #5d574b;
    --ing-panel-bg:      #fbfbfb;
    --ing-panel-border:  var(--border-default);
    --ing-subcard-bg:    var(--bg-soft);
    --ing-subcard-border: rgba(0, 0, 0, 0.05);
}


/* ═══════════════════════════════════════════════════════════════════════
   2. NOTE D'INTRO
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-note {
    margin: 0 0 18px;
    padding: 14px 16px;
    background: var(--ing-panel-bg); /* var(--primary-green) à 8 % */
    border-radius: 10px;
    display: flex;
    gap: 10px;
    align-items: flex-start;
    color: var(--text-dark);
    font-size: 0.92rem;
    line-height: 1.5;
    border:1px solid var(--border-default);
}

.ing-v3 .ing-v3-note > i {
    flex-shrink: 0;
    color: var(--text-dark);
    font-size: 1.1rem;
    line-height: 1.5;
}


/* ═══════════════════════════════════════════════════════════════════════
   3. BARRE D'ONGLETS — segmented control pleine largeur
═══════════════════════════════════════════════════════════════════════ */

/* Les radios restent dans le DOM (siblings des panels) mais invisibles. */
.ing-v3 .ing-tabs__radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

/* Conteneur : 4 colonnes égales, prend toute la largeur du parent. */
.ing-v3 .ing-v3-tabset {
    margin-top: 4px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: var(--ing-panel-bg);
    border: 1px solid var(--ing-panel-border);
    border-bottom: 0;
    border-radius: 12px 12px 0 0;
    overflow: hidden;
    width: max-content; max-width: 100%
}

.ing-v3 .ing-tabs__tab {
    padding: 13px 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: transparent;
    border: none;
    border-right: 1px solid rgba(0, 0, 0, 0.04);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    cursor: pointer;
    user-select: none;
    transition: color 0.12s, background 0.12s;
}

.ing-v3 .ing-v3-tabset > .ing-tabs__tab:last-child {
    border-right: none;
}

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

.ing-v3 .ing-tabs__tab:hover {
    color: var(--dark-pink);
    background: rgba(255, 107, 157, 0.04);
}

/* Onglet désactivé (pas de contenu sur cet onglet). */
.ing-v3 .ing-tabs__tab--empty {
    color: #c8c8c8;
    cursor: not-allowed;
    pointer-events: none;
}

/* Onglet actif : :has() cible le label associé au radio :checked,
   matché par l'attribut for$="-XXX". */
.ing-v3:has(.ing-tabs__radio--safety:checked)  .ing-v3-tabset > label[for$="-safety"],
.ing-v3:has(.ing-tabs__radio--skin:checked)    .ing-v3-tabset > label[for$="-skin"],
.ing-v3:has(.ing-tabs__radio--origins:checked) .ing-v3-tabset > label[for$="-origins"],
.ing-v3:has(.ing-tabs__radio--sheet:checked)   .ing-v3-tabset > label[for$="-sheet"] {
    background: var(--ing-panel-border);
    color: var(--text-dark);
    font-weight: 900;
}

/* Fallback :has() non supporté (navigateurs très anciens) : on dégrade
   proprement en mettant tous les onglets en couleur rose fade. */
@supports not selector(:has(*)) {
    .ing-v3 .ing-tabs__tab {
        color: var(--dark-pink);
        opacity: 0.6;
    }
}


/* ═══════════════════════════════════════════════════════════════════════
   4. CADRE D'ONGLET (tab-pane)
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .tab-pane {
    display: none;
    padding: 10px;
    background: var(--ing-panel-bg);
    border: 1px solid var(--ing-panel-border);
    border-radius: 0 12px 12px 12px;
    margin-top: 0;
}

/* Affichage du pane dont le radio est :checked. */
.ing-v3 .ing-tabs__radio--safety:checked  ~ .tab-pane[data-tab="safety"],
.ing-v3 .ing-tabs__radio--skin:checked    ~ .tab-pane[data-tab="skin"],
.ing-v3 .ing-tabs__radio--origins:checked ~ .tab-pane[data-tab="origins"],
.ing-v3 .ing-tabs__radio--sheet:checked   ~ .tab-pane[data-tab="sheet"] {
    display: block;
}


/* ═══════════════════════════════════════════════════════════════════════
   5. KPI STRIP — 3 mini-cards de verdict en exergue
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-kpi-strip {
    margin-bottom: 18px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.ing-v3 .ing-v3-kpi {
    padding: 12px 14px;
    background: #fff;
    border: 1px solid var(--ing-panel-border);
    border-radius: 10px;
    display: flex;
    align-items: center;
    gap: 11px;
}

.ing-v3 .ing-v3-kpi__icon {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    font-size: 1.05rem;
}

.ing-v3 .ing-v3-kpi__icon--success { background: rgba(143, 181, 105, 0.16); color: var(--darker-green); }
.ing-v3 .ing-v3-kpi__icon--info    { background: rgba(93, 173, 226, 0.16);  color: var(--ing-blue-dark); }
.ing-v3 .ing-v3-kpi__icon--warning { background: rgba(243, 156, 18, 0.16);  color: var(--ing-orange-dark); }
.ing-v3 .ing-v3-kpi__icon--danger  { background: rgba(231, 76, 60, 0.14);   color: var(--danger-red); }
.ing-v3 .ing-v3-kpi__icon--neutral { background: var(--ing-neutral-bg);     color: var(--text-soft); }

.ing-v3 .ing-v3-kpi__body {
    flex: 1;
    min-width: 0;
}

.ing-v3 .ing-v3-kpi__value {
    color: var(--text-dark);
    font-family: 'Outfit', sans-serif;
    font-size: 0.92rem;
    font-weight: 700;
    line-height: 1.2;
}

.ing-v3 .ing-v3-kpi__label {
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 0.62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}


/* ═══════════════════════════════════════════════════════════════════════
   6. GRILLE DE MAG-CARDS — bandeau coloré + corps blanc
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-mag {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
}

.ing-v3 .ing-v3-mag__card {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 12px;
    overflow: hidden;
}

.ing-v3 .ing-v3-mag__card--full {
    grid-column: 1 / -1;
}

.ing-v3 .ing-v3-mag__banner {
    padding: 7px 12px;
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: 'Outfit', sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

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

.ing-v3 .ing-v3-mag__banner small {
    margin-left: 2px;
    opacity: 0.75;
    font-size: 0.62rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
}

.ing-v3 .ing-v3-mag__banner--success { background: rgba(143, 181, 105, 0.20); color: var(--darker-green); }
.ing-v3 .ing-v3-mag__banner--info    { background: rgba(93, 173, 226, 0.20);  color: var(--ing-blue-dark); }
.ing-v3 .ing-v3-mag__banner--rose    { background: var(--ing-neutral-bg);     color: var(--ing-neutral-text); }
.ing-v3 .ing-v3-mag__banner--warning { background: rgba(243, 156, 18, 0.20);  color: var(--ing-orange-dark); }
.ing-v3 .ing-v3-mag__banner--danger  { background: rgba(231, 76, 60, 0.16);   color: var(--ing-red-dark); }
.ing-v3 .ing-v3-mag__banner--neutral { background: var(--ing-neutral-bg);     color: var(--ing-neutral-text); }

.ing-v3 .ing-v3-mag__body {
    flex: 1;
    padding: 14px 16px;
    color: #555;
    font-size: 0.86rem;
    line-height: 1.6;
}

.ing-v3 .ing-v3-mag__body strong {
    color: var(--text-dark);
    font-weight: 600;
}

.ing-v3 .ing-v3-mag__body p {
    margin: 0;
}

.ing-v3 .ing-v3-mag__body p + p {
    margin-top: 8px;
}

.ing-v3 .ing-v3-mag__body .ing-v3-hint {
    margin-top: 8px;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-style: italic;
    line-height: 1.55;
}


/* ═══════════════════════════════════════════════════════════════════════
   7. PILLS — réutilisables dans les bandeaux, sub-cards, badge-rows
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-pill {
    padding: 3px 10px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-radius: 12px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

.ing-v3 .ing-v3-pill--success { background: rgba(143, 181, 105, 0.20); color: var(--darker-green); }
.ing-v3 .ing-v3-pill--info    { background: rgba(93, 173, 226, 0.20);  color: var(--ing-blue-dark); }
.ing-v3 .ing-v3-pill--warning { background: rgba(243, 156, 18, 0.20);  color: var(--ing-orange-dark); }
.ing-v3 .ing-v3-pill--danger  { background: rgba(231, 76, 60, 0.16);   color: var(--ing-red-dark); }
.ing-v3 .ing-v3-pill--neutral { background: var(--ing-neutral-bg);     color: var(--text-soft); }


/* ═══════════════════════════════════════════════════════════════════════
   8. MÉTRIQUE LARGE (concentration typique)
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-metric {
    margin: 2px 0 8px;
    color: var(--dark-pink);
    font-family: 'Outfit', sans-serif;
    font-size: 1.55rem;
    font-weight: 700;
    line-height: 1.1;
}


/* ═══════════════════════════════════════════════════════════════════════
   9. BARRE DÉGRADÉE (allergène, comédogénicité)
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-bar {
    margin-top: 6px;
}

.ing-v3 .ing-v3-bar__track {
    position: relative;
    height: 8px;
    border-radius: 4px;
    background: linear-gradient(
        90deg,
        var(--primary-green),
        var(--warn-orange),
        var(--danger-red)
    );
    overflow: hidden;
}

/* Cap gris qui masque la partie au-delà du niveau (largeur en inline-style). */
.ing-v3 .ing-v3-bar__cap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    background: var(--ing-neutral-bg);
    border-radius: 0 4px 4px 0;
}

.ing-v3 .ing-v3-bar__meta {
    margin-top: 6px;
    display: flex;
    justify-content: space-between;
    color: var(--text-muted);
    font-size: 0.78rem;
}

.ing-v3 .ing-v3-bar__meta em {
    font-style: italic;
}


/* ═══════════════════════════════════════════════════════════════════════
   10. SUB-CARDS (origines possibles, types de peau, synergie/avoid)
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-subcards {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ing-v3 .ing-v3-subcard {
    padding: 12px 14px;
    background: var(--ing-subcard-bg);
    border: 1px solid var(--ing-subcard-border);
    border-radius: 10px;
}

.ing-v3 .ing-v3-subcard__head {
    margin-bottom: 4px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.ing-v3 .ing-v3-subcard__head h5 {
    margin: 0;
    color: var(--text-dark);
    font-family: 'Outfit', sans-serif;
    font-size: 0.88rem;
    font-weight: 700;
}

.ing-v3 .ing-v3-subcard__text {
    margin: 0;
    color: #555;
    font-size: 0.83rem;
    line-height: 1.5;
}


/* ═══════════════════════════════════════════════════════════════════════
   11. ROWS DE BADGES & CHIPS
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-badge-row {
    margin: 2px 0 6px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.ing-v3 .ing-v3-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}


/* ═══════════════════════════════════════════════════════════════════════
   12. PAIRS (synergie | avoid en split 2-col)
═══════════════════════════════════════════════════════════════════════ */

.ing-v3 .ing-v3-pairs {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}


/* ═══════════════════════════════════════════════════════════════════════
   14. RESPONSIVE — mobile (≤ 720 px)
═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
    .ing-v3 .ing-v3-mag,
    .ing-v3 .ing-v3-pairs,
    .ing-v3 .ing-v3-kpi-strip {
        grid-template-columns: 1fr;
    }
    .ingredient-card__body {
        padding: .6rem;
    }
    .ing-v3 .tab-pane {
        border-radius: 0 0px 12px 12px;
    } 
    .ing-v3 .ing-tabs__tab {
        padding: 11px 4px;
        gap: 4px;
        font-size: 0.70rem;
    }

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

    /* Pour très petits écrans, on peut masquer le texte des onglets
       et ne garder que l'icône. Désactivé par défaut, à activer si
       les libellés débordent. */
    /*
    @media (max-width: 480px) {
        .ing-v3 .ing-tabs__tab span { display: none; }
    }
    */
}
/* ═══════════════════════════════════════════════════════════════════════
 *  JAUGE DE CONCENTRATION (variante A — dot tracker sur graduation log)
 *
 *  À ajouter dans cosmelyse_ingredient_card.css ou intégrer si tu
 *  préfères tout regrouper. Branchée sur les vars globales de
 *  cosmelyse.css.
 *
 *  Markup attendu :
 *    <div class="ing-v3-conc">
 *        <div class="ing-v3-conc__track">
 *            <div class="ing-v3-conc__segment" style="left: X%; width: Y%;"></div>
 *            <div class="ing-v3-conc__dot ing-v3-conc__dot--min" style="left: X%;"></div>
 *            <div class="ing-v3-conc__dot ing-v3-conc__dot--max" style="left: X+Y%;"></div>
 *        </div>
 *        <div class="ing-v3-conc__ticks">…</div>
 *        <div class="ing-v3-conc__zones">…</div>
 *    </div>
 * ═══════════════════════════════════════════════════════════════════════ */
 
.ing-v3 .ing-v3-conc {
    margin: 8px 20px 15px;
}
 
/* Track : fine barre grise sur toute la largeur dispo */
.ing-v3 .ing-v3-conc__track {
    position: relative;
    height: 6px;
    background: rgba(0, 0, 0, 0.06);
    border-radius: 3px;
    /* margin-top pour laisser respirer après la valeur en gros */
    margin-top: 16px;
}
 
/* Segment coloré : la "plage" de l'ingrédient, rose dégradé */
.ing-v3 .ing-v3-conc__segment {
    position: absolute;
    top: 0;
    bottom: 0;
    background: linear-gradient(90deg, var(--primary-pink), var(--dark-pink));
    border-radius: 3px;
    /* min-width pour que les plages très étroites (ex. 1%–1%) restent visibles */
    min-width: 8px;
}
 
/* Pastilles min/max : centrées sur leur position via translate */
.ing-v3 .ing-v3-conc__dot {
    position: absolute;
    top: -2px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--dark-pink);
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px var(--dark-pink);
    transform: translateX(-50%);
}
 
/* Cas particulier : si une borne est manquante (≥ X % ou ≤ Y %),
   on n'affiche qu'une pastille avec un demi-segment vers le bord. */
.ing-v3 .ing-v3-conc__dot--solo {
    /* placeholder pour usage futur si besoin de différencier */
}
 
/* Ticks (graduation log) : 6 positions fixes 0,001 → 100 % */
.ing-v3 .ing-v3-conc__ticks {
    position: relative;
    height: 14px;
    margin-top: 6px;
}
.ing-v3 .ing-v3-conc__tick {
    position: absolute;
    transform: translateX(-50%);
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 600;
    white-space: nowrap;
}
.ing-v3 .ing-v3-conc__tick--major {
    color: var(--text-secondary);
}
 
/* Paliers d'usage (trace / actif / etc.) en italique sous les ticks */
.ing-v3 .ing-v3-conc__zones {
    position: relative;
    height: 14px;
    margin-top: 6px;
}
.ing-v3 .ing-v3-conc__zone {
    position: absolute;
    transform: translateX(-50%);
    color: var(--text-muted);
    font-size: 10.5px;
    font-style: italic;
    white-space: nowrap;
}
 
/* Variante "borne unique" : flèche vers la gauche ou la droite */
.ing-v3 .ing-v3-conc__bound-arrow {
    position: absolute;
    top: -3px;
    width: 0; height: 0;
    transform: translateX(-50%);
}
.ing-v3 .ing-v3-conc__bound-arrow--left {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-right: 8px solid var(--dark-pink);
}
.ing-v3 .ing-v3-conc__bound-arrow--right {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 8px solid var(--dark-pink);
}
 
/* Responsive : sur mobile, on garde la jauge mais les ticks
   intermédiaires peuvent gêner. Si nécessaire, masquer les ticks
   non-majeurs. */
@media (max-width: 480px) {
    .ing-v3 .ing-v3-conc__tick:not(.ing-v3-conc__tick--major) {
        display: none;
    }
}


/* ═══════════════════════════════════════════════════════════════════════
   3. HEADER V4 — summary grid, axes, fullname, sheet-link (ex-v4)
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
   CARTE INGRÉDIENT v4 — résumé « signal-first » (DÉFAUT EN PROD)

   La v4 est LA carte depuis 07/2026 (l'ancien switch ?cards= et le
   template pré-v4 ont été retirés). Cette section style les éléments
   ing4-* du résumé ; le corps (onglets, magazine, KPI) est stylé par
   les sections SOCLE et MAGAZINE de ce même fichier unique.

   Contrat visuel (identique à toutes les largeurs, AUCUN media query
   sur le résumé — rien ne bouge, jamais) :

       [badge]  NOM DE L'INGRÉDIENT                    [chevron]
                rôles · rôles
                [chips de signal]        ← seulement si signal

   Le badge de position porte le niveau de sécurité par sa FORME
   (bouclier / triangle / octogone / cercle) ET sa couleur : double
   codage, lisible par les daltoniens. Masques SVG → la couleur reste
   pilotée par les tokens de cosmelyse2.css. Zéro couleur en dur :
   les fonds translucides passent par color-mix().
   ═══════════════════════════════════════════════════════════════════════ */


/* ── 1. Racine : liseré gauche ── MIGRÉ vers .cosm-safety-rule ─────────
   (cf. note de la section SOCLE — classes posées au markup). */


/* ── 2. Résumé : grille rigide 2 lignes ────────────────────────────── */

.ing4-head {
    list-style: none;
    cursor: pointer;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "pos   id    chev"
        "chips chips chips";
    align-items: center;
    column-gap: 0.75rem;
    padding: 0.7rem 0.9rem;
    min-height: 56px;               /* cible tactile */
    -webkit-tap-highlight-color: transparent;
}
.ing4-head::marker,
.ing4-head::-webkit-details-marker { display: none; content: none; }
.ing4-head:focus-visible {
    outline: 2px solid var(--dark-pink);
    outline-offset: -2px;
    border-radius: 12px;
}


/* ── 3. Badge de position : la forme = le niveau ───────────────────── */

.ing4-head__pos {
    grid-area: pos;
    width: 32px;
    height: 32px;
    background: var(--primary-green);
    color: #fff;
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.72rem;
    display: grid;
    place-items: center;
    /* Bouclier (défaut = sûr) */
    -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 1 L21 4.5 V11 C21 17.2 17.2 21.6 12 23 C6.8 21.6 3 17.2 3 11 V4.5 Z"/></svg>') center / contain no-repeat;
    mask:         url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 1 L21 4.5 V11 C21 17.2 17.2 21.6 12 23 C6.8 21.6 3 17.2 3 11 V4.5 Z"/></svg>') center / contain no-repeat;
    padding-bottom: 3px;            /* recentre le n° (pointe basse) */
}

/* Triangle (prudence) — le n° descend dans la base */
.ingredient-card--watch .ing4-head__pos {
    background: var(--warn-orange);
    -webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2 L23 21 H1 Z" stroke="black" stroke-width="3" stroke-linejoin="round" fill="black"/></svg>');
    mask-image:         url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2 L23 21 H1 Z" stroke="black" stroke-width="3" stroke-linejoin="round" fill="black"/></svg>');
    padding-bottom: 0;
    padding-top: 8px;
    font-size: 0.66rem;
}

/* Octogone (à éviter / signal fort) */
.ingredient-card--avoid .ing4-head__pos {
    background: var(--danger-red);
    -webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.5 1 H16.5 L23 7.5 V16.5 L16.5 23 H7.5 L1 16.5 V7.5 Z"/></svg>');
    mask-image:         url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.5 1 H16.5 L23 7.5 V16.5 L16.5 23 H7.5 L1 16.5 V7.5 Z"/></svg>');
    padding-bottom: 0;
}

/* Cercle (non évalué / fiche en cours) */
.ingredient-card--unrated .ing4-head__pos {
    background: var(--text-hint);
    -webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11"/></svg>');
    mask-image:         url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11"/></svg>');
    padding-bottom: 0;
}


/* ── 4. Identité : nom puis rôles, empilés, ellipse si étroit ──────── */

.ing4-head__id {
    grid-area: id;
    min-width: 0;
}
.ing4-head__name {
    display: block;
    /* CONTRAT — bloc conteneur des textes a11y : le titre héberge des
       <span class="visually-hidden"> (position:absolute, Bootstrap).
       Un absolu n'est clippé par l'overflow:hidden d'un ancêtre QUE si
       cet ancêtre appartient à sa chaîne de blocs conteneurs. Sans
       position ici, le bloc conteneur des spans est .cosm-card
       (relative) : ils échappent au clip du titre, se placent à leur
       position statique — la fin du TEXTE COMPLET non tronqué — et
       étendent le scrollable overflow → seul scroll horizontal du site
       (Chrome, +196px mesurés sur un nom long). position:relative fait
       du titre leur bloc conteneur : son overflow:hidden les clippe.
       Règle générale : tout conteneur ellipsé hébergeant des
       .visually-hidden doit être position:relative. */
    position: relative;
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    color: var(--text-dark);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ing4-head__roles {
    display: block;
    font-size: 0.76rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 0.05rem;
}


/* ── 5. Chevron ────────────────────────────────────────────────────── */

.ing4-head__chev {
    grid-area: chev;
    color: var(--text-hint);
    transition: transform 0.2s ease;
}
.ing-v4[open] .ing4-head__chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
    .ing4-head__chev { transition: none; }
}


/* ── 6. Chips de signal : ligne 2, uniquement si non neutre ────────── */

.ing4-head__chips {
    grid-area: chips;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.45rem;
}
.ing4-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.74rem;
    font-weight: 500;
    padding: 0.22rem 0.55rem;
    border-radius: 999px;
    white-space: nowrap;
}
.ing4-chip--watch {
    background: color-mix(in srgb, var(--warn-orange) 13%, transparent);
    color: var(--dark-gold);
}
.ing4-chip--avoid {
    background: color-mix(in srgb, var(--danger-red) 12%, transparent);
    color: var(--danger-red);
}
.ing4-chip--neutral {
    background: color-mix(in srgb, var(--text-muted) 10%, transparent);
    color: var(--text-secondary);
}


/* ── 7. Axes compacts : le neutre complet, sous le pli ─────────────── */
/* Rendu en tête du body v4, au-dessus des onglets base/v3.            */

.ing4-axes {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.4rem;
    margin-bottom: 0.9rem;
    /* Parité post-retrait du flex body : en flex item, la grille était
       compressée à son contenu (rendu compact historique, validé en
       prod). En flux block elle s'étirerait à 100 % — on fige donc le
       compact explicitement. max-width borne le mobile (3×2). */
    width: max-content;
    max-width: 100%;
}
.ing4-axes__item {
    background: color-mix(in srgb, var(--sand-light) 45%, transparent);
    border-radius: 8px;
    padding: 0.45rem 0.3rem;
    text-align: center;
}
.ing4-axes__val {
    display: block;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-dark);
}
.ing4-axes__val::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 0.3rem;
    background: var(--text-hint);
    vertical-align: 1px;
}
.ing4-axes__item--good  .ing4-axes__val::before { background: var(--primary-green); }
.ing4-axes__item--watch .ing4-axes__val::before { background: var(--warn-orange);   }
.ing4-axes__item--avoid .ing4-axes__val::before { background: var(--danger-red);    }
.ing4-axes__lbl {
    display: block;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin-top: 0.1rem;
}

/* ── Nom complet, jamais tronqué (lot F) ────────────────────────────────
   Le titre (.ing4-head__name) est ellipsé : sur un nom long,
   l'utilisateur perd l'identité de l'ingrédient. Cette ligne, en tête
   du corps (avant la note descriptive, présente même sans note), donne
   l'INCI intégral suivi du nom d'affichage quand il diffère.
   CONTRAT anti-débordement : texte JAMAIS tronqué — doit replier, y
   compris un INCI sans espaces. Aucun white-space:nowrap ici, jamais
   (cf. traque scroll 08/2026). */

.ing4-fullname {
    margin: 0 0 10px;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--text-dark);
    overflow-wrap: anywhere;
}

.ing4-fullname__inci {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.ing4-fullname__fr {
    color: var(--text-muted, #888);
    font-weight: 500;
}

/* ── Onglets internes : radios EN FLUX, 0×0 ─────────────────────────────
   Technique de masquage retenue : en flux, juste avant le tabset dans
   l'ordre DOM, le focus au clic d'un label reste au niveau des onglets
   quel que soit le display du parent (l'ancien body FLEX téléportait
   la position statique des absolute en haut de la card — retiré
   08/2026, le body est redevenu block ; la règle reste comme
   robustesse). opacity:0 et pointer-events:none hérités du socle/v3. */

.ing-v4 .ing-tabs__radio {
    display: block;
    position: static;
    width: 0;
    height: 0;
    margin: 0;
    appearance: none;
    -webkit-appearance: none;
}

/* ── Action « fiche complète » du panneau Fiche (lot F) ─────────────────
   Le lien active l'onglet à lui seul (cf. $hasSheetTab côté template) :
   dès qu'un ingrédient existe en base, sa fiche unitaire est à un tap. */

.ing4-sheet-link {
    /* Le conteneur .ing-v3-mag est une GRID 2 colonnes : sans étendre
       l'item sur les deux, le lien occupait une demi-cellule et son
       flex-end le poussait vers le centre de la card. */
    grid-column: 1 / -1;
    display: flex;
    justify-content: flex-end;
    margin-top: 4px;
}

/* Seuil canonique uniquement (768) : 6 axes → grille 3×2 */
@media (max-width: 767.98px) {
    .ing4-axes { grid-template-columns: repeat(3, 1fr); }
}
