/* ╔═══════════════════════════════════════════════════════════════════════╗
   ║  Cosmélyse V2 — cosmelyse.css                                         ║
   ║  CSS principal : variables + base                                     ║
   ╚═══════════════════════════════════════════════════════════════════════╝

   Compatible Bootstrap 5.3.x.
   Charger APRÈS bootstrap.css.

   ─── Architecture des variables ───────────────────────────────────────

   Toutes les couleurs et tokens visuels du projet sont centralisés ici
   dans :root. Les autres fichiers CSS (navbar, footer, futurs composants)
   ne définissent JAMAIS de couleur en dur — ils consomment ces variables.
   C'est la condition pour pouvoir faire évoluer la charte sans relire
   tout le code.

     --primary-pink         Rose principal (boutons primaires, gradients,
                            accents header)
     --secondary-pink       Rose clair (variantes, états hover doux)
     --dark-pink            Rose foncé (fin de gradient, hover boutons)
     --danger-red           Rouge erreur

     --primary-green        Vert principal (boutons secondaires, accents)
     --dark-green           Vert clair
     --darker-green         Vert foncé

     --cream                Crème de fond de page
     --text-dark            Texte principal
     --info-blue            Bleu info
     --gold-accent          Or accent
     --warn-orange          Orange warn (badges "à clarifier", chips
                            warn, bordures de carte d'arbitrage)
*/


/* ============================================
   1. :ROOT VARIABLES
   ============================================ */

:root {
    /* Roses */
    --primary-pink:   #ff6b9d;
    --secondary-pink: #ff9cbd;
    --dark-pink:      #e91e63;
    --danger-red:     #e74c3c;

    /* Verts */
    --primary-green:  #8fb569;
    --dark-green:     #a4c486;
    --darker-green:   #6ca039;

    /* Neutres — accents */
    --cream:          #fef9f3;
    --text-dark:      #2c2c2c;
    --info-blue:      #5DADE2;
    --gold-accent:    #d4af37;
    --warn-orange:    #f39c12;
    --dark-gold:      #a8851a;
    /* Sand — palette des bandeaux de cards (Salve F) */
    --sand-light:     #f0e3cd;
    --sand-dark:      #d8c4a3;
    --sand-text:      #6b5535;

    /* Neutres — texte (échelle de gris du plus foncé au plus clair).
       Toutes les valeurs proches (ex : #777 vs #888) sont volontairement
       distinctes : elles permettent une hiérarchie visuelle subtile entre
       texte secondaire, texte descriptif/lead et texte sourd. Voir
       cosmelyse2.css §1 (commentaires d'origine) avant de fusionner. */
    --text-secondary: #666;   /* texte secondaire (sections, headers neutres)  */
    --text-soft:      #777;   /* texte descriptif/lead (descriptions courtes)  */
    --text-muted:     #888;   /* texte sourd (annotations, micro-meta)         */
    --text-hint:      #999;   /* hint, placeholder, label calé                 */
    --text-disabled:  #aaa;   /* texte/icône désactivé, état neutre absolu     */

    /* Neutres — backgrounds & bordures */
    --bg-soft:        #fafafa; /* fond très clair (cards alternées, blocs)     */
    --border-default: #e8e8e8; /* bordures discrètes (inputs, séparateurs)
                                  Fusion historique de #e5e5e5/#e8e8e8/#eaeaea
                                  (écart imperceptible sur bordure 1px).       */
    --border-strong:  #e0e0e0; /* bordures structurelles (stepper, chips,
                                  cards interactives) — plus visibles que
                                  --border-default malgré la nuance subtile.   */

    /* Liens — base globale (règles en §2 BASE & BODY). #d81b60 plutôt
       que --dark-pink (#e91e63) : même famille rose, mais contraste AA
       sur fond blanc/crème (4.97:1 vs 4.36:1 — seuil WCAG 4.5:1).
       Le hover intensifie (jamais plus clair que la base). */
    --link-color:     #d81b60;
    --link-hover:     #ad1457;
}


/* ============================================
   2. BASE & BODY
   ============================================ */

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'DM Sans', sans-serif;
    background: var(--cream);
    color: var(--text-dark);
    position: relative;
    overflow-x: hidden;
}

/* ─── Liens — base globale ──────────────────────────────────────────
   Sans cette règle, les <a> nus héritent du bleu Bootstrap (#0d6efd),
   hors charte. On aligne sur la palette rose : soulignement fin et
   atténué qui s'intensifie au hover — l'affordance lien reste marquée
   (le rose est proche du seuil de contraste, le soulignement compense),
   le rendu reste doux, cohérent avec l'esthétique sable/arrondi.

   Périmètre : uniquement les ancres NON stylées par un composant.
   Les règles composant existantes (.footer-links a, .cosm-breadcrumb a,
   .btn — Bootstrap définit .btn:hover, spécificité (0,2,0) > a:hover —,
   .cosm-tile, navbar, dropdowns…) gagnent par spécificité : aucune
   retouche nécessaire. cosmelyse2.css est chargé APRÈS bootstrap.css
   (cf. _head.php) → cette règle gagne sur les ancres nues à
   spécificité égale. L'admin ne charge pas les CSS front : non
   concerné. */

a {
    color: var(--link-color);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    text-decoration-color: color-mix(in srgb, var(--link-color) 35%, transparent);
    transition: color 0.15s ease, text-decoration-color 0.15s ease;
}

a:hover {
    color: var(--link-hover);
    text-decoration-color: currentColor;
}

/* Focus clavier — anneau charte plutôt que l'outline navigateur.
   :focus-visible uniquement : pas de style résiduel après un clic. */
a:focus-visible {
    outline: 2px solid var(--primary-pink);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Conteneur principal qui englobe le contenu d'une page entre navbar
   et footer. Utilisé par index.php (home) — d'autres pages le réutiliseront. */
.main-container {
    position: relative;
    z-index: 1;
    padding: 2rem 0 1rem 0;
}


/* ============================================
   3. HOME — HERO
   ============================================ */

.center-wrapper {
    text-align: center;
    margin: 0 auto;
}

.hero-title {
    font-family: 'Outfit', sans-serif;
    font-size: 3.5rem;
    font-weight: 800;
    color: var(--text-dark);
    margin-bottom: 1.5rem;
    line-height: 1.2;
    animation: fadeInUp 0.8s ease-out 0.2s backwards;
}

.hero-title .gradient-text {
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.hero-subtitle {
    font-size: 1.3rem;
    color: #666;
    margin-bottom: 3rem;
    animation: fadeInUp 0.8s ease-out 0.4s backwards;
}


/* ============================================
   4. HOME — FLOATING-CARD (carte centrale)
   ============================================ */

.floating-card {
    background: white;
    border-radius: 12px;
    padding: 1.5rem;
    box-shadow: 0 2px 16px rgba(0, 0, 0, .07), 0 0 0 1px rgba(255, 107, 157, .08);
    animation: fadeInUp 0.8s ease-out 0.6s backwards;
    position: relative;
    border-top: 3px solid var(--primary-pink);
}

.floating-card h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 1.25rem;
    font-weight: bold;
}


/* ============================================
   5. HOME — TUILES (Photographier / Copier-Coller / Comparer)
   ============================================ */

.tabs-beautiful {
    display: flex;
    gap: 1.5rem;
    margin-bottom: 2rem;
}

.tab-item {
    flex: 1;
    padding: 1.5rem;
    border-radius: 8px;
    border: 2px solid rgba(255, 107, 157, 0.2);
    background: white;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
    text-align: center;
}

.tab-item:hover {
    border-color: var(--primary-pink);
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(255, 107, 157, .12);
}

.tab-item.active {
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    border-color: var(--dark-pink);
    color: white;
    transform: none;
    box-shadow: 0 6px 24px rgba(255, 107, 157, .25);
}

.tab-item.active .tab-icon {
    background: rgba(255, 255, 255, 0.2);
    color: white;
}

.tab-item.active .tab-desc {
    opacity: 1;
}

.tab-icon {
    width: 56px;
    height: 56px;
    margin: 0 auto 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    background: linear-gradient(135deg, rgba(255, 107, 157, 0.1), rgba(233, 30, 99, 0.1));
    border-radius: 50%;
    transition: all 0.3s ease;
}

.tab-title {
    font-weight: 700;
    font-size: 1.1rem;
    margin-bottom: 0.5rem;
}

.tab-desc {
    font-size: 0.9rem;
    opacity: 0.8;
}


/* ============================================
   6. HOME — ZONES D'INPUT (photo / text / compare)
   ============================================ */

.input-zone {
    background: rgba(143, 181, 105, 0.05);
    border: 2px dashed rgba(143, 181, 105, 0.3);
    border-radius: 12px;
    padding: 2rem 1.5rem;
    margin-bottom: 2rem;
    transition: all 0.3s ease;
}

.input-zone:hover {
    border-color: var(--primary-green);
    background: rgba(143, 181, 105, 0.08);
}

.input-placeholder {
    text-align: center;
}

.input-placeholder i {
    font-size: 4rem;
    color: var(--primary-green);
    margin-bottom: 1rem;
    opacity: 0.6;
}

.input-placeholder h4 {
    font-weight: 700;
    color: var(--text-dark);
    margin-bottom: 0.5rem;
}

.input-placeholder p {
    color: #666;
    margin: 0;
}

/* Compteur de caractères sous les textareas */
.char-counter {
    color: #888;
    font-size: 0.85rem;
    margin-top: 0.5rem;
}

.char-counter i {
    margin-right: 0.25rem;
    opacity: 0.7;
}


/* ============================================
   7. HOME — BOUTONS D'ACTION (Cosmélyser / Recommencer)
   ============================================ */

.action-buttons {
    display: flex;
    gap: 1rem;
}

.btn-primary-gradient {
    flex: 3;
    padding: 1.3rem;
    font-size: 1.2rem;
    font-weight: 700;
    border-radius: 10px;
    border: none;
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    color: white;
    box-shadow: 0 6px 20px rgba(255, 107, 157, .2);
    transition: all 0.3s ease;
    cursor: pointer;
}

.btn-primary-gradient:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(255, 107, 157, .25);
}

.btn-secondary-outline {
    flex: 1;
    padding: 1.3rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 10px;
    border: 2px solid var(--primary-green);
    background: white;
    color: var(--primary-green);
    transition: all 0.3s ease;
    cursor: pointer;
}

.btn-secondary-outline:hover {
    background: var(--primary-green);
    color: white;
    transform: none;
}


/* ============================================
   8. HOME — FEATURES ROW (3 icônes vertes en bas)
   ============================================ */

.features-row {
    display: flex;
    gap: 2rem;
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
}

.feature-item {
    flex: 1;
    text-align: center;
}

.feature-icon {
    width: 60px;
    height: 60px;
    margin: 0 auto 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.8rem;
    background: linear-gradient(135deg, rgba(143, 181, 105, 0.15), rgba(164, 196, 134, 0.15));
    border-radius: 50%;
    color: var(--primary-green);
}

.feature-title {
    font-weight: 700;
    font-size: 1rem;
    margin-bottom: 0.3rem;
    color: var(--text-dark);
}

.feature-text {
    font-size: 0.85rem;
    color: #666;
}


/* ============================================
   9. HOME — FLASH MESSAGES (depuis Session::flash)
   ============================================ */

.flash {
    padding: 1em 1.2em;
    border-radius: 8px;
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}

.flash i {
    flex-shrink: 0;
}

.flash--error {
    background: rgba(231, 76, 60, 0.08);
    color: #8a2a1f;
    border-left: 4px solid var(--danger-red);
}

.flash--info {
    background: rgba(93, 173, 226, 0.08);
    color: #1c5980;
    border-left: 4px solid var(--info-blue);
}


.flash--info {
    background: rgba(93, 173, 226, 0.08);
    color: #1c5980;
    border-left: 4px solid var(--info-blue);
}

.flash--success {
    background: rgba(143, 181, 105, 0.08);
    border-left: 4px solid var(--primary-green);
    color: #3d5e1f;
}


/* ============================================
   10. ANIMATIONS
   ============================================ */

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


/* ============================================
   11. RESPONSIVE
   ============================================ */

@media (max-width: 991px) {
    .hero-title {
        font-size: 2.5rem;
    }

    .hero-subtitle {
        font-size: 1.1rem;
        margin-bottom: 2rem;
    }

    .tabs-beautiful {
        flex-direction: column;
        gap: 1rem;
    }

    .features-row {
        flex-direction: column;
        gap: 1.5rem;
    }
}

@media (max-width: 576px) {
    .hero-title {
        font-size: 2rem;
    }

    .floating-card {
        padding: 1rem;
    }

    .action-buttons {
        flex-direction: column;
    }

    .btn-primary-gradient,
    .btn-secondary-outline {
        flex: 1 1 auto;
        width: 100%;
    }
}


/* ============================================
   12. COMPOSANTS GÉNÉRIQUES RÉUTILISABLES
   ============================================
   
   Briques visuelles consommables par n'importe quelle page V2 :
   pas de classe spécifique à un écran ici. Le préfixe `.cosm-`
   évite les collisions avec Bootstrap et avec les classes legacy.
   
   Si une page a besoin d'une variante très spécifique, elle
   *étend* via un modifier (`.cosm-XXX--variant`) plutôt que
   de redéfinir.
*/


/* ── 12.1 Page header (badge pilule + titre + sous-titre) ──
   Pattern utilisé sur confirmer.php, et destiné aux futures
   pages transientes (compare, étapes d'inscription, etc.).
   Marqueurs : <div class="cosm-page-header">
                  <span class="cosm-page-header__badge">…</span>
                  <h1 class="cosm-page-header__title">…</h1>
                  <p  class="cosm-page-header__lead">…</p>
               </div>
*/
.cosm-page-header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.cosm-page-header__badge {
    display: inline-block;
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    color: #fff;
    padding: 0.4rem 1rem;
    border-radius: 100px;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    box-shadow: 0 4px 12px rgba(233, 30, 99, 0.25);
    margin-bottom: 1rem;
}

.cosm-page-header__title {
    font-family: 'Outfit', sans-serif;
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.25;
    margin-bottom: 0.5rem;
    color: var(--text-dark);
}

.cosm-page-header__title .gradient-text {
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.cosm-page-header__lead {
    color: #666;
    max-width: 540px;
    margin: 0 auto;
    font-size: 1.02rem;
}


/* ── 12.2 Pills (chips compteurs colorés) ──
   Petite pastille avec puce colorée à gauche. 4 variantes
   sémantiques. Utilisable pour stats, status, tags légers.
*/
.cosm-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: #fff;
    padding: 0.45rem 0.95rem;
    border-radius: 100px;
    font-size: 0.85rem;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.cosm-pill__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-block;
}

.cosm-pill--ok       { color: var(--darker-green);     }
.cosm-pill--ok       .cosm-pill__dot { background: var(--primary-green); }

.cosm-pill--warn     { color: var(--warn-orange);      }
.cosm-pill--warn     .cosm-pill__dot { background: var(--warn-orange);  }

.cosm-pill--danger   { color: var(--danger-red);       }
.cosm-pill--danger   .cosm-pill__dot { background: var(--danger-red);   }

.cosm-pill--info     { color: var(--info-blue);        }
.cosm-pill--info     .cosm-pill__dot { background: var(--info-blue);    }

.cosm-pill--neutral  { color: #888;                    }
.cosm-pill--neutral  .cosm-pill__dot { background: #bbb;                }


/* Rangée de pills (ou de chips) horizontale, centrée, qui wrap sur mobile.
   Utilisée typiquement pour des compteurs de stats sous un page-header. */
.cosm-stats-row {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}


/* ── 12.3 Card (conteneur de section sur fond crème) ──
   Carte blanche arrondie, base de toute zone de contenu.
   Variantes :
   - --warn : cartes d'arbitrage / avertissement (bordure orange)
   - --info : cartes d'information / action réussie (bordure bleue)
*/
.cosm-card {
    background: #fff;
    border-radius: 16px;
    padding: 1.5rem;
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(0, 0, 0, 0.09);
    margin-bottom: 1rem;
    position: relative;
}

.cosm-card--warn {
    border: 2px solid var(--warn-orange);
    box-shadow: 0 4px 20px rgba(243, 156, 18, 0.12);
}

.cosm-card--info {
    border: 2px solid var(--info-blue);
    box-shadow: 0 4px 20px rgba(93, 173, 226, 0.12);
}


/* ── 12.4 Card avec bandeau d'en-tête (Salve F) ──
   Pattern réutilisable :
       <section class="cosm-card">
           <header class="cosm-card__header">
               <h3 class="cosm-card__title">
                   <i class="bi bi-..."></i> Titre
               </h3>
           </header>
           <div class="cosm-card__body">
               [contenu]
           </div>
       </section>

   Variantes du __header :
       (par défaut)        sand — neutre, à utiliser pour toutes les cards
                                 d'information (Notation, Stats, Reco…)
       --pink              gradient rose Cosmélyse — réservé aux contenus
                                 à forte valeur narrative (Synthèse IA).
                                 Le contraste rose vs sand crée une
                                 hiérarchie visuelle claire.

   Quand un .cosm-card contient un __header, on annule son padding
   par défaut (1.5rem) — le padding est géré par __body. :has() est
   supporté par tous les navigateurs modernes (Chrome 105+, Safari 15.4+,
   Firefox 121+) ; aucun fallback nécessaire pour notre cible 2026.
*/
.cosm-card:has(> .cosm-card__header) {
    padding: 0;
    /* Pas d'overflow:hidden : peut casser le scroll Chrome dans certains
       cas (notamment avec position:sticky d'un ancêtre, c'est dans la spec).
       Le border-radius 16px de .cosm-card et le border-radius 16px 16px 0 0
       du __header suffisent à arrondir les coins visuellement. */
}

.cosm-card__header {
    background: linear-gradient(135deg, var(--sand-light), var(--sand-dark));
    padding: 0.875rem 1.5rem;
    border-radius: 16px 16px 0 0; /* aligné avec .cosm-card border-radius */
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.cosm-card__header--pink {
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
}

.cosm-card__title {
    margin: 0;
    color: var(--sand-text);
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 1.15rem;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    letter-spacing: 0.01em;
}

.cosm-card__header--pink .cosm-card__title {
    color: #fff;
}

.cosm-card__title i {
    font-size: 1.05rem;
    opacity: 0.9;
    color: inherit; /* hérite du title — sand-text par défaut, blanc en --pink */
}

.cosm-card__body {
    padding: 1.5rem;
}


/* ============================================
   13. BREADCRUMB (.cosm-breadcrumb)
   ============================================

   Fil d'Ariane standard de toutes les pages internes. Composant
   sous forme de "pilule" arrondie, blanche, avec ombre douce.
   Compose avec un <nav aria-label="Fil d'Ariane"> parent purement
   sémantique : le <nav> n'est pas stylé, c'est le <div> enfant qui
   porte les styles.

   Markup attendu :
     <nav aria-label="Fil d'Ariane">
         <div class="cosm-breadcrumb">
             <a href="index.php"><i class="bi bi-house-fill"></i>CosmÉlyse</a>
             <span class="cosm-breadcrumb__sep"><i class="bi bi-chevron-right"></i></span>
             <span class="cosm-breadcrumb__current">Page courante</span>
         </div>
     </nav>

   Présent sur : confirmer, recherche, result, ingredient, compare.
*/

.cosm-breadcrumb {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.95rem;
    background: #fff;
    border-radius: 100px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
    font-size: 0.85rem;
    margin-bottom: 1rem;
}

.cosm-breadcrumb a {
    color: var(--primary-pink);
    text-decoration: none;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.cosm-breadcrumb a:hover {
    color: var(--dark-pink);
}

.cosm-breadcrumb__sep {
    color: #ccc;
    font-size: 0.7rem;
    line-height: 1;
}

.cosm-breadcrumb__current {
    color: var(--text-dark);
    font-weight: 600;
}

/* Responsive : sur mobile, on resserre légèrement la pilule. */
@media (max-width: 575.98px) {
    .cosm-breadcrumb {
        font-size: 0.78rem;
        padding: 0.35rem 0.75rem;
    }
}


/* ============================================
   13b. COSM-TILE — mini-card cliquable générique
   ============================================

   Tile blanche cliquable, fond léger, ombre douce, hover qui soulève
   et fait apparaître une bordure rose subtile. Pattern unifié pour les
   listes d'éléments cliquables : résultats de recherche, produits du
   catalogue, partenaires beauté, items d'historique, etc.

   Markup attendu :
       <a href="..." class="cosm-tile search-card">
           ...sous-éléments spécifiques à la page...
       </a>

   La double classe est volontaire : .cosm-tile fournit le squelette
   (fond, bordure, ombre, transitions, hover), .search-card / .product-card /
   .rdv-card / .history-item ajoutent leurs spécificités (padding, layout
   interne, sous-éléments BEM).

   Variants :
     (par défaut)   tile interactive en column, hover translateY(-3px)
     --row          tile horizontale (sans translateY au hover, juste
                    bordure + ombre — plus calme pour un item de liste
                    informatif comme .history-item)
*/

.cosm-tile {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.07);
    border-radius: 14px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
    text-decoration: none;
    color: var(--text-dark);
    transition: transform 0.18s ease,
                box-shadow 0.18s ease,
                border-color 0.18s ease;
}

.cosm-tile:hover,
.cosm-tile:focus {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    border-color: rgba(255, 107, 157, 0.25);
    color: var(--text-dark);
    text-decoration: none;
}

/* Variante "row" : tile horizontale plus calme. Pas de translateY,
   juste un retour de bordure + ombre légèrement marquée au hover.
   Utilisée pour des listes d'items informatifs (ex: historique). */
.cosm-tile--row {
    flex-direction: row;
    align-items: center;
}

.cosm-tile--row:hover,
.cosm-tile--row:focus {
    transform: none;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
}


/* ============================================
   14. ACCORDION (composant générique)
   ============================================
   
   Bloc déplié/replié basé sur <details>/<summary> natifs HTML
   (zéro JS). Utilisé sur la page result pour "Comparer une autre
   formule", et destiné à servir aussi pour les cards d'ingrédient
   et autres blocs déroulants.
   
   Markup attendu :
     <details class="cosm-accordion">
        <summary class="cosm-accordion__head">
           <i class="bi bi-XXX cosm-accordion__icon"></i>
           <span class="cosm-accordion__title">Titre</span>
           <i class="bi bi-chevron-down cosm-accordion__chevron"></i>
        </summary>
        <div class="cosm-accordion__body">…</div>
     </details>
*/

.cosm-accordion {
    background: #fff;
    border-radius: 12px;
    border: 1px solid rgba(0, 0, 0, 0.04);
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.05);
    margin-bottom: 1rem;
    overflow: hidden;
}

.cosm-accordion__head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    cursor: pointer;
    list-style: none;
    user-select: none;
    font-weight: 600;
    transition: background-color 0.15s ease;
}

.cosm-accordion__head::-webkit-details-marker {
    display: none;
}

.cosm-accordion__head:hover {
    background: rgba(255, 107, 157, 0.04);
}

.cosm-accordion__icon {
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 107, 157, 0.1);
    color: var(--primary-pink);
    border-radius: 50%;
    flex-shrink: 0;
}

.cosm-accordion__title {
    flex: 1;
    text-transform: uppercase;
    font-size: 0.95rem;
    letter-spacing: 0.04em;
    color: var(--text-dark);
}

.cosm-accordion__chevron {
    color: var(--primary-pink);
    transition: transform 0.2s ease;
    flex-shrink: 0;
}

.cosm-accordion[open] .cosm-accordion__chevron {
    transform: rotate(180deg);
}

.cosm-accordion__body {
    padding: 0 1.25rem 1.25rem;
    border-top: 1px solid rgba(0, 0, 0, 0.04);
    padding-top: 1.25rem;
}


/* ============================================
   15. CHIP (composant générique)
   ============================================
   
   Petite étiquette inline pour qualificatifs courts (rôle, catégorie,
   propriété, tag). Utilisée sur la page result pour les rôles
   d'ingrédient ("émollient", "lubrifiant"...) — réutilisable partout.
   
   Distinction avec .cosm-pill : 
     - .cosm-pill   = compteur/statut, avec point coloré, plus large
     - .cosm-chip   = étiquette inline sobre, plus petite, sans point
*/

.cosm-chip {
    display: inline-block;
    padding: 0.18rem 0.55rem;
    background: rgba(0, 0, 0, 0.04);
    color: #555;
    border-radius: 100px;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
}

.cosm-chip--rose    { background: rgba(255, 107, 157, 0.1); color: var(--dark-pink);     }
.cosm-chip--green   { background: rgba(143, 181, 105, 0.1); color: var(--darker-green);  }
.cosm-chip--orange  { background: rgba(243, 156, 18, 0.12); color: #b67209;              }
.cosm-chip--red     { background: rgba(231, 76, 60, 0.12);  color: #a52d22;              }
.cosm-chip--blue    { background: rgba(93, 173, 226, 0.12); color: #1c5980;              }


/* Rangée de chips horizontale, qui wrap. */
.cosm-chips-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

/* Chip cliquable (<a class="cosm-chip ...">).
   Neutralise le style lien de base (§2 BASE & BODY) : la forme
   "étiquette" porte déjà l'affordance, le soulignement serait du
   bruit. Padding légèrement augmenté (cible tactile). Hover déclaré
   par variante, au cas par cas — seule --rose sert de lien à ce jour
   (maillage fiches ingrédients, home). */
a.cosm-chip {
    text-decoration: none;
    padding: 0.3rem 0.7rem;
    transition: background-color 0.15s ease, color 0.15s ease;
}

a.cosm-chip.cosm-chip--rose:hover {
    background: rgba(255, 107, 157, 0.2);
    color: var(--dark-pink);
}


/* ============================================
   16. BADGE (composant générique)
   ============================================
   
   Étiquette plus visible que .cosm-chip, avec icône optionnelle
   et 6 variantes sémantiques. Utilisé pour des QUALIFICATIONS
   précises ("Faible", "Modéré", "Interdit", "COSMOS Natural"...).
   
   Distinction avec .cosm-chip :
     - .cosm-chip   = tag inline neutre (rôle, catégorie)
     - .cosm-badge  = qualification sémantique (statut, niveau)
*/

.cosm-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.7rem;
    border-radius: 100px;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.3;
    background: rgba(0, 0, 0, 0.05);
    color: var(--text-dark);
    white-space: nowrap;
}

.cosm-badge i {
    font-size: 0.85rem;
}

.cosm-badge--success { background: rgba(143, 181, 105, 0.15); color: var(--darker-green); }
.cosm-badge--warning { background: rgba(243, 156, 18, 0.15);  color: #b67209;             }
.cosm-badge--danger  { background: rgba(231, 76, 60, 0.12);   color: #a52d22;             }
.cosm-badge--info    { background: rgba(93, 173, 226, 0.15);  color: #1c5980;             }
.cosm-badge--neutral { background: rgba(0, 0, 0, 0.06);       color: #666;                }
.cosm-badge--dark    { background: var(--text-dark);          color: #fff;                }


/* ============================================
   17. GAUGE (composant générique)
   ============================================
   
   Petite jauge horizontale graduée. Utilisée pour visualiser un
   niveau (allergène 0-3, comédogénicité 0-5, etc.).
   Le caller pose --level (0..1) en variable CSS pour piloter le fill.
   
   Exemple :
     <div class="cosm-gauge" style="--level: 0.6;">
        <div class="cosm-gauge__track"><div class="cosm-gauge__fill"></div></div>
        <span class="cosm-gauge__val">3/5</span>
     </div>
*/

.cosm-gauge {
    --level: 0;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.4rem 0;
}

.cosm-gauge__track {
    flex: 1;
    height: 8px;
    background: rgba(0, 0, 0, 0.06);
    border-radius: 99px;
    overflow: hidden;
    min-width: 80px;
}

.cosm-gauge__fill {
    height: 100%;
    width: calc(var(--level) * 100%);
    border-radius: 99px;
    /* Gradient sémantique : vert → orange → rouge selon le niveau */
    background: linear-gradient(90deg,
        var(--primary-green)  0%,
        var(--primary-green) 33%,
        var(--warn-orange)   50%,
        var(--warn-orange)   66%,
        var(--danger-red)    85%,
        var(--danger-red)   100%);
    background-size: calc(100% / var(--level, 1)) 100%;
    transition: width 0.6s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.cosm-gauge__val {
    font-family: 'Outfit', sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--text-dark);
    min-width: 32px;
    text-align: right;
}


/* ============================================
   18. LOADER SPINNER (composant générique)
   ============================================
   
   Petit spinner animé (rotation 0.8s linear infinite) pour signaler
   un chargement en cours. Utilisé sur la page result pour les cards
   d'ingrédient en cours d'enrichissement IA, mais réutilisable partout.
   
   Markup : <span class="cosm-loader-spinner" aria-hidden="true"></span>
*/

.cosm-loader-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    vertical-align: middle;
    flex-shrink: 0;
    animation: cosmSpin 0.8s linear infinite;
}

@keyframes cosmSpin {
    to { transform: rotate(360deg); }
}


/* ============================================
   19. OCR (page d'accueil — onglet Photographier)
   ============================================
   
   Composants spécifiques au flow OCR :
   - .ocr-placeholder      → état initial cliquable (existe déjà via
                              .input-placeholder, on pose juste un cursor)
   - .ocr-gallery          → conteneur visible quand 1+ photo sélectionnée
   - .ocr-thumbs           → rangée horizontale des thumbnails
   - .ocr-thumb            → vignette d'une photo + bouton retirer
   - .ocr-sources          → duo de boutons "appareil photo" / "galerie"
                              (partial _ocr_sources.php, rendu 2×)
   - .ocr-source-btn       → un bouton de source (--camera / --gallery)
   - .ocr-hint-desktop     → hint drag&drop, masqué sur tactile
   - .ocr-coverage-hint    → message bleu "Bonne couverture..."
   - .ocr-extract-btn      → bouton principal "Analyser N photo(s)"
   - .ocr-cancel-btn       → bouton "Annuler" (visible pendant OCR)
   - .ocr-loader-toast     → toast "Lecture en cours..."
   - .ocr-reconstructed-hint → encart vert sur le textarea après OCR

   La zone .input-zone existe déjà ; on étend juste son comportement
   en cas de drag-over et de "has-photos".
*/

/* État cliquable du placeholder */
.ocr-placeholder {
    cursor: pointer;
    transition: transform 0.15s ease;
}

.ocr-placeholder:hover {
    transform: scale(1.01);
}

/* Drag-over feedback sur la zone photo */
#photo-zone.drag-over {
    border-color: var(--primary-pink);
    background: rgba(255, 107, 157, 0.04);
}

/* La gallery prend le relais du placeholder dès qu'il y a 1+ photo */
.ocr-gallery {
    padding: 0.5rem;
}

/* Rangée horizontale des thumbnails (auto-wrap si beaucoup) */
.ocr-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.ocr-thumb {
    position: relative;
    width: 80px;
    height: 80px;
    border-radius: 10px;
    overflow: hidden;
    background: #f0f0f0;
    border: 2px solid var(--info-blue);  /* bordure cyan/bleue cf. capture V1 */
    flex-shrink: 0;
}

.ocr-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ocr-thumb__label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    text-align: center;
    padding: 2px 0;
    line-height: 1.2;
}

.ocr-thumb__remove {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--danger-red);
    color: #fff;
    border: 2px solid #fff;
    cursor: pointer;
    font-size: 0.7rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    box-shadow: 0 2px 4px rgba(0,0,0,0.15);
    transition: transform 0.15s ease;
}

.ocr-thumb__remove:hover {
    transform: scale(1.1);
}

.ocr-thumb__remove:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.ocr-thumb__remove i {
    font-size: 0.85rem;
}

/* ─── Sources d'image (partial _ocr_sources.php) ──────────────────────
   Duo de boutons "appareil photo" / "galerie", rendu 2× : dans le
   placeholder (variante par défaut) et sous les thumbnails
   (.ocr-sources--compact, qui remplace l'ancien bouton unique
   "Ajouter une vue").

   Pourquoi masquer le bouton appareil sur desktop : l'attribut capture
   est ignoré par les navigateurs desktop, les deux boutons ouvriraient
   donc exactement le même explorateur de fichiers. Un seul suffit.
   Symétriquement, le hint drag&drop n'a aucun sens sur tactile.
   → tout se joue en media query `pointer`, aucun JS d'affichage.        */

.ocr-sources {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    justify-content: center;
    margin-top: 1.25rem;
}

.ocr-source-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    min-height: 44px;              /* cible tactile confortable (iOS HIG) */
    padding: 0.6rem 1.15rem;
    border: 1px solid transparent;
    border-radius: 100px;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease,
                border-color 0.15s ease, color 0.15s ease;
}

.ocr-source-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Neutralise l'héritage de .input-placeholder i (4rem, vert, opacity .6) :
   ces icônes sont dans des boutons, pas des illustrations. Sélecteur à 2
   classes pour ne pas dépendre de l'ordre des règles dans le fichier. */
.ocr-sources .ocr-source-btn i {
    font-size: 1.05rem;
    color: inherit;
    opacity: 1;
    margin: 0;
}

/* Primaire — prendre une photo */
.ocr-source-btn--camera {
    background: var(--primary-pink);
    color: #fff;
    box-shadow: 0 4px 12px rgba(255, 107, 157, 0.28);
}

.ocr-source-btn--camera:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(255, 107, 157, 0.35);
}

/* Secondaire — réutiliser une image existante */
.ocr-source-btn--gallery {
    background: #fff;
    color: #555;
    border-color: rgba(0, 0, 0, 0.15);
}

.ocr-source-btn--gallery:hover:not(:disabled) {
    border-color: var(--primary-pink);
    color: var(--primary-pink);
}

/* Variante compacte — sous la galerie de thumbnails */
.ocr-sources--compact {
    margin: 0.5rem 0 0.9rem;
}

.ocr-sources--compact .ocr-source-btn {
    min-height: 38px;
    padding: 0.4rem 0.95rem;
    font-size: 0.85rem;
    font-weight: 500;
}

.ocr-sources--compact .ocr-source-btn--camera {
    background: transparent;
    color: var(--primary-pink);
    border-color: var(--primary-pink);
    box-shadow: none;
}

.ocr-sources--compact .ocr-source-btn--camera:hover:not(:disabled) {
    background: rgba(255, 107, 157, 0.07);
    transform: none;
    box-shadow: none;
}

/* ─── Adaptation au support ───────────────────────────────────────────
   pointer: fine   = souris  → pas d'appareil photo, drag&drop pertinent
   pointer: coarse = doigt   → l'inverse                                */

@media (pointer: fine) {
    .ocr-source-btn--camera {
        display: none;
    }
}

@media (pointer: coarse) {
    /* Le drag&drop n'existe pas au doigt : le hint est un mensonge. */
    .ocr-hint-desktop {
        display: none;
    }

    /* L'action est portée par les boutons, plus par la zone entière :
       on rend l'illustration moins envahissante pour laisser la place
       aux cibles tactiles sans faire scroller le placeholder.
       Sélecteur enfant direct : ne doit PAS toucher les icônes des
       boutons de source. */
    .ocr-placeholder > i {
        font-size: 3rem;
        margin-bottom: 0.5rem;
    }

    /* Pas de micro-zoom au "hover" fantôme du tactile. */
    .ocr-placeholder:hover {
        transform: none;
    }
}

/* Hint de couverture (texte bleu doux sous "Ajouter une vue") */
.ocr-coverage-hint {
    text-align: center;
    color: var(--info-blue);
    font-size: 0.85rem;
    margin: 0 0 1rem 0;
    line-height: 1.5;
}

.ocr-coverage-hint i {
    margin-right: 0.3rem;
}

/* Bouton principal Extract — grande largeur, gradient rose */
.ocr-extract-btn {
    width: 100%;
    margin-bottom: 0.5rem;
}

/* Bouton Annuler — pleine largeur aussi, vert outline */
.ocr-cancel-btn {
    width: 100%;
    margin-bottom: 0.5rem;
}

/* Toast loader pendant l'OCR — encart bleu pâle, centré, animé */
.ocr-loader-toast {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin: 0.5rem auto 0;
    max-width: 360px;
    padding: 0.6rem 1rem;
    background: #e8f4fb;
    border: 1px solid rgba(93, 173, 226, 0.3);
    border-radius: 100px;
    color: #1c5980;
    font-size: 0.88rem;
    font-weight: 500;
    animation: ocrToastFadeIn 0.3s ease-out;
}

.ocr-loader-toast i {
    font-size: 1rem;
    animation: ocrToastPulse 1.4s ease-in-out infinite;
}

.ocr-loader-toast--error {
    background: #fbe9e7;
    border-color: rgba(231, 76, 60, 0.3);
    color: #b13927;
}

.ocr-loader-toast--error i {
    animation: none;
    color: var(--danger-red);
}

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

@keyframes ocrToastPulse {
    0%, 100% { opacity: 1;   transform: scale(1);    }
    50%      { opacity: 0.6; transform: scale(1.08); }
}

/* Encart vert "Formule reconstituée" sur le textarea */
.ocr-reconstructed-hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
    padding: 0.65rem 1rem;
    background: #f0f7e8;
    border: 1px solid rgba(143, 181, 105, 0.4);
    border-radius: 10px;
    color: var(--darker-green);
    font-size: 0.88rem;
    font-weight: 500;
    line-height: 1.45;
    text-align: center;
    animation: ocrToastFadeIn 0.3s ease-out;
}

.ocr-reconstructed-hint i {
    color: var(--primary-green);
    font-size: 1.05rem;
    flex-shrink: 0;
}

/* Responsive — thumbnails un peu plus petites sur mobile */
@media (max-width: 460px) {
    .ocr-thumb {
        width: 64px;
        height: 64px;
    }

    .ocr-thumb__label {
        font-size: 0.62rem;
    }
    .cosm-card__body {
        padding: .5rem;
    }
}

/* ============================================
   N. LOADER OVERLAY (.cosm-loader-overlay)
   ============================================
   Overlay plein écran "Analyse en cours" affiché au moment du submit
   d'un formulaire d'analyse INCI. Couvre l'attente serveur (parsing,
   résolution, corrections, redirection) avec une rampe UX en 3 phases :
 
     Phase 1 — Scan (par défaut)
       Animation des ingrédients qui se cochent un à un, compteur
       0/N → N/N, barre qui se remplit, spinner à vitesse normale.
 
     Phase 2 — Finalisation (.is-finalizing)
       Tous les items sont cochés mais la nav serveur n'est pas
       arrivée. Le spinner ralentit, message "Finalisation de
       l'analyse…" sous le compteur. La barre reste à 100%.
 
     Phase 3 — Plus de temps (.is-extended)
       6s après l'entrée en phase 2, le message change pour rassurer.
       Le spinner repart à vitesse normale (relance la dynamique).
 
   Mode dégradé (.is-empty)
       Activé si aucun ingrédient n'a pu être extrait du textarea
       (parsing vide). Masque la liste et le compteur, la barre
       devient un loader indéterminé.
 
   Markup dans views/partials/_loader_overlay.php.
   Logique JS dans assets/js/cosmelyse-loader.js.
   Composant générique car réutilisable sur 3 pages (home + confirmer).
*/
 
/* ── Conteneur fullscreen ────────────────────────────────────────── */
.cosm-loader-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
 
    /* Fond semi-transparent rose : voile la page sans la cacher
       complètement (l'utilisateur garde un repère visuel). */
    background: rgba(255, 107, 157, 0.92);
 
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}
 
.cosm-loader-overlay.is-active {
    opacity: 1;
    pointer-events: auto;
}
 
/* ── Card centrale (override de .cosm-card pour ce contexte) ────── */
.cosm-loader-overlay__panel {
    width: 100%;
    max-width: 460px;
    text-align: center;
    margin: 0;       /* override du margin-bottom de .cosm-card */
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.18);
 
    transform: translateY(20px);
    opacity: 0;
    transition: transform 0.35s ease 0.05s, opacity 0.35s ease 0.05s;
}
 
.cosm-loader-overlay.is-active .cosm-loader-overlay__panel {
    transform: translateY(0);
    opacity: 1;
}
 
/* ── Spinner SVG ─────────────────────────────────────────────────── */
.cosm-loader-overlay__spinner {
    width: 60px;
    height: 60px;
    margin: 0 auto 1rem;
}
 
.cosm-loader-overlay__spinner-svg {
    width: 100%;
    height: 100%;
    /* Phase 1 (par défaut) : 1.4s/tour. Phase 2 ralentit à 2.2s.
       Phase 3 revient à 1.4s pour relancer la dynamique. */
    animation: cosmLoaderSpin 1.4s linear infinite;
    transition: animation-duration 0.4s ease;
}
 
/* Phase 2 — finalisation : spinner ralentit */
.cosm-loader-overlay.is-finalizing:not(.is-extended)
    .cosm-loader-overlay__spinner-svg {
    animation-duration: 2.2s;
}
 
/* Phase 3 — l'animation revient à vitesse normale (héritée du défaut),
   pas besoin de règle explicite — la phase 3 efface l'effet de la 2. */
 
.cosm-loader-overlay__spinner-track {
    fill: none;
    stroke: rgba(255, 107, 157, 0.15);
    stroke-width: 4;
}
 
.cosm-loader-overlay__spinner-fill {
    fill: none;
    stroke: var(--primary-pink);
    stroke-width: 4;
    stroke-linecap: round;
    stroke-dasharray: 90 200;
    stroke-dashoffset: 0;
    transform-origin: center;
}
 
@keyframes cosmLoaderSpin {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}
 
/* ── Titre + compteur ────────────────────────────────────────────── */
.cosm-loader-overlay__title {
    font-family: 'Outfit', sans-serif;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--text-dark);
    margin: 0 0 0.4rem 0;
}
 
.cosm-loader-overlay__counter {
    font-size: 0.92rem;
    color: #777;
    margin: 0 0 1rem 0;
    font-feature-settings: 'tnum';   /* chiffres tabulaires */
}
 
.cosm-loader-overlay__counter-current,
.cosm-loader-overlay__counter-total {
    font-weight: 700;
    color: var(--primary-pink);
}
 
.cosm-loader-overlay__counter-sep {
    margin: 0 0.15rem;
    color: #ccc;
}
 
.cosm-loader-overlay.is-empty .cosm-loader-overlay__counter {
    display: none;
}
 
/* ── Barre de progression ────────────────────────────────────────── */
.cosm-loader-overlay__progress {
    width: 100%;
    height: 6px;
    background: rgba(255, 107, 157, 0.12);
    border-radius: 100px;
    overflow: hidden;
    margin-bottom: 1.2rem;
}
 
.cosm-loader-overlay__progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--primary-pink), var(--dark-pink));
    border-radius: 100px;
    transition: width 0.25s ease;
}
 
/* Mode dégradé .is-empty : barre indéterminée pulsante */
.cosm-loader-overlay.is-empty .cosm-loader-overlay__progress-bar {
    width: 40%;
    animation: cosmLoaderIndeterminate 1.6s ease-in-out infinite;
}
 
@keyframes cosmLoaderIndeterminate {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%);  }
}
 
/* ── Liste défilante des ingrédients ─────────────────────────────── */
.cosm-loader-overlay__list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 220px;
    overflow-y: auto;
    text-align: left;
    scroll-behavior: smooth;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 107, 157, 0.3) transparent;
}
 
.cosm-loader-overlay__list::-webkit-scrollbar {
    width: 4px;
}
.cosm-loader-overlay__list::-webkit-scrollbar-thumb {
    background: rgba(255, 107, 157, 0.3);
    border-radius: 4px;
}
 
.cosm-loader-overlay.is-empty .cosm-loader-overlay__list {
    display: none;
}
 
/* Items individuels — état "à cocher" par défaut */
.cosm-loader-overlay__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.35rem;
    background: rgba(255, 107, 157, 0.04);
    border-radius: 8px;
    font-size: 0.9rem;
    color: #999;
    transition: color 0.25s ease, background 0.25s ease;
}
 
.cosm-loader-overlay__item-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.15);
    flex-shrink: 0;
    transition: background 0.25s ease, transform 0.25s ease;
}
 
.cosm-loader-overlay__item-label {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
 
/* État "coché" — posé par le JS au tick */
.cosm-loader-overlay__item.is-done {
    background: rgba(143, 181, 105, 0.10);
    color: var(--text-dark);
}
 
.cosm-loader-overlay__item.is-done .cosm-loader-overlay__item-dot {
    background: var(--primary-green);
    transform: scale(1.2);
    box-shadow: 0 0 0 3px rgba(143, 181, 105, 0.2);
}
 
/* ── Messages de phases (2 & 3) ──────────────────────────────────── */
/*
   Les 2 messages sont rendus côte-à-côte dans le DOM. Le CSS bascule
   leur visibilité selon les classes posées sur le conteneur :
     - défaut          → les 2 sont masqués
     - .is-finalizing  → "Finalisation de l'analyse…" visible
     - .is-extended    → "L'analyse prend un peu plus de temps…" visible
     - .is-extended a priorité (cache le 1er message même si is-finalizing)
*/
.cosm-loader-overlay__phase-msg {
    display: none;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin: 0.8rem 0 0 0;
    font-size: 0.88rem;
    color: #888;
    font-style: italic;
    line-height: 1.5;
 
    /* Animation d'apparition douce */
    opacity: 0;
    animation: cosmLoaderPhaseFadeIn 0.4s ease forwards;
}
 
.cosm-loader-overlay__phase-msg i {
    font-size: 1rem;
    color: var(--primary-pink);
}
 
/* Phase 2 visible (sauf si phase 3 a pris le relais) */
.cosm-loader-overlay.is-finalizing:not(.is-extended)
    .cosm-loader-overlay__phase-msg--finalizing {
    display: inline-flex;
}
 
/* Phase 3 visible (cache le message phase 2) */
.cosm-loader-overlay.is-extended
    .cosm-loader-overlay__phase-msg--extended {
    display: inline-flex;
}
 
@keyframes cosmLoaderPhaseFadeIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0);   }
}
 
/* ── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 480px) {
    .cosm-loader-overlay__panel {
        max-width: 100%;
    }
 
    .cosm-loader-overlay__title {
        font-size: 1.2rem;
    }
 
    .cosm-loader-overlay__list {
        max-height: 180px;
    }
 
    .cosm-loader-overlay__phase-msg {
        font-size: 0.82rem;
    }
}

/* ============================================
   COSM-HONEYPOT — composant générique
   ============================================ */

/*  Champ leurre anti-bot. Doit être :
      1. Invisible visuellement (mais PAS via display:none ni
         visibility:hidden — certains bots détectent ces tricks et
         évitent de remplir).
      2. Hors flux pour ne prendre aucune place.
      3. Inaccessible au clavier (tabindex=-1 côté HTML, on confirme
         côté CSS via pointer-events).
      4. Annoncé en aria-hidden=true côté HTML pour les screen readers.

    Approche retenue : position absolute hors viewport + opacity 0.
    Stratégie classique éprouvée — visible uniquement par les bots
    naïfs qui parsent le DOM en oubliant le CSS.

    Préfixe .cosm-* parce que c'est un composant global, partagé entre
    auth (login, register, reset, password change) et programme
    (cosmétiques & moi).                                                  */

.cosm-honeypot {
    position: absolute !important;
    left: -9999px !important;
    top: auto !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

.cosm-honeypot * {
    pointer-events: none !important;
}
/* ============================================
   COSM-TOAST — système de notifications flottantes
   ============================================ */

/*  Container fixe par-dessus tout le contenu. Position adaptée :
      - Desktop : bottom-right, stack vertical depuis le bas
      - Mobile  : top-center, stack vertical depuis le haut
                  (les toasts en bas de mobile gênent les gestures iOS
                  de retour, et risquent d'être masqués par la barre
                  de navigation flottante de certains navigateurs)

    Pointer-events: none sur le container pour que les zones VIDES
    (entre toasts) laissent passer les clics au contenu. Les toasts
    eux-mêmes restituent les pointer-events.                              */

.cosm-toasts {
    position: fixed;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    pointer-events: none;

    /* Desktop : bottom-right */
    bottom: 1.25rem;
    right: 1.25rem;
    left: auto;
    top: auto;

    /* Largeur max pour ne pas s'étaler à 100% en grand écran */
    width: min(380px, calc(100vw - 2.5rem));
}

@media (max-width: 640px) {
    /* Mobile : top-center, full-width-ish */
    .cosm-toasts {
        top: 0.75rem;
        left: 0.75rem;
        right: 0.75rem;
        bottom: auto;
        width: auto;
        flex-direction: column;
    }
}


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

.cosm-toast {
    pointer-events: auto;       /* réactive les clics sur les toasts eux-mêmes */
    cursor: pointer;            /* signale qu'on peut cliquer pour fermer */

    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: flex-start;
    gap: 0.7rem;

    padding: 0.85rem 0.95rem;
    background: #fff;
    color: var(--text-dark);
    border-radius: 12px;
    border-left: 4px solid #ccc;   /* couleur définie par les modifiers --type */
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12),
                0 2px 6px  rgba(0, 0, 0, 0.06);

    font-size: 0.92rem;
    line-height: 1.45;

    /* État initial : caché, prêt pour animation d'entrée */
    opacity: 0;
    transform: translateX(110%);
    transition: opacity 280ms ease, transform 280ms ease;
}

@media (max-width: 640px) {
    /* Sur mobile, l'animation arrive depuis le HAUT (pas de la droite) */
    .cosm-toast {
        transform: translateY(-120%);
    }
}

/* État visible : déclenché par JS au mount via .is-visible */
.cosm-toast.is-visible {
    opacity: 1;
    transform: translateX(0);
}

@media (max-width: 640px) {
    .cosm-toast.is-visible {
        transform: translateY(0);
    }
}

/* État sortie : déclenché par JS au dismiss */
.cosm-toast.is-leaving {
    opacity: 0;
    transform: translateX(110%);
}

@media (max-width: 640px) {
    .cosm-toast.is-leaving {
        transform: translateY(-120%);
    }
}

/*  Sans JS (pas de classes is-visible/is-leaving), on veut quand même
    voir les toasts : on remet opacity 1 et transform 0 par défaut. La
    règle s'applique uniquement si JS n'a JAMAIS posé .is-visible.
    Astuce : la spec CSS dit que .cosm-toast a opacity:0 + translateX
    par défaut. Pour que sans JS ça reste visible, on ne pose ces
    valeurs que si .cosm-toast n'a pas data-cosm-init.

    Mais on ne peut pas conditionner via :not([data-cosm-init]) sur
    l'opacity sans casser la transition. Solution pragmatique : on
    utilise un fallback @media (prefers-reduced-motion) qui désactive
    les transitions, ET côté JS on pose is-visible TRÈS rapidement.
    Pour le mode dégradé sans JS pur, on accepte que l'animation
    d'entrée ne joue pas — les toasts apparaissent instantanément.   */

@media (prefers-reduced-motion: reduce) {
    .cosm-toast {
        transition: none;
        opacity: 1;
        transform: none;
    }
}


/* ─── Icône à gauche ───────────────────────────────────────────── */

.cosm-toast__icon {
    font-size: 1.15rem;
    line-height: 1.3;
    margin-top: 0.05rem;
    flex-shrink: 0;
}


/* ─── Message au milieu ────────────────────────────────────────── */

.cosm-toast__msg {
    color: var(--text-dark);
    font-weight: 500;
    word-wrap: break-word;
    overflow-wrap: anywhere;
    min-width: 0;
}


/* ─── Bouton fermer à droite ───────────────────────────────────── */

.cosm-toast__close {
    background: transparent;
    border: 0;
    padding: 0.15rem 0.35rem;
    color: #999;
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    border-radius: 6px;
    flex-shrink: 0;
    transition: color 0.15s ease, background-color 0.15s ease;
}

.cosm-toast__close:hover {
    color: var(--text-dark);
    background: rgba(0, 0, 0, 0.05);
}

.cosm-toast__close:focus-visible {
    outline: 2px solid var(--primary-pink);
    outline-offset: 1px;
}


/* ─── Variantes par type ───────────────────────────────────────── */

.cosm-toast--success {
    border-left-color: var(--primary-green);
}
.cosm-toast--success .cosm-toast__icon {
    color: var(--primary-green);
}

.cosm-toast--info {
    border-left-color: var(--info-blue);
}
.cosm-toast--info .cosm-toast__icon {
    color: var(--info-blue);
}

.cosm-toast--warning {
    border-left-color: var(--warn-orange);
}
.cosm-toast--warning .cosm-toast__icon {
    color: var(--warn-orange);
}

.cosm-toast--error {
    border-left-color: var(--danger-red);
}
.cosm-toast--error .cosm-toast__icon {
    color: var(--danger-red);
}

/* ─────────────────────────────────────────────────────────────────────
   Logo Cosmélyse (SVG inline)
   Composant générique. La taille est imposée par le contexte parent
   (.navbar-brand-logo, .footer-logo, etc.) qui doit appliquer
   width/height au .cosm-logo.

   Le wordmark est vectorise en contours pleins : les regles ci-dessous
   posent un fill, pas un stroke. Le logo suit donc la palette du site,
   changer --primary-pink change la loupe sans toucher au SVG.
   ───────────────────────────────────────────────────────────────────── */

.cosm-logo {
    display: block;
    overflow: visible;
}


.cosm-logo__word {
    fill: var(--text-dark);
}

.cosm-logo__glass {
    fill: var(--primary-pink);
}

.cosm-logo__leaf {
    fill: var(--primary-green);
}

.cosm-logo__leaf-vein {
    fill: var(--darker-green);
}
.cosm-logo {
    display: block;
    overflow: visible;
}


/* ============================================
   18. HELP CTA (composant générique)
   ============================================
*/

.cosm-help-cta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.9rem;
    padding: 0.9rem 1.1rem;
    background: var(--cream);
    border: 1px solid rgba(212, 175, 55, 0.3);
    border-radius: 12px;
}

.cosm-help-cta__text {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: 0.87rem;
    color: #5f5f5f;
    line-height: 1.5;
    flex: 1 1 260px;
}
.cosm-help-cta__text i {
    color: var(--gold-accent);
    font-size: 1.05rem;
    margin-top: 0.08rem;
    flex-shrink: 0;
}

.cosm-help-cta__btn {
    white-space: nowrap;
    flex-shrink: 0;
}


.cosm-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    vertical-align: middle;
    background: #bbb;            /* défaut = neutral */
}

.cosm-dot--ok      { background: var(--primary-green); }
.cosm-dot--warn    { background: var(--warn-orange);   }
.cosm-dot--danger  { background: var(--danger-red);    }
.cosm-dot--info    { background: var(--info-blue);     }


/* ============================================
   COSM-SAFETY-RULE — liseré coloré gauche selon le profil de sécurité
   ============================================
   Composant générique appliquable à n'importe quelle carte/conteneur
   pour signaler visuellement le niveau de sécurité d'un ingrédient
   (4 stops cosing : safe / watch / avoid / unrated).

   La valeur par défaut (sans modifieur) est neutre (gris) — utilisée
   pour les ingrédients non évalués.

   Mapping (identique à .cosm-dot) :
     safe    → vert     (--primary-green)
     watch   → orange   (--warn-orange)
     avoid   → rouge    (--danger-red)
     unrated → gris défaut (pas de modifieur)

   NB : .ingredient-card--safe/--watch/--avoid (cosmelyse_ingredient_card_base.css)
   définissent le même liseré + d'autres règles descendantes (pastille de
   position, badge sécurité). Tant que la fiche ingrédient n'est pas migrée
   vers .cosm-safety-rule, les deux composants cohabitent. Voir le TODO
   dans cosmelyse_ingredient_card_base.css. */

.cosm-safety-rule          { border-left: 4px solid #bbb; }
.cosm-safety-rule--safe    { border-left-color: var(--primary-green); }
.cosm-safety-rule--watch   { border-left-color: var(--warn-orange);   }
.cosm-safety-rule--avoid   { border-left-color: var(--danger-red);    }


/* ============================================
   19. COSM-PAGE — wrapper générique de page
   ============================================
   Conteneur standard pour les pages de contenu. Remplace les anciennes
   classes ad-hoc .auth-wrapper, .cfm-wrap, .profile-wrapper,
   .rdv-wrapper, .program-wrapper, .historique-wrapper, .search-wrap,
   .result-wrap.

   Markup attendu :
       <main class="main-container">
           <div class="cosm-page cosm-page--small">...</div>
       </main>

   PAS de <div class="container"> Bootstrap autour : .cosm-page assure
   son propre centrage horizontal et son propre padding.

   Le padding horizontal de 1.5rem est aligné sur la gutter par défaut
   du .container Bootstrap (--bs-gutter-x: 1.5rem). On retrouve donc
   visuellement le même alignement que les pages qui utilisaient le
   .container Bootstrap. Sur très petit écran (<576px), on réduit
   à 1rem pour récupérer de l'espace utile.
*/

.cosm-page {
    margin: 0 auto;
    padding: 1.5rem 1.5rem 3rem;
}

.cosm-page--narrow { max-width: 580px;  }   /* auth (login, register, etc.) */
.cosm-page--small  { max-width: 720px;  }   /* confirmer, profil, faq */
.cosm-page--medium { max-width: 960px;  }   /* rdv, cosmétiques-et-moi */
.cosm-page--wide   { max-width: 1200px; }   /* result, compare, ingredient, recherche, historique */
.cosm-page--full   { max-width: 100%;   }   /* pleine largeur (réservé pour cas spéciaux) */

/* Marge sous le header de page, harmonisée. Remplace les déclarations
   répétées .auth-wrapper .cosm-page-header et .profile-wrapper .cosm-page-header. */
.cosm-page > .cosm-page-header {
    margin-bottom: 1.5rem;
}

/* Responsive : sur très petit écran on rapproche du bord et on réduit
   les marges verticales. Remplace les media queries ad-hoc de
   .cfm-wrap / .auth-wrapper / etc. */
@media (max-width: 575.98px) {
    .cosm-page {
        padding: 1rem 1rem 2.5rem;
    }

    .cosm-page-header__title {
        font-size: 1.5rem;
    }
}

/* ═══════════════════════════════════════════════════════════════════════
   .cosm-score-badge — Badge de score /20 avec icône + valeur + unité
   Salve S + alignement tabulaire — utilisé sur cards produit
   ═══════════════════════════════════════════════════════════════════════ */
 
.cosm-score-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.35em 0.7em;
    border-radius: 12px;
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.85rem;
    color: #fff;
    line-height: 1;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
    white-space: nowrap;
    text-decoration: none;
    /* Chiffres à largeur fixe : "11.7" et "9.4" prennent la même place. */
    font-variant-numeric: tabular-nums;
}
 
.cosm-score-badge__icon  {
    font-size: 0.95em;
    opacity: 0.95;
    flex-shrink: 0;
}
 
/* Valeur : largeur fixe + alignement à droite pour caler les décimales
   entre badges. 2.2em couvre "18.5", "20.0", "9.8", etc. */
.cosm-score-badge__value {
    font-weight: 800;
    width: 2.2em;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
 
/* Unité : largeur fixe + alignement à gauche pour que "/20" tombe pile
   sous "/20" du badge voisin. 1.5em suffisent. */
.cosm-score-badge__unit  {
    font-weight: 500;
    opacity: 0.85;
    font-size: 0.85em;
    width: 1.5em;
    text-align: left;
}
 
/* Variantes par niveau (inchangées) */
.cosm-score-badge--excellent { background: var(--primary-green); }
.cosm-score-badge--good      { background: var(--darker-green); }
.cosm-score-badge--fair      { background: var(--info-blue); }
.cosm-score-badge--poor      { background: var(--warn-orange); }
.cosm-score-badge--bad       { background: var(--danger-red); }
.cosm-score-badge--neutral   { background: #888; }
 
/* Variante compacte (inchangée) */
.cosm-score-badge--compact {
    padding: 0.25em 0.55em;
    font-size: 0.75rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   .cosm-perso-pill — Pill verdict perso (Adapté / Vigilance / À éviter)
   Utilisée sur cards ingrédient + chips actifs si besoin
   ═══════════════════════════════════════════════════════════════════════ */
 
.cosm-perso-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    padding: 0.25em 0.6em;
    border-radius: 999px;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
 
.cosm-perso-pill i { font-size: 0.95em; }
 
.cosm-perso-pill--safe {
    background: rgba(143, 181, 105, 0.15);
    color: var(--darker-green);
}
.cosm-perso-pill--caution {
    background: rgba(243, 156, 18, 0.15);
    color: var(--warn-orange);
}
.cosm-perso-pill--avoid {
    background: rgba(231, 76, 60, 0.15);
    color: var(--danger-red);
}
/* ═══════════════════════════════════════════════════════════════════════
   Multi-profil
   ═══════════════════════════════════════════════════════════════════════ */
 
.cosm-profile-switcher {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0 0 .9rem;
    padding: .45rem .7rem;
    border: 1px solid var(--cosm-border, #e4e0da);
    border-radius: 10px;
    background: var(--cosm-surface, #fff);
    font-size: .85rem;
}
 
.cosm-profile-switcher__label {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-weight: 600;
    white-space: nowrap;
    margin: 0;
}
 
.cosm-profile-switcher__select {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 22rem;
    padding: .3rem .5rem;
    font-size: .85rem;
    border: 1px solid var(--cosm-border, #d8d2c8);
    border-radius: 8px;
    background: #fff;
}
 
.cosm-profile-switcher__btn {
    padding: .3rem .7rem;
    font-size: .8rem;
    font-weight: 600;
    border: 1px solid var(--cosm-accent, #7a9d54);
    border-radius: 8px;
    background: var(--cosm-accent, #7a9d54);
    color: #fff;
    cursor: pointer;
    white-space: nowrap;
}



/* ============================================
   20. HOME — SECTION ÉDITORIALE SEO (.home-seo)
   ============================================

   Bloc de contenu crawlable sous la floating-card de la home
   (index.php uniquement). Le hero + formulaire restent le héros
   visuel ; cette section apporte le texte que Google ne trouvait
   pas sur la page (Qu'est-ce que / Comment ça marche /
   différenciateurs / mini-FAQ / maillage interne).

   Réutilise les composants génériques (.cosm-card, .cosm-accordion,
   grille Bootstrap). Seuls les styles STRICTEMENT spécifiques à la
   section vivent ici : wrapper, titres de section, pastille d'étape,
   icône des cards différenciateurs.
*/

.home-seo {
    max-width: 860px;
    margin: 4rem auto 1rem;
    text-align: left;
}

.home-seo__block {
    margin-bottom: 3rem;
}

.home-seo__title {
    font-family: 'Outfit', sans-serif;
    font-size: 1.45rem;
    font-weight: 700;
    color: var(--text-dark);
    margin-bottom: 1rem;
}

.home-seo p {
    color: #555;
    line-height: 1.7;
}

/* Pastille numérotée des étapes "Comment ça marche" */
.home-seo__step-num {
    width: 2.2rem;
    height: 2.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary-pink), var(--dark-pink));
    color: #fff;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

.home-seo__step-title,
.home-seo__diff-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-dark);
    margin-bottom: 0.4rem;
}

.home-seo__step-text,
.home-seo__diff-text {
    font-size: 0.9rem;
    color: #666;
    margin-bottom: 0;
    line-height: 1.6;
}

/* Icône ronde des cards différenciateurs — même esthétique que
   .feature-icon de la floating-card (cohérence visuelle home),
   déclinée en rose. */
.home-seo__diff-icon {
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    background: linear-gradient(135deg, rgba(255, 107, 157, 0.14), rgba(255, 107, 157, 0.05));
    border-radius: 50%;
    color: var(--primary-pink);
    margin-bottom: 0.85rem;
}

.home-seo__more {
    margin-top: 1rem;
}

/* Dans les grilles de la section, la gouttière Bootstrap (g-3) gère
   l'espacement vertical : on neutralise le margin-bottom par défaut
   de .cosm-card et on égalise les hauteurs de colonnes. */
.home-seo .row .cosm-card {
    margin-bottom: 0;
    height: 100%;
}

@media (max-width: 768px) {
    .home-seo {
        margin-top: 3rem;
    }
    .home-seo__block {
        margin-bottom: 2.25rem;
    }
}

/* ============================================
   COSM-REPORT-ERROR — lien discret de signalement
   d'erreur sur une fiche (result, compare, ingredient)
   Rendu par views/partials/_report_error_link.php
   ============================================ */

.cosm-report-error {
    text-align: center;
    margin: 1.25rem 0 0;
    font-size: 0.85rem;
}

.cosm-report-error a {
    color: #b9a2ac;
    text-decoration: none;
    transition: color 0.15s ease;
}

.cosm-report-error a:hover {
    color: var(--primary-pink, #ff6b9d);
    text-decoration: underline;
}

.cosm-report-error i {
    margin-right: 0.3rem;
}
